diff --git a/packages/layout-engine/pm-adapter/src/utilities.test.ts b/packages/layout-engine/pm-adapter/src/utilities.test.ts index c9b231da1d..1218404f3b 100644 --- a/packages/layout-engine/pm-adapter/src/utilities.test.ts +++ b/packages/layout-engine/pm-adapter/src/utilities.test.ts @@ -836,6 +836,40 @@ describe('Media Utilities', () => { const result = hydrateImageBlocks(blocks, mediaFiles); expect(result[0].src).toBe('data:image/png;base64,iVBORw0KGgoAAAANS'); }); + + it('handles Uint8Array media values from persistence layers', () => { + const blocks: FlowBlock[] = [ + { + kind: 'image', + id: '1', + src: 'media/image.png', + runs: [], + }, + ]; + // Persistence layers (e.g., Y.js binary encoding) may return Uint8Array + const base64String = 'iVBORw0KGgoAAAANS'; + const mediaFiles = { 'media/image.png': new TextEncoder().encode(base64String) }; + + const result = hydrateImageBlocks(blocks, mediaFiles); + expect(result[0].src).toBe('data:image/png;base64,iVBORw0KGgoAAAANS'); + }); + + it('handles Uint8Array data URI values from persistence layers', () => { + const blocks: FlowBlock[] = [ + { + kind: 'image', + id: '1', + src: 'media/image.png', + runs: [], + }, + ]; + // Data URI stored as Uint8Array + const dataUri = 'data:image/png;base64,iVBORw0KGgoAAAANS'; + const mediaFiles = { 'media/image.png': new TextEncoder().encode(dataUri) }; + + const result = hydrateImageBlocks(blocks, mediaFiles); + expect(result[0].src).toBe('data:image/png;base64,iVBORw0KGgoAAAANS'); + }); }); describe('hydrateImageBlocks - ShapeGroup image hydration', () => { diff --git a/packages/layout-engine/pm-adapter/src/utilities.ts b/packages/layout-engine/pm-adapter/src/utilities.ts index 978a1621b7..1af7679a7f 100644 --- a/packages/layout-engine/pm-adapter/src/utilities.ts +++ b/packages/layout-engine/pm-adapter/src/utilities.ts @@ -954,7 +954,7 @@ export function inferExtensionFromPath(value?: string | null): string | undefine * // Matches via candidate path: word/media/rId3.png * ``` */ -export function hydrateImageBlocks(blocks: FlowBlock[], mediaFiles?: Record): FlowBlock[] { +export function hydrateImageBlocks(blocks: FlowBlock[], mediaFiles?: Record): FlowBlock[] { if (!mediaFiles || Object.keys(mediaFiles).length === 0) { return blocks; } @@ -963,7 +963,9 @@ export function hydrateImageBlocks(blocks: FlowBlock[], mediaFiles?: Record { const normalized = normalizeMediaKey(key); if (normalized) { - normalizedMedia.set(normalized, value); + // Handle Uint8Array values from persistence layers (e.g., Y.js binary encoding) + const stringValue = value instanceof Uint8Array ? new TextDecoder().decode(value) : value; + normalizedMedia.set(normalized, stringValue); } });