1import mermaid from 'mermaid'23const CHANNEL = 'diagram.zip:renderer:v1'4const ENGINE = 'mermaid'5const VERSION = 'mermaid@11.17.0'6const BUILD = 'mermaid-11.17.0-client-unit-2'7const MAX_SOURCE_LENGTH = 100_00089mermaid.initialize({10 startOnLoad: false,11 securityLevel: 'strict',12 htmlLabels: false,13 secure: [14 'secure', 'securityLevel', 'startOnLoad', 'maxTextSize',15 'suppressErrorRendering', 'maxEdges', 'htmlLabels',16 ],17 suppressErrorRendering: true,18 maxTextSize: MAX_SOURCE_LENGTH,19 maxEdges: 5_000,20 flowchart: { useMaxWidth: false },21})2223let queue = Promise.resolve()2425async function render(message) {26 if (typeof message.source !== 'string' || message.source.length > MAX_SOURCE_LENGTH) {27 throw new Error('Mermaid source must be a string no larger than 100 KB.')28 }29 const id = `diagramzip-${message.requestId.replace(/[^a-zA-Z0-9_-]/g, '')}`30 const { svg } = await mermaid.render(id, message.source)31 return svg32}3334window.addEventListener('message', event => {35 const message = event.data36 if (37 event.source !== parent38 || message?.channel !== CHANNEL39 || message?.type !== 'render'40 || message?.engine !== ENGINE41 || typeof message?.requestId !== 'string'42 ) return4344 queue = queue.then(async () => {45 try {46 parent.postMessage({47 channel: CHANNEL,48 type: 'result',49 requestId: message.requestId,50 ok: true,51 svg: await render(message),52 version: VERSION,53 build: BUILD,54 pipeline: [ENGINE],55 }, '*')56 } catch (error) {57 parent.postMessage({58 channel: CHANNEL,59 type: 'result',60 requestId: message.requestId,61 ok: false,62 error: error instanceof Error ? error.message.slice(0, 500) : 'Mermaid rendering failed.',63 }, '*')64 }65 })66})6768parent.postMessage({ channel: CHANNEL, type: 'ready', engine: ENGINE, version: VERSION, build: BUILD }, '*')