Spaces:
Runtime error
Runtime error
| import * as Y from "yjs"; | |
| /** | |
| * Metadata describing a data file uploaded into the embed data store. | |
| * | |
| * Kept intentionally lean (strings + small numbers) so it can live | |
| * alongside the raw content inside a single Y.Map entry without | |
| * bloating the document size. | |
| */ | |
| export interface EmbedDataFileMeta { | |
| name: string; | |
| /** Extension without leading dot, lowercased: "csv" | "tsv" | "json" | "txt" */ | |
| ext: string; | |
| /** Size of the stored text content in bytes (UTF-8). */ | |
| size: number; | |
| /** Uploader user id (if available). */ | |
| uploader?: string; | |
| /** Epoch ms when the file was added. */ | |
| addedAt: number; | |
| /** Light metadata computed client-side after parsing. */ | |
| rowCount?: number; | |
| columns?: string[]; | |
| } | |
| export interface EmbedDataFile { | |
| meta: EmbedDataFileMeta; | |
| /** Raw text content (UTF-8). */ | |
| content: string; | |
| } | |
| /** | |
| * Collaborative store for tabular/textual data files attached to a | |
| * document. Each key is a filename (e.g. "sales.csv") and the value is | |
| * an `EmbedDataFile` object (meta + raw text content). | |
| * | |
| * These files are accessible to the Embed Studio AI via tool calls so | |
| * charts can reference user-provided datasets. The store is backed by | |
| * `Y.Map("embed-data")` for realtime collaboration. | |
| */ | |
| export function createEmbedDataStore(ydoc: Y.Doc) { | |
| const ymap = ydoc.getMap<EmbedDataFile>("embed-data"); | |
| function get(name: string): EmbedDataFile | undefined { | |
| return ymap.get(name); | |
| } | |
| function getContent(name: string): string { | |
| return ymap.get(name)?.content ?? ""; | |
| } | |
| function getMeta(name: string): EmbedDataFileMeta | undefined { | |
| return ymap.get(name)?.meta; | |
| } | |
| function has(name: string): boolean { | |
| return ymap.has(name); | |
| } | |
| function set(file: EmbedDataFile) { | |
| ymap.set(file.meta.name, file); | |
| } | |
| function remove(name: string) { | |
| ymap.delete(name); | |
| } | |
| function rename(oldName: string, newName: string) { | |
| const file = ymap.get(oldName); | |
| if (!file) return; | |
| ydoc.transact(() => { | |
| ymap.set(newName, { ...file, meta: { ...file.meta, name: newName } }); | |
| ymap.delete(oldName); | |
| }); | |
| } | |
| function keys(): string[] { | |
| return Array.from(ymap.keys()); | |
| } | |
| function list(): EmbedDataFileMeta[] { | |
| const items: EmbedDataFileMeta[] = []; | |
| ymap.forEach((file) => { | |
| items.push(file.meta); | |
| }); | |
| return items.sort((a, b) => a.name.localeCompare(b.name)); | |
| } | |
| function observe(callback: () => void) { | |
| ymap.observe(callback); | |
| return () => ymap.unobserve(callback); | |
| } | |
| return { | |
| get, | |
| getContent, | |
| getMeta, | |
| has, | |
| set, | |
| remove, | |
| rename, | |
| keys, | |
| list, | |
| observe, | |
| }; | |
| } | |
| export type EmbedDataStore = ReturnType<typeof createEmbedDataStore>; | |