{ "version": 3, "sources": ["../src/mermaid.ts"], "sourcesContent": ["/**\n * Web page integration module for the mermaid framework. It uses the mermaidAPI for mermaid\n * functionality and to render the diagrams to svg code!\n */\nimport { dedent } from 'ts-dedent';\nimport { MermaidConfig } from './config.type.js';\nimport { log } from './logger.js';\nimport utils from './utils.js';\nimport { mermaidAPI, ParseOptions, RenderResult } from './mermaidAPI.js';\nimport {\n registerLazyLoadedDiagrams,\n loadRegisteredDiagrams,\n detectType,\n} from './diagram-api/detectType.js';\nimport type { ParseErrorFunction } from './Diagram.js';\nimport { isDetailedError } from './utils.js';\nimport type { DetailedError } from './utils.js';\nimport { ExternalDiagramDefinition } from './diagram-api/types.js';\nimport { UnknownDiagramError } from './errors.js';\n\nexport type {\n MermaidConfig,\n DetailedError,\n ExternalDiagramDefinition,\n ParseErrorFunction,\n RenderResult,\n ParseOptions,\n UnknownDiagramError,\n};\n\nexport interface RunOptions {\n /**\n * The query selector to use when finding elements to render. Default: `\".mermaid\"`.\n */\n querySelector?: string;\n /**\n * The nodes to render. If this is set, `querySelector` will be ignored.\n */\n nodes?: ArrayLike;\n /**\n * A callback to call after each diagram is rendered.\n */\n postRenderCallback?: (id: string) => unknown;\n /**\n * If `true`, errors will be logged to the console, but not thrown. Default: `false`\n */\n suppressErrors?: boolean;\n}\n\nconst handleError = (error: unknown, errors: DetailedError[], parseError?: ParseErrorFunction) => {\n log.warn(error);\n if (isDetailedError(error)) {\n // handle case where error string and hash were\n // wrapped in object like`const error = { str, hash };`\n if (parseError) {\n parseError(error.str, error.hash);\n }\n errors.push({ ...error, message: error.str, error });\n } else {\n // assume it is just error string and pass it on\n if (parseError) {\n parseError(error);\n }\n if (error instanceof Error) {\n errors.push({\n str: error.message,\n message: error.message,\n hash: error.name,\n error,\n });\n }\n }\n};\n\n/**\n * ## run\n *\n * Function that goes through the document to find the chart definitions in there and render them.\n *\n * The function tags the processed attributes with the attribute data-processed and ignores found\n * elements with the attribute already set. This way the init function can be triggered several\n * times.\n *\n * ```mermaid\n * graph LR;\n * a(Find elements)-->b{Processed}\n * b-->|Yes|c(Leave element)\n * b-->|No |d(Transform)\n * ```\n *\n * Renders the mermaid diagrams\n *\n * @param options - Optional runtime configs\n */\nconst run = async function (\n options: RunOptions = {\n querySelector: '.mermaid',\n }\n) {\n try {\n await runThrowsErrors(options);\n } catch (e) {\n if (isDetailedError(e)) {\n log.error(e.str);\n }\n if (mermaid.parseError) {\n mermaid.parseError(e as string);\n }\n if (!options.suppressErrors) {\n log.error('Use the suppressErrors option to suppress these errors');\n throw e;\n }\n }\n};\n\nconst runThrowsErrors = async function (\n { postRenderCallback, querySelector, nodes }: Omit = {\n querySelector: '.mermaid',\n }\n) {\n const conf = mermaidAPI.getConfig();\n\n log.debug(`${!postRenderCallback ? 'No ' : ''}Callback function found`);\n\n let nodesToProcess: ArrayLike;\n if (nodes) {\n nodesToProcess = nodes;\n } else if (querySelector) {\n nodesToProcess = document.querySelectorAll(querySelector);\n } else {\n throw new Error('Nodes and querySelector are both undefined');\n }\n\n log.debug(`Found ${nodesToProcess.length} diagrams`);\n if (conf?.startOnLoad !== undefined) {\n log.debug('Start On Load: ' + conf?.startOnLoad);\n mermaidAPI.updateSiteConfig({ startOnLoad: conf?.startOnLoad });\n }\n\n // generate the id of the diagram\n const idGenerator = new utils.initIdGenerator(conf.deterministicIds, conf.deterministicIDSeed);\n\n let txt: string;\n const errors: DetailedError[] = [];\n\n // element is the current div with mermaid class\n // eslint-disable-next-line unicorn/prefer-spread\n for (const element of Array.from(nodesToProcess)) {\n log.info('Rendering diagram: ' + element.id);\n /*! Check if previously processed */\n if (element.getAttribute('data-processed')) {\n continue;\n }\n element.setAttribute('data-processed', 'true');\n\n const id = `mermaid-${idGenerator.next()}`;\n\n // Fetch the graph definition including tags\n txt = element.innerHTML;\n\n // transforms the html to pure text\n txt = dedent(utils.entityDecode(txt)) // removes indentation, required for YAML parsing\n .trim()\n .replace(//gi, '
');\n\n const init = utils.detectInit(txt);\n if (init) {\n log.debug('Detected early reinit: ', init);\n }\n try {\n const { svg, bindFunctions } = await render(id, txt, element);\n element.innerHTML = svg;\n if (postRenderCallback) {\n await postRenderCallback(id);\n }\n if (bindFunctions) {\n bindFunctions(element);\n }\n } catch (error) {\n handleError(error, errors, mermaid.parseError);\n }\n }\n if (errors.length > 0) {\n // TODO: We should be throwing an error object.\n throw errors[0];\n }\n};\n\n/**\n * Used to set configurations for mermaid.\n * This function should be called before the run function.\n * @param config - Configuration object for mermaid.\n */\n\nconst initialize = function (config: MermaidConfig) {\n mermaidAPI.initialize(config);\n};\n\n/**\n * ## init\n *\n * @deprecated Use {@link initialize} and {@link run} instead.\n *\n * Renders the mermaid diagrams\n *\n * @param config - **Deprecated**, please set configuration in {@link initialize}.\n * @param nodes - **Default**: `.mermaid`. One of the following:\n * - A DOM Node\n * - An array of DOM nodes (as would come from a jQuery selector)\n * - A W3C selector, a la `.mermaid`\n * @param callback - Called once for each rendered diagram's id.\n */\nconst init = async function (\n config?: MermaidConfig,\n nodes?: string | HTMLElement | NodeListOf,\n callback?: (id: string) => unknown\n) {\n log.warn('mermaid.init is deprecated. Please use run instead.');\n if (config) {\n initialize(config);\n }\n const runOptions: RunOptions = { postRenderCallback: callback, querySelector: '.mermaid' };\n if (typeof nodes === 'string') {\n runOptions.querySelector = nodes;\n } else if (nodes) {\n if (nodes instanceof HTMLElement) {\n runOptions.nodes = [nodes];\n } else {\n runOptions.nodes = nodes;\n }\n }\n await run(runOptions);\n};\n\n/**\n * Used to register external diagram types.\n * @param diagrams - Array of {@link ExternalDiagramDefinition}.\n * @param opts - If opts.lazyLoad is false, the diagrams will be loaded immediately.\n */\nconst registerExternalDiagrams = async (\n diagrams: ExternalDiagramDefinition[],\n {\n lazyLoad = true,\n }: {\n lazyLoad?: boolean;\n } = {}\n) => {\n registerLazyLoadedDiagrams(...diagrams);\n if (lazyLoad === false) {\n await loadRegisteredDiagrams();\n }\n};\n\n/**\n * ##contentLoaded Callback function that is called when page is loaded. This functions fetches\n * configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the\n * page.\n */\nconst contentLoaded = function () {\n if (mermaid.startOnLoad) {\n const { startOnLoad } = mermaidAPI.getConfig();\n if (startOnLoad) {\n mermaid.run().catch((err) => log.error('Mermaid failed to initialize', err));\n }\n }\n};\n\nif (typeof document !== 'undefined') {\n /*!\n * Wait for document loaded before starting the execution\n */\n window.addEventListener('load', contentLoaded, false);\n window.addEventListener('error', ({ message }) => {\n if (message.includes('mermaid.initialize is not a function')) {\n const notify = () =>\n // eslint-disable-next-line no-console\n console.error(`------------------------------\nBreaking change in Mermaid v11\n------------------------------\nUse mermaid.default.initialize() instead of mermaid.initialize()\nRead more: https://github.com/mermaid-js/mermaid/releases/tag/v11.0.0\n`);\n notify();\n // Log again after a delay to ensure it's the last message\n setTimeout(notify, 1000);\n }\n });\n}\n\n/**\n * ## setParseErrorHandler Alternative to directly setting parseError using:\n *\n * ```js\n * mermaid.parseError = function(err,hash){=\n * forExampleDisplayErrorInGui(err); // do something with the error\n * };\n * ```\n *\n * This is provided for environments where the mermaid object can't directly have a new member added\n * to it (eg. dart interop wrapper). (Initially there is no parseError member of mermaid).\n *\n * @param parseErrorHandler - New parseError() callback.\n */\nconst setParseErrorHandler = function (parseErrorHandler: (err: any, hash: any) => void) {\n mermaid.parseError = parseErrorHandler;\n};\n\nconst executionQueue: (() => Promise)[] = [];\nlet executionQueueRunning = false;\nconst executeQueue = async () => {\n if (executionQueueRunning) {\n return;\n }\n executionQueueRunning = true;\n while (executionQueue.length > 0) {\n const f = executionQueue.shift();\n if (f) {\n try {\n await f();\n } catch (e) {\n log.error('Error executing queue', e);\n }\n }\n }\n executionQueueRunning = false;\n};\n\n/**\n * Parse the text and validate the syntax.\n * @param text - The mermaid diagram definition.\n * @param parseOptions - Options for parsing.\n * @returns true if the diagram is valid, false otherwise if parseOptions.suppressErrors is true.\n * @throws Error if the diagram is invalid and parseOptions.suppressErrors is false.\n */\nconst parse = async (text: string, parseOptions?: ParseOptions): Promise => {\n return new Promise((resolve, reject) => {\n // This promise will resolve when the render call is done.\n // It will be queued first and will be executed when it is first in line\n const performCall = () =>\n new Promise((res, rej) => {\n mermaidAPI.parse(text, parseOptions).then(\n (r) => {\n // This resolves for the promise for the queue handling\n res(r);\n // This fulfills the promise sent to the value back to the original caller\n resolve(r);\n },\n (e) => {\n log.error('Error parsing', e);\n mermaid.parseError?.(e);\n rej(e);\n reject(e);\n }\n );\n });\n executionQueue.push(performCall);\n executeQueue().catch(reject);\n });\n};\n\n/**\n * Function that renders an svg with a graph from a chart definition. Usage example below.\n *\n * ```javascript\n * element = document.querySelector('#graphDiv');\n * const graphDefinition = 'graph TB\\na-->b';\n * const { svg, bindFunctions } = await mermaid.render('graphDiv', graphDefinition);\n * element.innerHTML = svg;\n * bindFunctions?.(element);\n * ```\n *\n * @remarks\n * Multiple calls to this function will be enqueued to run serially.\n *\n * @param id - The id for the SVG element (the element to be rendered)\n * @param text - The text for the graph definition\n * @param container - HTML element where the svg will be inserted. (Is usually element with the .mermaid class)\n * If no svgContainingElement is provided then the SVG element will be appended to the body.\n * Selector to element in which a div with the graph temporarily will be\n * inserted. If one is provided a hidden div will be inserted in the body of the page instead. The\n * element will be removed when rendering is completed.\n * @returns Returns the SVG Definition and BindFunctions.\n */\nconst render = (id: string, text: string, container?: Element): Promise => {\n return new Promise((resolve, reject) => {\n // This promise will resolve when the mermaidAPI.render call is done.\n // It will be queued first and will be executed when it is first in line\n const performCall = () =>\n new Promise((res, rej) => {\n mermaidAPI.render(id, text, container).then(\n (r) => {\n // This resolves for the promise for the queue handling\n res(r);\n // This fulfills the promise sent to the value back to the original caller\n resolve(r);\n },\n (e) => {\n log.error('Error parsing', e);\n mermaid.parseError?.(e);\n rej(e);\n reject(e);\n }\n );\n });\n executionQueue.push(performCall);\n executeQueue().catch(reject);\n });\n};\n\nexport interface Mermaid {\n startOnLoad: boolean;\n parseError?: ParseErrorFunction;\n mermaidAPI: typeof mermaidAPI;\n parse: typeof parse;\n render: typeof render;\n init: typeof init;\n run: typeof run;\n registerExternalDiagrams: typeof registerExternalDiagrams;\n initialize: typeof initialize;\n contentLoaded: typeof contentLoaded;\n setParseErrorHandler: typeof setParseErrorHandler;\n detectType: typeof detectType;\n}\n\nconst mermaid: Mermaid = {\n startOnLoad: true,\n mermaidAPI,\n parse,\n render,\n init,\n run,\n registerExternalDiagrams,\n initialize,\n parseError: undefined,\n contentLoaded,\n setParseErrorHandler,\n detectType,\n};\n\nexport default mermaid;\n"], "mappings": "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", "names": ["handleError", "__name", "error", "errors", "parseError", "log", "isDetailedError", "run", "options", "runThrowsErrors", "e", "mermaid", "postRenderCallback", "querySelector", "nodes", "conf", "mermaidAPI", "nodesToProcess", "idGenerator", "utils_default", "txt", "element", "id", "dedent", "init", "svg", "bindFunctions", "render", "initialize", "config", "callback", "runOptions", "registerExternalDiagrams", "diagrams", "lazyLoad", "registerLazyLoadedDiagrams", "loadRegisteredDiagrams", "contentLoaded", "startOnLoad", "err", "message", "notify", "setParseErrorHandler", "parseErrorHandler", "executionQueue", "executionQueueRunning", "executeQueue", "f", "parse", "text", "parseOptions", "resolve", "reject", "performCall", "res", "rej", "r", "container", "detectType", "mermaid_default"] }