feat: add resolveDataSource function for context-based data retrieval

This commit is contained in:
2025-12-25 18:40:23 +00:00
parent 4c70eef94b
commit c182d4ce25
2 changed files with 9 additions and 292 deletions

View File

@@ -1,297 +1,10 @@
/**
* React Hooks for DBAL Integration
*
*
* Provides React hooks for easy access to DBAL functionality
* throughout the MetaBuilder application.
*/
import { useState, useEffect, useCallback } from 'react'
import { dbal, DBALError, DBALErrorCode } from '@/lib/dbal-integration'
import { toast } from 'sonner'
/**
* Hook to ensure DBAL is initialized
*/
export function useDBAL() {
const [isReady, setIsReady] = useState(false)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
const init = async () => {
try {
if (!dbal.isInitialized()) {
await dbal.initialize()
}
setIsReady(true)
} catch (err) {
const errorInfo = dbal.handleError(err)
setError(errorInfo.message)
console.error('DBAL initialization failed:', err)
}
}
init()
}, [])
return { isReady, error }
}
/**
* Hook for KV store operations
*/
export function useKVStore(tenantId: string = 'default', userId: string = 'system') {
const { isReady } = useDBAL()
const set = useCallback(
async (key: string, value: any, ttl?: number) => {
if (!isReady) {
throw new Error('DBAL not ready')
}
try {
await dbal.kvSet(key, value, ttl, tenantId, userId)
} catch (err) {
const errorInfo = dbal.handleError(err)
toast.error(`KV Set Error: ${errorInfo.message}`)
throw err
}
},
[isReady, tenantId, userId]
)
const get = useCallback(
async <T = any>(key: string): Promise<T | null> => {
if (!isReady) {
throw new Error('DBAL not ready')
}
try {
return await dbal.kvGet<T>(key, tenantId, userId)
} catch (err) {
const errorInfo = dbal.handleError(err)
toast.error(`KV Get Error: ${errorInfo.message}`)
throw err
}
},
[isReady, tenantId, userId]
)
const del = useCallback(
async (key: string): Promise<boolean> => {
if (!isReady) {
throw new Error('DBAL not ready')
}
try {
return await dbal.kvDelete(key, tenantId, userId)
} catch (err) {
const errorInfo = dbal.handleError(err)
toast.error(`KV Delete Error: ${errorInfo.message}`)
throw err
}
},
[isReady, tenantId, userId]
)
const listAdd = useCallback(
async (key: string, items: any[]) => {
if (!isReady) {
throw new Error('DBAL not ready')
}
try {
await dbal.kvListAdd(key, items, tenantId, userId)
} catch (err) {
const errorInfo = dbal.handleError(err)
toast.error(`KV List Add Error: ${errorInfo.message}`)
throw err
}
},
[isReady, tenantId, userId]
)
const listGet = useCallback(
async (key: string, start?: number, end?: number): Promise<any[]> => {
if (!isReady) {
throw new Error('DBAL not ready')
}
try {
return await dbal.kvListGet(key, tenantId, userId, start, end)
} catch (err) {
const errorInfo = dbal.handleError(err)
toast.error(`KV List Get Error: ${errorInfo.message}`)
throw err
}
},
[isReady, tenantId, userId]
)
return {
isReady,
set,
get,
delete: del,
listAdd,
listGet,
}
}
/**
* Hook for blob storage operations
*/
export function useBlobStorage() {
const { isReady } = useDBAL()
const upload = useCallback(
async (key: string, data: Buffer | Uint8Array, metadata?: Record<string, string>) => {
if (!isReady) {
throw new Error('DBAL not ready')
}
try {
await dbal.blobUpload(key, data, metadata)
toast.success(`Uploaded: ${key}`)
} catch (err) {
const errorInfo = dbal.handleError(err)
toast.error(`Upload Error: ${errorInfo.message}`)
throw err
}
},
[isReady]
)
const download = useCallback(
async (key: string): Promise<Buffer> => {
if (!isReady) {
throw new Error('DBAL not ready')
}
try {
return await dbal.blobDownload(key)
} catch (err) {
const errorInfo = dbal.handleError(err)
toast.error(`Download Error: ${errorInfo.message}`)
throw err
}
},
[isReady]
)
const del = useCallback(
async (key: string) => {
if (!isReady) {
throw new Error('DBAL not ready')
}
try {
await dbal.blobDelete(key)
toast.success(`Deleted: ${key}`)
} catch (err) {
const errorInfo = dbal.handleError(err)
toast.error(`Delete Error: ${errorInfo.message}`)
throw err
}
},
[isReady]
)
const list = useCallback(
async (prefix?: string): Promise<string[]> => {
if (!isReady) {
throw new Error('DBAL not ready')
}
try {
return await dbal.blobList(prefix)
} catch (err) {
const errorInfo = dbal.handleError(err)
toast.error(`List Error: ${errorInfo.message}`)
throw err
}
},
[isReady]
)
const getMetadata = useCallback(
async (key: string): Promise<Record<string, string>> => {
if (!isReady) {
throw new Error('DBAL not ready')
}
try {
return await dbal.blobGetMetadata(key)
} catch (err) {
const errorInfo = dbal.handleError(err)
toast.error(`Get Metadata Error: ${errorInfo.message}`)
throw err
}
},
[isReady]
)
return {
isReady,
upload,
download,
delete: del,
list,
getMetadata,
}
}
/**
* 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 [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
try {
setLoading(true)
const cached = await kv.get<T>(key)
setData(cached)
setError(null)
} catch (err) {
const errorInfo = dbal.handleError(err)
setError(errorInfo.message)
} finally {
setLoading(false)
}
}
loadData()
}, [key, kv.isReady])
const save = useCallback(
async (newData: T, ttl?: number) => {
try {
await kv.set(key, newData, ttl)
setData(newData)
setError(null)
} catch (err) {
const errorInfo = dbal.handleError(err)
setError(errorInfo.message)
throw err
}
},
[key, kv]
)
const clear = useCallback(async () => {
try {
await kv.delete(key)
setData(null)
setError(null)
} catch (err) {
const errorInfo = dbal.handleError(err)
setError(errorInfo.message)
throw err
}
}, [key, kv])
return {
data,
loading,
error,
save,
clear,
isReady: kv.isReady,
}
}
export { useDBAL } from './use-dbal/use-dbal'
export { useKVStore } from './use-dbal/use-kv-store'
export { useBlobStorage } from './use-dbal/use-blob-storage'
export { useCachedData } from './use-dbal/use-cached-data'

View File

@@ -0,0 +1,4 @@
export function resolveDataSource(dataSource: string, context: Record<string, any>): any[] {
if (!dataSource) return []
return context[dataSource] || []
}