'use client' import type { ExcalidrawElement } from '@excalidraw/excalidraw/element/types' import type { BinaryFiles } from '@excalidraw/excalidraw/types' /** * Parses canvas JSON from DB — either a bare elements array or { elements, files }. * Returns null for PPTX placeholders or invalid JSON. */ export function parseExcalidrawSceneFromCanvasData( dataStr: string ): { elements: readonly ExcalidrawElement[]; files: BinaryFiles | null } | null { if (!dataStr?.trim()) return null try { const parsed = JSON.parse(dataStr) if (parsed && parsed.type === 'pptx') return null if (Array.isArray(parsed)) { return { elements: parsed as ExcalidrawElement[], files: null } } if (parsed?.elements && Array.isArray(parsed.elements)) { const files = parsed.files && typeof parsed.files === 'object' ? (parsed.files as BinaryFiles) : null return { elements: parsed.elements as readonly ExcalidrawElement[], files } } } catch { /* ignore */ } return null } /** * Renders Excali scene to PNG in the browser (uses Excalidraw export helpers). */ export async function exportExcalidrawSceneToPngBlob(dataStr: string): Promise { const scene = parseExcalidrawSceneFromCanvasData(dataStr) if (!scene || scene.elements.length === 0) return null const { exportToBlob, getNonDeletedElements, MIME_TYPES } = await import('@excalidraw/excalidraw') const elements = getNonDeletedElements(scene.elements as ExcalidrawElement[]) if (!elements.length) return null try { return await exportToBlob({ elements, files: scene.files, mimeType: MIME_TYPES.png, exportPadding: 24, maxWidthOrHeight: 2400, appState: { exportBackground: true, exportWithDarkMode: false, viewBackgroundColor: '#ffffff', }, }) } catch (e) { console.error('[excalidraw-export-image] exportToBlob failed:', e) return null } }