feat: refactoeing
This commit is contained in:
115
frontend/src/app/recollections/state/recollectionStore.ts
Normal file
115
frontend/src/app/recollections/state/recollectionStore.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* Per-recollection persistence: graph (Flux) and logos (BlockNote) state.
|
||||
* Single API for loading, saving, and removing all data for a recollection.
|
||||
*/
|
||||
|
||||
import type { StoredGraphState } from '@/lib/graph/state'
|
||||
|
||||
export type { StoredGraphState }
|
||||
|
||||
/** BlockNote document: array of blocks (PartialBlock). Stored as JSON. */
|
||||
export type StoredLogosContent = Record<string, unknown>[]
|
||||
|
||||
/** One entry in the render-output cache (one per rendering node, overwritten on each update). */
|
||||
export type RenderOutputCacheEntry = {
|
||||
nodeId: string
|
||||
label: string
|
||||
type: 'image' | 'html'
|
||||
content: string
|
||||
}
|
||||
|
||||
export const RECOLLECTION_FILE_EXT = '.zui.json'
|
||||
export const RECOLLECTION_VERSION = 1
|
||||
|
||||
const GRAPH_KEY_PREFIX = 'zui_graph_'
|
||||
const LOGOS_KEY_PREFIX = 'zui_logos_'
|
||||
const RENDER_CACHE_KEY_PREFIX = 'zui_render_cache_'
|
||||
|
||||
function getGraphKey(recollectionId: string): string {
|
||||
return `${GRAPH_KEY_PREFIX}${recollectionId}`
|
||||
}
|
||||
|
||||
function getLogosKey(recollectionId: string): string {
|
||||
return `${LOGOS_KEY_PREFIX}${recollectionId}`
|
||||
}
|
||||
|
||||
function getRenderCacheKey(recollectionId: string): string {
|
||||
return `${RENDER_CACHE_KEY_PREFIX}${recollectionId}`
|
||||
}
|
||||
|
||||
export function getGraph(recollectionId: string): StoredGraphState | null {
|
||||
try {
|
||||
const raw = localStorage.getItem(getGraphKey(recollectionId))
|
||||
if (!raw) return null
|
||||
const data = JSON.parse(raw) as unknown
|
||||
if (
|
||||
!data ||
|
||||
typeof data !== 'object' ||
|
||||
!Array.isArray((data as StoredGraphState).nodes) ||
|
||||
!Array.isArray((data as StoredGraphState).edges)
|
||||
)
|
||||
return null
|
||||
return data as StoredGraphState
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function setGraph(recollectionId: string, state: StoredGraphState): void {
|
||||
localStorage.setItem(getGraphKey(recollectionId), JSON.stringify(state))
|
||||
}
|
||||
|
||||
export function getLogosContent(recollectionId: string): StoredLogosContent | null {
|
||||
try {
|
||||
const raw = localStorage.getItem(getLogosKey(recollectionId))
|
||||
if (!raw) return null
|
||||
const data = JSON.parse(raw) as unknown
|
||||
if (!Array.isArray(data)) return null
|
||||
if (!data.every((item) => item != null && typeof item === 'object')) return null
|
||||
return data as StoredLogosContent
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function setLogosContent(recollectionId: string, content: StoredLogosContent): void {
|
||||
localStorage.setItem(getLogosKey(recollectionId), JSON.stringify(content))
|
||||
}
|
||||
|
||||
/** Render output cache: one entry per rendering node (keyed by nodeId). Used by Logos "Insert from Flux" block. */
|
||||
export function getRenderOutputCache(recollectionId: string): RenderOutputCacheEntry[] {
|
||||
try {
|
||||
const raw = localStorage.getItem(getRenderCacheKey(recollectionId))
|
||||
if (!raw) return []
|
||||
const data = JSON.parse(raw) as unknown
|
||||
if (!Array.isArray(data)) return []
|
||||
return data.filter(
|
||||
(item): item is RenderOutputCacheEntry =>
|
||||
item != null &&
|
||||
typeof item === 'object' &&
|
||||
typeof (item as RenderOutputCacheEntry).nodeId === 'string' &&
|
||||
typeof (item as RenderOutputCacheEntry).label === 'string' &&
|
||||
((item as RenderOutputCacheEntry).type === 'image' || (item as RenderOutputCacheEntry).type === 'html') &&
|
||||
typeof (item as RenderOutputCacheEntry).content === 'string'
|
||||
) as RenderOutputCacheEntry[]
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export function upsertRenderOutputEntry(recollectionId: string, entry: RenderOutputCacheEntry): void {
|
||||
const entries = getRenderOutputCache(recollectionId)
|
||||
const byNodeId = new Map(entries.map((e) => [e.nodeId, e]))
|
||||
byNodeId.set(entry.nodeId, entry)
|
||||
localStorage.setItem(
|
||||
getRenderCacheKey(recollectionId),
|
||||
JSON.stringify(Array.from(byNodeId.values()))
|
||||
)
|
||||
}
|
||||
|
||||
/** Removes both graph, logos, and render cache data for the recollection. */
|
||||
export function removeRecollectionData(recollectionId: string): void {
|
||||
localStorage.removeItem(getGraphKey(recollectionId))
|
||||
localStorage.removeItem(getLogosKey(recollectionId))
|
||||
localStorage.removeItem(getRenderCacheKey(recollectionId))
|
||||
}
|
||||
Reference in New Issue
Block a user