Spaces:
Runtime error
Runtime error
| import * as Y from "yjs"; | |
| /** | |
| * Collaborative store for HTML embed content, backed by Y.Map("embeds"). | |
| * | |
| * Each key is a filename (e.g. "d3-scaling-chart.html") and the value is | |
| * the raw HTML fragment (not a full document - buildDoc wraps it for display). | |
| * | |
| * The ProseMirror htmlEmbed node only stores the `src` attribute as a | |
| * reference key. The actual HTML lives here so multiple collaborators | |
| * can edit chart content concurrently. | |
| */ | |
| export function createEmbedStore(ydoc: Y.Doc) { | |
| const ymap = ydoc.getMap<string>("embeds"); | |
| function get(src: string): string { | |
| return ymap.get(src) ?? ""; | |
| } | |
| function set(src: string, html: string) { | |
| ymap.set(src, html); | |
| } | |
| function has(src: string): boolean { | |
| return ymap.has(src); | |
| } | |
| function remove(src: string) { | |
| ymap.delete(src); | |
| } | |
| function rename(oldSrc: string, newSrc: string) { | |
| const html = ymap.get(oldSrc); | |
| if (html !== undefined) { | |
| ydoc.transact(() => { | |
| ymap.set(newSrc, html); | |
| ymap.delete(oldSrc); | |
| }); | |
| } | |
| } | |
| /** Apply a search/replace patch to an existing embed. */ | |
| function patch(src: string, search: string, replace: string): boolean { | |
| const html = ymap.get(src); | |
| if (!html || !html.includes(search)) return false; | |
| ymap.set(src, html.replace(search, replace)); | |
| return true; | |
| } | |
| function keys(): string[] { | |
| return Array.from(ymap.keys()); | |
| } | |
| function getAll(): Record<string, string> { | |
| const result: Record<string, string> = {}; | |
| ymap.forEach((val, key) => { | |
| result[key] = val; | |
| }); | |
| return result; | |
| } | |
| /** | |
| * Observe changes to any embed. | |
| * Returns an unsubscribe function. | |
| */ | |
| function observe(callback: () => void) { | |
| ymap.observe(callback); | |
| return () => ymap.unobserve(callback); | |
| } | |
| /** | |
| * Observe changes to a specific embed key. | |
| * Returns an unsubscribe function. | |
| */ | |
| function observeKey(src: string, callback: (html: string) => void) { | |
| const handler = (event: Y.YMapEvent<string>) => { | |
| if (event.keysChanged.has(src)) { | |
| callback(ymap.get(src) ?? ""); | |
| } | |
| }; | |
| ymap.observe(handler); | |
| return () => ymap.unobserve(handler); | |
| } | |
| return { | |
| get, | |
| set, | |
| has, | |
| remove, | |
| rename, | |
| patch, | |
| keys, | |
| getAll, | |
| observe, | |
| observeKey, | |
| }; | |
| } | |
| export type EmbedStore = ReturnType<typeof createEmbedStore>; | |