@hackersheet/next-document-content-components 0.1.0-alpha.31 → 0.1.0-alpha.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/cjs/components/mermaid/index.d.ts +3 -2
  2. package/dist/cjs/components/mermaid/index.js +5 -6
  3. package/dist/cjs/components/mermaid/index.js.map +1 -1
  4. package/dist/cjs/components/mermaid/mermaid-iframe-renderer.d.ts +33 -0
  5. package/dist/cjs/components/mermaid/mermaid-iframe-renderer.js +138 -0
  6. package/dist/cjs/components/mermaid/mermaid-iframe-renderer.js.map +1 -0
  7. package/dist/cjs/components/mermaid/mermaid-renderer.d.ts +1 -20
  8. package/dist/cjs/components/mermaid/mermaid-renderer.js +2 -38
  9. package/dist/cjs/components/mermaid/mermaid-renderer.js.map +1 -1
  10. package/dist/cjs/components/mermaid/mermaid-utils.d.ts +1 -15
  11. package/dist/cjs/components/mermaid/mermaid-utils.js +0 -11
  12. package/dist/cjs/components/mermaid/mermaid-utils.js.map +1 -1
  13. package/dist/cjs/components/mermaid/mermaid.d.ts +2 -1
  14. package/dist/cjs/components/mermaid/mermaid.js +4 -6
  15. package/dist/cjs/components/mermaid/mermaid.js.map +1 -1
  16. package/dist/esm/components/mermaid/index.d.mts +3 -2
  17. package/dist/esm/components/mermaid/index.mjs +5 -5
  18. package/dist/esm/components/mermaid/index.mjs.map +1 -1
  19. package/dist/esm/components/mermaid/mermaid-iframe-renderer.d.mts +33 -0
  20. package/dist/esm/components/mermaid/mermaid-iframe-renderer.mjs +113 -0
  21. package/dist/esm/components/mermaid/mermaid-iframe-renderer.mjs.map +1 -0
  22. package/dist/esm/components/mermaid/mermaid-renderer.d.mts +1 -20
  23. package/dist/esm/components/mermaid/mermaid-renderer.mjs +2 -36
  24. package/dist/esm/components/mermaid/mermaid-renderer.mjs.map +1 -1
  25. package/dist/esm/components/mermaid/mermaid-utils.d.mts +1 -15
  26. package/dist/esm/components/mermaid/mermaid-utils.mjs +0 -10
  27. package/dist/esm/components/mermaid/mermaid-utils.mjs.map +1 -1
  28. package/dist/esm/components/mermaid/mermaid.d.mts +2 -1
  29. package/dist/esm/components/mermaid/mermaid.mjs +6 -8
  30. package/dist/esm/components/mermaid/mermaid.mjs.map +1 -1
  31. package/package.json +1 -2
  32. package/dist/cjs/components/code-block/__tests__/parse-tree-output.unit.test.d.ts +0 -2
  33. package/dist/cjs/components/code-block/__tests__/parse-tree-output.unit.test.js +0 -627
  34. package/dist/cjs/components/code-block/__tests__/parse-tree-output.unit.test.js.map +0 -1
  35. package/dist/esm/components/code-block/__tests__/parse-tree-output.unit.test.d.mts +0 -2
  36. package/dist/esm/components/code-block/__tests__/parse-tree-output.unit.test.mjs +0 -626
  37. package/dist/esm/components/code-block/__tests__/parse-tree-output.unit.test.mjs.map +0 -1
@@ -1,5 +1,6 @@
1
1
  export { default as Mermaid, default } from './mermaid.js';
2
- export { getErrorMessage, hasValidSvgDimensions, normalizeCode } from './mermaid-utils.js';
3
- export { MermaidRenderResult, renderWithBeautifulMermaid, renderWithMermaidFallback, withSafeJsonStringify } from './mermaid-renderer.js';
2
+ export { hasValidSvgDimensions, normalizeCode } from './mermaid-utils.js';
3
+ export { MermaidRenderResult, renderWithBeautifulMermaid } from './mermaid-renderer.js';
4
+ export { destroyIframe, renderWithIframe } from './mermaid-iframe-renderer.js';
4
5
  import 'react';
5
6
  import '@hackersheet/react-document-content';
@@ -30,26 +30,25 @@ var mermaid_exports = {};
30
30
  __export(mermaid_exports, {
31
31
  Mermaid: () => import_mermaid2.default,
32
32
  default: () => import_mermaid.default,
33
- getErrorMessage: () => import_mermaid_utils.getErrorMessage,
33
+ destroyIframe: () => import_mermaid_iframe_renderer.destroyIframe,
34
34
  hasValidSvgDimensions: () => import_mermaid_utils.hasValidSvgDimensions,
35
35
  normalizeCode: () => import_mermaid_utils.normalizeCode,
36
36
  renderWithBeautifulMermaid: () => import_mermaid_renderer.renderWithBeautifulMermaid,
37
- renderWithMermaidFallback: () => import_mermaid_renderer.renderWithMermaidFallback,
38
- withSafeJsonStringify: () => import_mermaid_renderer.withSafeJsonStringify
37
+ renderWithIframe: () => import_mermaid_iframe_renderer.renderWithIframe
39
38
  });
40
39
  module.exports = __toCommonJS(mermaid_exports);
41
40
  var import_mermaid = __toESM(require("./mermaid"));
42
41
  var import_mermaid2 = __toESM(require("./mermaid"));
43
42
  var import_mermaid_utils = require("./mermaid-utils");
44
43
  var import_mermaid_renderer = require("./mermaid-renderer");
44
+ var import_mermaid_iframe_renderer = require("./mermaid-iframe-renderer");
45
45
  // Annotate the CommonJS export names for ESM import in node:
46
46
  0 && (module.exports = {
47
47
  Mermaid,
48
- getErrorMessage,
48
+ destroyIframe,
49
49
  hasValidSvgDimensions,
50
50
  normalizeCode,
51
51
  renderWithBeautifulMermaid,
52
- renderWithMermaidFallback,
53
- withSafeJsonStringify
52
+ renderWithIframe
54
53
  });
55
54
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/mermaid/index.ts"],"sourcesContent":["/**\n * Mermaid diagram component and utilities.\n * @module\n */\n\nexport { default } from './mermaid';\nexport { default as Mermaid } from './mermaid';\nexport { getErrorMessage, hasValidSvgDimensions, normalizeCode } from './mermaid-utils';\nexport { renderWithBeautifulMermaid, renderWithMermaidFallback, withSafeJsonStringify } from './mermaid-renderer';\nexport type { MermaidRenderResult } from './mermaid-renderer';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,qBAAwB;AACxB,IAAAA,kBAAmC;AACnC,2BAAsE;AACtE,8BAA6F;","names":["import_mermaid"]}
1
+ {"version":3,"sources":["../../../../src/components/mermaid/index.ts"],"sourcesContent":["/**\n * Mermaid diagram component and utilities.\n * @module\n */\n\nexport { default } from './mermaid';\nexport { default as Mermaid } from './mermaid';\nexport { hasValidSvgDimensions, normalizeCode } from './mermaid-utils';\nexport { renderWithBeautifulMermaid } from './mermaid-renderer';\nexport { destroyIframe, renderWithIframe } from './mermaid-iframe-renderer';\nexport type { MermaidRenderResult } from './mermaid-renderer';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,qBAAwB;AACxB,IAAAA,kBAAmC;AACnC,2BAAqD;AACrD,8BAA2C;AAC3C,qCAAgD;","names":["import_mermaid"]}
@@ -0,0 +1,33 @@
1
+ import { MermaidRenderResult } from './mermaid-renderer.js';
2
+
3
+ /**
4
+ * Sandboxed iframe-based mermaid renderer.
5
+ * Isolates mermaid rendering from cross-origin iframes on the page.
6
+ * @module
7
+ */
8
+
9
+ /**
10
+ * Render mermaid diagram using a sandboxed iframe.
11
+ * This isolates the rendering from any cross-origin content on the page.
12
+ *
13
+ * @param code - Mermaid diagram code
14
+ * @param isDark - Whether to use dark theme
15
+ * @param timeout - Timeout in milliseconds (default: 10000)
16
+ * @returns Promise resolving to render result
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const result = await renderWithIframe('graph TD; A-->B;', false);
21
+ * if (result.success) {
22
+ * console.log(result.svg);
23
+ * }
24
+ * ```
25
+ */
26
+ declare function renderWithIframe(code: string, isDark: boolean, timeout?: number): Promise<MermaidRenderResult>;
27
+ /**
28
+ * Clean up the iframe instance.
29
+ * Call this when the mermaid component is no longer needed.
30
+ */
31
+ declare function destroyIframe(): void;
32
+
33
+ export { destroyIframe, renderWithIframe };
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var mermaid_iframe_renderer_exports = {};
21
+ __export(mermaid_iframe_renderer_exports, {
22
+ destroyIframe: () => destroyIframe,
23
+ renderWithIframe: () => renderWithIframe
24
+ });
25
+ module.exports = __toCommonJS(mermaid_iframe_renderer_exports);
26
+ const MERMAID_CDN_URL = "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs";
27
+ const generateIframeHtml = () => `
28
+ <!DOCTYPE html>
29
+ <html>
30
+ <head>
31
+ <meta charset="UTF-8">
32
+ <style>
33
+ body { margin: 0; padding: 0; background: transparent; }
34
+ #container { display: flex; justify-content: center; }
35
+ </style>
36
+ </head>
37
+ <body>
38
+ <div id="container"></div>
39
+ <script type="module">
40
+ import('${MERMAID_CDN_URL}')
41
+ .then((module) => {
42
+ const mermaid = module.default;
43
+ const counter = { value: 0 };
44
+
45
+ window.addEventListener('message', async (event) => {
46
+ const { type, code, isDark, requestId } = event.data;
47
+ if (type !== 'render') return;
48
+
49
+ const theme = isDark ? 'dark' : 'default';
50
+ mermaid.initialize({ startOnLoad: false, theme });
51
+
52
+ try {
53
+ counter.value += 1;
54
+ const uniqueId = 'mermaid-' + counter.value;
55
+ const { svg } = await mermaid.render(uniqueId, code);
56
+ window.parent.postMessage({ type: 'result', success: true, svg, requestId }, '*');
57
+ } catch (error) {
58
+ const message = error instanceof Error ? error.message : 'Unknown error';
59
+ window.parent.postMessage({ type: 'result', success: false, error: message, requestId }, '*');
60
+ }
61
+ });
62
+
63
+ window.parent.postMessage({ type: 'ready' }, '*');
64
+ });
65
+ </script>
66
+ </body>
67
+ </html>
68
+ `;
69
+ const state = {
70
+ iframe: null,
71
+ ready: null,
72
+ pendingRequests: /* @__PURE__ */ new Map()
73
+ };
74
+ const generateRequestId = () => `${Date.now()}-${Math.random().toString(36).slice(2)}`;
75
+ const handleIframeMessage = (event) => {
76
+ const { data } = event;
77
+ if (data.type !== "result") return;
78
+ const resolver = state.pendingRequests.get(data.requestId);
79
+ if (!resolver) return;
80
+ state.pendingRequests.delete(data.requestId);
81
+ const result = data.success && data.svg ? { success: true, svg: data.svg } : { success: false, error: data.error ?? "Unknown error" };
82
+ resolver(result);
83
+ };
84
+ const createIframe = () => {
85
+ if (state.ready) {
86
+ return state.ready;
87
+ }
88
+ state.ready = new Promise((resolve) => {
89
+ const iframe = document.createElement("iframe");
90
+ iframe.style.cssText = "position:fixed;top:-9999px;left:-9999px;width:1920px;height:1080px;border:0;pointer-events:none;";
91
+ iframe.sandbox.add("allow-scripts", "allow-same-origin");
92
+ iframe.srcdoc = generateIframeHtml();
93
+ const handleReady = (event) => {
94
+ if (event.source !== iframe.contentWindow || event.data.type !== "ready") return;
95
+ window.removeEventListener("message", handleReady);
96
+ window.addEventListener("message", handleIframeMessage);
97
+ resolve();
98
+ };
99
+ window.addEventListener("message", handleReady);
100
+ document.body.appendChild(iframe);
101
+ state.iframe = iframe;
102
+ });
103
+ return state.ready;
104
+ };
105
+ async function renderWithIframe(code, isDark, timeout = 1e4) {
106
+ await createIframe();
107
+ const contentWindow = state.iframe?.contentWindow;
108
+ if (!contentWindow) {
109
+ return { success: false, error: "Failed to create iframe" };
110
+ }
111
+ const requestId = generateRequestId();
112
+ return new Promise((resolve) => {
113
+ const timeoutId = setTimeout(() => {
114
+ state.pendingRequests.delete(requestId);
115
+ resolve({ success: false, error: "Render timeout" });
116
+ }, timeout);
117
+ state.pendingRequests.set(requestId, (result) => {
118
+ clearTimeout(timeoutId);
119
+ resolve(result);
120
+ });
121
+ const message = { type: "render", code, isDark, requestId };
122
+ contentWindow.postMessage(message, "*");
123
+ });
124
+ }
125
+ function destroyIframe() {
126
+ if (!state.iframe) return;
127
+ window.removeEventListener("message", handleIframeMessage);
128
+ state.iframe.remove();
129
+ state.iframe = null;
130
+ state.ready = null;
131
+ state.pendingRequests.clear();
132
+ }
133
+ // Annotate the CommonJS export names for ESM import in node:
134
+ 0 && (module.exports = {
135
+ destroyIframe,
136
+ renderWithIframe
137
+ });
138
+ //# sourceMappingURL=mermaid-iframe-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/mermaid/mermaid-iframe-renderer.ts"],"sourcesContent":["'use client';\n\n/**\n * Sandboxed iframe-based mermaid renderer.\n * Isolates mermaid rendering from cross-origin iframes on the page.\n * @module\n */\n\nimport type { MermaidRenderResult } from './mermaid-renderer';\n\n/**\n * CDN URL for mermaid library.\n * Using ESM build for modern browser compatibility.\n * Used as fallback when beautiful-mermaid doesn't support the diagram type (e.g., Gantt).\n */\nconst MERMAID_CDN_URL = 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';\n\n/**\n * Generate the HTML content for the sandboxed iframe.\n * This HTML includes mermaid library and handles postMessage communication.\n *\n * @returns HTML string for iframe srcdoc\n */\nconst generateIframeHtml = (): string => `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <style>\n body { margin: 0; padding: 0; background: transparent; }\n #container { display: flex; justify-content: center; }\n </style>\n</head>\n<body>\n <div id=\"container\"></div>\n <script type=\"module\">\n import('${MERMAID_CDN_URL}')\n .then((module) => {\n const mermaid = module.default;\n const counter = { value: 0 };\n\n window.addEventListener('message', async (event) => {\n const { type, code, isDark, requestId } = event.data;\n if (type !== 'render') return;\n\n const theme = isDark ? 'dark' : 'default';\n mermaid.initialize({ startOnLoad: false, theme });\n\n try {\n counter.value += 1;\n const uniqueId = 'mermaid-' + counter.value;\n const { svg } = await mermaid.render(uniqueId, code);\n window.parent.postMessage({ type: 'result', success: true, svg, requestId }, '*');\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n window.parent.postMessage({ type: 'result', success: false, error: message, requestId }, '*');\n }\n });\n\n window.parent.postMessage({ type: 'ready' }, '*');\n });\n </script>\n</body>\n</html>\n`;\n\n/**\n * Message sent to iframe for rendering.\n */\ninterface RenderMessage {\n readonly type: 'render';\n readonly code: string;\n readonly isDark: boolean;\n readonly requestId: string;\n}\n\n/**\n * Message received from iframe with render result.\n */\ninterface ResultMessage {\n readonly type: 'result';\n readonly requestId: string;\n readonly success: boolean;\n readonly svg?: string;\n readonly error?: string;\n}\n\n/**\n * Message received when iframe is ready.\n */\ninterface ReadyMessage {\n readonly type: 'ready';\n}\n\ntype IframeMessage = ResultMessage | ReadyMessage;\n\n/**\n * Renderer state container.\n * Using an object instead of separate variables to avoid `let`.\n */\ninterface RendererState {\n iframe: HTMLIFrameElement | null;\n ready: Promise<void> | null;\n readonly pendingRequests: Map<string, (result: MermaidRenderResult) => void>;\n}\n\n/**\n * Singleton renderer state.\n * Reusing a single iframe improves performance.\n */\nconst state: RendererState = {\n iframe: null,\n ready: null,\n pendingRequests: new Map(),\n};\n\n/**\n * Generate a unique request ID.\n *\n * @returns Unique string identifier\n */\nconst generateRequestId = (): string => `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n/**\n * Handle messages from the sandboxed iframe.\n *\n * @param event - Message event from iframe\n */\nconst handleIframeMessage = (event: MessageEvent<IframeMessage>): void => {\n const { data } = event;\n\n if (data.type !== 'result') return;\n\n const resolver = state.pendingRequests.get(data.requestId);\n if (!resolver) return;\n\n state.pendingRequests.delete(data.requestId);\n\n const result: MermaidRenderResult =\n data.success && data.svg\n ? { success: true, svg: data.svg }\n : { success: false, error: data.error ?? 'Unknown error' };\n\n resolver(result);\n};\n\n/**\n * Create and initialize the sandboxed iframe.\n *\n * @returns Promise that resolves when iframe is ready\n */\nconst createIframe = (): Promise<void> => {\n if (state.ready) {\n return state.ready;\n }\n\n state.ready = new Promise((resolve) => {\n const iframe = document.createElement('iframe');\n iframe.style.cssText =\n 'position:fixed;top:-9999px;left:-9999px;width:1920px;height:1080px;border:0;pointer-events:none;';\n iframe.sandbox.add('allow-scripts', 'allow-same-origin');\n iframe.srcdoc = generateIframeHtml();\n\n const handleReady = (event: MessageEvent<IframeMessage>): void => {\n if (event.source !== iframe.contentWindow || event.data.type !== 'ready') return;\n\n window.removeEventListener('message', handleReady);\n window.addEventListener('message', handleIframeMessage);\n resolve();\n };\n\n window.addEventListener('message', handleReady);\n document.body.appendChild(iframe);\n state.iframe = iframe;\n });\n\n return state.ready;\n};\n\n/**\n * Render mermaid diagram using a sandboxed iframe.\n * This isolates the rendering from any cross-origin content on the page.\n *\n * @param code - Mermaid diagram code\n * @param isDark - Whether to use dark theme\n * @param timeout - Timeout in milliseconds (default: 10000)\n * @returns Promise resolving to render result\n *\n * @example\n * ```ts\n * const result = await renderWithIframe('graph TD; A-->B;', false);\n * if (result.success) {\n * console.log(result.svg);\n * }\n * ```\n */\nexport async function renderWithIframe(code: string, isDark: boolean, timeout = 10000): Promise<MermaidRenderResult> {\n await createIframe();\n\n const contentWindow = state.iframe?.contentWindow;\n if (!contentWindow) {\n return { success: false, error: 'Failed to create iframe' };\n }\n\n const requestId = generateRequestId();\n\n return new Promise((resolve) => {\n const timeoutId = setTimeout(() => {\n state.pendingRequests.delete(requestId);\n resolve({ success: false, error: 'Render timeout' });\n }, timeout);\n\n state.pendingRequests.set(requestId, (result) => {\n clearTimeout(timeoutId);\n resolve(result);\n });\n\n const message: RenderMessage = { type: 'render', code, isDark, requestId };\n contentWindow.postMessage(message, '*');\n });\n}\n\n/**\n * Clean up the iframe instance.\n * Call this when the mermaid component is no longer needed.\n */\nexport function destroyIframe(): void {\n if (!state.iframe) return;\n\n window.removeEventListener('message', handleIframeMessage);\n state.iframe.remove();\n state.iframe = null;\n state.ready = null;\n state.pendingRequests.clear();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeA,MAAM,kBAAkB;AAQxB,MAAM,qBAAqB,MAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAa3B,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0E7B,MAAM,QAAuB;AAAA,EAC3B,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,iBAAiB,oBAAI,IAAI;AAC3B;AAOA,MAAM,oBAAoB,MAAc,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAO5F,MAAM,sBAAsB,CAAC,UAA6C;AACxE,QAAM,EAAE,KAAK,IAAI;AAEjB,MAAI,KAAK,SAAS,SAAU;AAE5B,QAAM,WAAW,MAAM,gBAAgB,IAAI,KAAK,SAAS;AACzD,MAAI,CAAC,SAAU;AAEf,QAAM,gBAAgB,OAAO,KAAK,SAAS;AAE3C,QAAM,SACJ,KAAK,WAAW,KAAK,MACjB,EAAE,SAAS,MAAM,KAAK,KAAK,IAAI,IAC/B,EAAE,SAAS,OAAO,OAAO,KAAK,SAAS,gBAAgB;AAE7D,WAAS,MAAM;AACjB;AAOA,MAAM,eAAe,MAAqB;AACxC,MAAI,MAAM,OAAO;AACf,WAAO,MAAM;AAAA,EACf;AAEA,QAAM,QAAQ,IAAI,QAAQ,CAAC,YAAY;AACrC,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,MAAM,UACX;AACF,WAAO,QAAQ,IAAI,iBAAiB,mBAAmB;AACvD,WAAO,SAAS,mBAAmB;AAEnC,UAAM,cAAc,CAAC,UAA6C;AAChE,UAAI,MAAM,WAAW,OAAO,iBAAiB,MAAM,KAAK,SAAS,QAAS;AAE1E,aAAO,oBAAoB,WAAW,WAAW;AACjD,aAAO,iBAAiB,WAAW,mBAAmB;AACtD,cAAQ;AAAA,IACV;AAEA,WAAO,iBAAiB,WAAW,WAAW;AAC9C,aAAS,KAAK,YAAY,MAAM;AAChC,UAAM,SAAS;AAAA,EACjB,CAAC;AAED,SAAO,MAAM;AACf;AAmBA,eAAsB,iBAAiB,MAAc,QAAiB,UAAU,KAAqC;AACnH,QAAM,aAAa;AAEnB,QAAM,gBAAgB,MAAM,QAAQ;AACpC,MAAI,CAAC,eAAe;AAClB,WAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,EAC5D;AAEA,QAAM,YAAY,kBAAkB;AAEpC,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,YAAY,WAAW,MAAM;AACjC,YAAM,gBAAgB,OAAO,SAAS;AACtC,cAAQ,EAAE,SAAS,OAAO,OAAO,iBAAiB,CAAC;AAAA,IACrD,GAAG,OAAO;AAEV,UAAM,gBAAgB,IAAI,WAAW,CAAC,WAAW;AAC/C,mBAAa,SAAS;AACtB,cAAQ,MAAM;AAAA,IAChB,CAAC;AAED,UAAM,UAAyB,EAAE,MAAM,UAAU,MAAM,QAAQ,UAAU;AACzE,kBAAc,YAAY,SAAS,GAAG;AAAA,EACxC,CAAC;AACH;AAMO,SAAS,gBAAsB;AACpC,MAAI,CAAC,MAAM,OAAQ;AAEnB,SAAO,oBAAoB,WAAW,mBAAmB;AACzD,QAAM,OAAO,OAAO;AACpB,QAAM,SAAS;AACf,QAAM,QAAQ;AACd,QAAM,gBAAgB,MAAM;AAC9B;","names":[]}
@@ -8,15 +8,6 @@ type MermaidRenderResult = {
8
8
  success: false;
9
9
  error: string;
10
10
  };
11
- /**
12
- * Run a function with a patched JSON.stringify that handles circular references.
13
- * This is needed because mermaid's block-beta renderer tries to stringify DOM elements.
14
- *
15
- * @param fn - Async function to execute with safe JSON.stringify
16
- * @returns Result of the function
17
- * @internal
18
- */
19
- declare function withSafeJsonStringify<T>(fn: () => Promise<T>): Promise<T>;
20
11
  /**
21
12
  * Render diagram using beautiful-mermaid library.
22
13
  * Uses dynamic import to reduce initial bundle size.
@@ -26,15 +17,5 @@ declare function withSafeJsonStringify<T>(fn: () => Promise<T>): Promise<T>;
26
17
  * @returns SVG string if successful, null otherwise
27
18
  */
28
19
  declare function renderWithBeautifulMermaid(code: string, isDark: boolean): Promise<string | null>;
29
- /**
30
- * Render diagram using original mermaid library as fallback.
31
- * Uses dynamic import to reduce initial bundle size.
32
- *
33
- * @param code - Mermaid diagram code
34
- * @param isDark - Whether to use dark theme
35
- * @param uniqueId - Unique identifier for the mermaid render container
36
- * @returns Result object with success status and SVG or error message
37
- */
38
- declare function renderWithMermaidFallback(code: string, isDark: boolean, uniqueId: string): Promise<MermaidRenderResult>;
39
20
 
40
- export { type MermaidRenderResult, renderWithBeautifulMermaid, renderWithMermaidFallback, withSafeJsonStringify };
21
+ export { type MermaidRenderResult, renderWithBeautifulMermaid };
@@ -29,31 +29,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
30
  var mermaid_renderer_exports = {};
31
31
  __export(mermaid_renderer_exports, {
32
- renderWithBeautifulMermaid: () => renderWithBeautifulMermaid,
33
- renderWithMermaidFallback: () => renderWithMermaidFallback,
34
- withSafeJsonStringify: () => withSafeJsonStringify
32
+ renderWithBeautifulMermaid: () => renderWithBeautifulMermaid
35
33
  });
36
34
  module.exports = __toCommonJS(mermaid_renderer_exports);
37
35
  var import_mermaid_utils = require("./mermaid-utils");
38
- async function withSafeJsonStringify(fn) {
39
- const originalStringify = JSON.stringify;
40
- JSON.stringify = function(value, _replacer, space) {
41
- const seen = /* @__PURE__ */ new WeakSet();
42
- const safeReplacer = (_key, val) => {
43
- if (typeof val === "object" && val !== null) {
44
- if (seen.has(val)) return void 0;
45
- seen.add(val);
46
- }
47
- return val;
48
- };
49
- return originalStringify(value, safeReplacer, space);
50
- };
51
- try {
52
- return await fn();
53
- } finally {
54
- JSON.stringify = originalStringify;
55
- }
56
- }
57
36
  async function renderWithBeautifulMermaid(code, isDark) {
58
37
  const { renderMermaid, THEMES } = await import("beautiful-mermaid");
59
38
  const colors = isDark ? THEMES["github-dark"] : THEMES["github-light"];
@@ -67,23 +46,8 @@ async function renderWithBeautifulMermaid(code, isDark) {
67
46
  }
68
47
  return null;
69
48
  }
70
- async function renderWithMermaidFallback(code, isDark, uniqueId) {
71
- const mermaid = (await import("mermaid")).default;
72
- const mermaidTheme = isDark ? "dark" : "default";
73
- mermaid.initialize({ startOnLoad: false, theme: mermaidTheme });
74
- try {
75
- const { svg } = await withSafeJsonStringify(() => mermaid.render(uniqueId, code));
76
- return { success: true, svg };
77
- } catch (error) {
78
- return { success: false, error: (0, import_mermaid_utils.getErrorMessage)(error) };
79
- } finally {
80
- document.getElementById(`d${uniqueId}`)?.remove();
81
- }
82
- }
83
49
  // Annotate the CommonJS export names for ESM import in node:
84
50
  0 && (module.exports = {
85
- renderWithBeautifulMermaid,
86
- renderWithMermaidFallback,
87
- withSafeJsonStringify
51
+ renderWithBeautifulMermaid
88
52
  });
89
53
  //# sourceMappingURL=mermaid-renderer.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/mermaid/mermaid-renderer.ts"],"sourcesContent":["'use client';\n\n/**\n * Mermaid diagram rendering functions.\n * Handles rendering with beautiful-mermaid and fallback to original mermaid library.\n * @module\n */\n\nimport { getErrorMessage, hasValidSvgDimensions, normalizeCode } from './mermaid-utils';\n\n/**\n * Result type for mermaid rendering operations.\n */\nexport type MermaidRenderResult = { success: true; svg: string } | { success: false; error: string };\n\n/**\n * Run a function with a patched JSON.stringify that handles circular references.\n * This is needed because mermaid's block-beta renderer tries to stringify DOM elements.\n *\n * @param fn - Async function to execute with safe JSON.stringify\n * @returns Result of the function\n * @internal\n */\nexport async function withSafeJsonStringify<T>(fn: () => Promise<T>): Promise<T> {\n const originalStringify = JSON.stringify;\n JSON.stringify = function (value, _replacer, space) {\n const seen = new WeakSet();\n const safeReplacer = (_key: string, val: unknown) => {\n if (typeof val === 'object' && val !== null) {\n if (seen.has(val)) return undefined;\n seen.add(val);\n }\n return val;\n };\n return originalStringify(value, safeReplacer, space);\n };\n try {\n return await fn();\n } finally {\n JSON.stringify = originalStringify;\n }\n}\n\n/**\n * Render diagram using beautiful-mermaid library.\n * Uses dynamic import to reduce initial bundle size.\n *\n * @param code - Mermaid diagram code\n * @param isDark - Whether to use dark theme\n * @returns SVG string if successful, null otherwise\n */\nexport async function renderWithBeautifulMermaid(code: string, isDark: boolean): Promise<string | null> {\n const { renderMermaid, THEMES } = await import('beautiful-mermaid');\n const colors = isDark ? THEMES['github-dark'] : THEMES['github-light'];\n const normalizedCode = normalizeCode(code);\n const result = await renderMermaid(normalizedCode, {\n ...colors,\n transparent: true,\n });\n if (result && hasValidSvgDimensions(result)) {\n return result;\n }\n return null;\n}\n\n/**\n * Render diagram using original mermaid library as fallback.\n * Uses dynamic import to reduce initial bundle size.\n *\n * @param code - Mermaid diagram code\n * @param isDark - Whether to use dark theme\n * @param uniqueId - Unique identifier for the mermaid render container\n * @returns Result object with success status and SVG or error message\n */\nexport async function renderWithMermaidFallback(\n code: string,\n isDark: boolean,\n uniqueId: string\n): Promise<MermaidRenderResult> {\n const mermaid = (await import('mermaid')).default;\n const mermaidTheme = isDark ? 'dark' : 'default';\n mermaid.initialize({ startOnLoad: false, theme: mermaidTheme });\n try {\n const { svg } = await withSafeJsonStringify(() => mermaid.render(uniqueId, code));\n return { success: true, svg };\n } catch (error) {\n return { success: false, error: getErrorMessage(error) };\n } finally {\n document.getElementById(`d${uniqueId}`)?.remove();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,2BAAsE;AAetE,eAAsB,sBAAyB,IAAkC;AAC/E,QAAM,oBAAoB,KAAK;AAC/B,OAAK,YAAY,SAAU,OAAO,WAAW,OAAO;AAClD,UAAM,OAAO,oBAAI,QAAQ;AACzB,UAAM,eAAe,CAAC,MAAc,QAAiB;AACnD,UAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,YAAI,KAAK,IAAI,GAAG,EAAG,QAAO;AAC1B,aAAK,IAAI,GAAG;AAAA,MACd;AACA,aAAO;AAAA,IACT;AACA,WAAO,kBAAkB,OAAO,cAAc,KAAK;AAAA,EACrD;AACA,MAAI;AACF,WAAO,MAAM,GAAG;AAAA,EAClB,UAAE;AACA,SAAK,YAAY;AAAA,EACnB;AACF;AAUA,eAAsB,2BAA2B,MAAc,QAAyC;AACtG,QAAM,EAAE,eAAe,OAAO,IAAI,MAAM,OAAO,mBAAmB;AAClE,QAAM,SAAS,SAAS,OAAO,aAAa,IAAI,OAAO,cAAc;AACrE,QAAM,qBAAiB,oCAAc,IAAI;AACzC,QAAM,SAAS,MAAM,cAAc,gBAAgB;AAAA,IACjD,GAAG;AAAA,IACH,aAAa;AAAA,EACf,CAAC;AACD,MAAI,cAAU,4CAAsB,MAAM,GAAG;AAC3C,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAWA,eAAsB,0BACpB,MACA,QACA,UAC8B;AAC9B,QAAM,WAAW,MAAM,OAAO,SAAS,GAAG;AAC1C,QAAM,eAAe,SAAS,SAAS;AACvC,UAAQ,WAAW,EAAE,aAAa,OAAO,OAAO,aAAa,CAAC;AAC9D,MAAI;AACF,UAAM,EAAE,IAAI,IAAI,MAAM,sBAAsB,MAAM,QAAQ,OAAO,UAAU,IAAI,CAAC;AAChF,WAAO,EAAE,SAAS,MAAM,IAAI;AAAA,EAC9B,SAAS,OAAO;AACd,WAAO,EAAE,SAAS,OAAO,WAAO,sCAAgB,KAAK,EAAE;AAAA,EACzD,UAAE;AACA,aAAS,eAAe,IAAI,QAAQ,EAAE,GAAG,OAAO;AAAA,EAClD;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/mermaid/mermaid-renderer.ts"],"sourcesContent":["'use client';\n\n/**\n * Mermaid diagram rendering functions.\n * Handles rendering with beautiful-mermaid library.\n * @module\n */\n\nimport { hasValidSvgDimensions, normalizeCode } from './mermaid-utils';\n\n/**\n * Result type for mermaid rendering operations.\n */\nexport type MermaidRenderResult = { success: true; svg: string } | { success: false; error: string };\n\n/**\n * Render diagram using beautiful-mermaid library.\n * Uses dynamic import to reduce initial bundle size.\n *\n * @param code - Mermaid diagram code\n * @param isDark - Whether to use dark theme\n * @returns SVG string if successful, null otherwise\n */\nexport async function renderWithBeautifulMermaid(code: string, isDark: boolean): Promise<string | null> {\n const { renderMermaid, THEMES } = await import('beautiful-mermaid');\n const colors = isDark ? THEMES['github-dark'] : THEMES['github-light'];\n const normalizedCode = normalizeCode(code);\n const result = await renderMermaid(normalizedCode, {\n ...colors,\n transparent: true,\n });\n if (result && hasValidSvgDimensions(result)) {\n return result;\n }\n return null;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,2BAAqD;AAerD,eAAsB,2BAA2B,MAAc,QAAyC;AACtG,QAAM,EAAE,eAAe,OAAO,IAAI,MAAM,OAAO,mBAAmB;AAClE,QAAM,SAAS,SAAS,OAAO,aAAa,IAAI,OAAO,cAAc;AACrE,QAAM,qBAAiB,oCAAc,IAAI;AACzC,QAAM,SAAS,MAAM,cAAc,gBAAgB;AAAA,IACjD,GAAG;AAAA,IACH,aAAa;AAAA,EACf,CAAC;AACD,MAAI,cAAU,4CAAsB,MAAM,GAAG;AAC3C,WAAO;AAAA,EACT;AACA,SAAO;AACT;","names":[]}
@@ -31,19 +31,5 @@ declare function normalizeCode(code: string): string;
31
31
  * ```
32
32
  */
33
33
  declare function hasValidSvgDimensions(svg: string): boolean;
34
- /**
35
- * Extract error message from an unknown error value.
36
- *
37
- * @param error - Unknown error value (Error object, string, or other)
38
- * @returns Error message string
39
- *
40
- * @example
41
- * ```ts
42
- * getErrorMessage(new Error('Parse error')) // returns 'Parse error'
43
- * getErrorMessage('Something went wrong') // returns 'Something went wrong'
44
- * getErrorMessage(null) // returns 'Unknown error'
45
- * ```
46
- */
47
- declare function getErrorMessage(error: unknown): string;
48
34
 
49
- export { getErrorMessage, hasValidSvgDimensions, normalizeCode };
35
+ export { hasValidSvgDimensions, normalizeCode };
@@ -18,7 +18,6 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var mermaid_utils_exports = {};
20
20
  __export(mermaid_utils_exports, {
21
- getErrorMessage: () => getErrorMessage,
22
21
  hasValidSvgDimensions: () => hasValidSvgDimensions,
23
22
  normalizeCode: () => normalizeCode
24
23
  });
@@ -41,18 +40,8 @@ function hasValidSvgDimensions(svg) {
41
40
  const height = parseFloat(heightMatch[1]);
42
41
  return Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0;
43
42
  }
44
- function getErrorMessage(error) {
45
- if (error instanceof Error) {
46
- return error.message;
47
- }
48
- if (typeof error === "string") {
49
- return error;
50
- }
51
- return "Unknown error";
52
- }
53
43
  // Annotate the CommonJS export names for ESM import in node:
54
44
  0 && (module.exports = {
55
- getErrorMessage,
56
45
  hasValidSvgDimensions,
57
46
  normalizeCode
58
47
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/mermaid/mermaid-utils.ts"],"sourcesContent":["/**\n * Utility functions for Mermaid diagram processing.\n * These are pure functions that can be easily unit tested.\n * @module\n */\n\n/** Hoisted regex patterns to avoid recreation on each function call. */\nconst TRAILING_SEMICOLON_REGEX = /;(\\s*)$/;\nconst ARROW_LEFT_REGEX = /(\\w)-->/g;\nconst ARROW_RIGHT_REGEX = /-->(\\w)/g;\nconst WIDTH_REGEX = /width=\"([^\"]+)\"/;\nconst HEIGHT_REGEX = /height=\"([^\"]+)\"/;\n\n/**\n * Normalize mermaid code for beautiful-mermaid compatibility.\n * - Removes trailing semicolons from each line\n * - Adds spaces around arrows (e.g., A-->B becomes A --> B)\n *\n * @param code - Raw mermaid diagram code\n * @returns Normalized code string\n *\n * @example\n * ```ts\n * normalizeCode('A-->B;') // returns 'A --> B'\n * ```\n */\nexport function normalizeCode(code: string): string {\n return code\n .split('\\n')\n .map((line) =>\n line\n .replace(TRAILING_SEMICOLON_REGEX, '$1')\n .replace(ARROW_LEFT_REGEX, '$1 -->')\n .replace(ARROW_RIGHT_REGEX, '--> $1')\n )\n .join('\\n');\n}\n\n/**\n * Check if an SVG string has valid dimensions.\n * beautiful-mermaid returns invalid SVGs with negative/infinite dimensions for unsupported diagrams.\n *\n * @param svg - SVG string to validate\n * @returns true if SVG has valid positive finite dimensions\n *\n * @example\n * ```ts\n * hasValidSvgDimensions('<svg width=\"100\" height=\"50\">...</svg>') // returns true\n * hasValidSvgDimensions('<svg width=\"-1\" height=\"Infinity\">...</svg>') // returns false\n * ```\n */\nexport function hasValidSvgDimensions(svg: string): boolean {\n const widthMatch = svg.match(WIDTH_REGEX);\n const heightMatch = svg.match(HEIGHT_REGEX);\n if (!widthMatch || !heightMatch) return false;\n const width = parseFloat(widthMatch[1]);\n const height = parseFloat(heightMatch[1]);\n return Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0;\n}\n\n/**\n * Extract error message from an unknown error value.\n *\n * @param error - Unknown error value (Error object, string, or other)\n * @returns Error message string\n *\n * @example\n * ```ts\n * getErrorMessage(new Error('Parse error')) // returns 'Parse error'\n * getErrorMessage('Something went wrong') // returns 'Something went wrong'\n * getErrorMessage(null) // returns 'Unknown error'\n * ```\n */\nexport function getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === 'string') {\n return error;\n }\n return 'Unknown error';\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,MAAM,2BAA2B;AACjC,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;AAC1B,MAAM,cAAc;AACpB,MAAM,eAAe;AAed,SAAS,cAAc,MAAsB;AAClD,SAAO,KACJ,MAAM,IAAI,EACV;AAAA,IAAI,CAAC,SACJ,KACG,QAAQ,0BAA0B,IAAI,EACtC,QAAQ,kBAAkB,QAAQ,EAClC,QAAQ,mBAAmB,QAAQ;AAAA,EACxC,EACC,KAAK,IAAI;AACd;AAeO,SAAS,sBAAsB,KAAsB;AAC1D,QAAM,aAAa,IAAI,MAAM,WAAW;AACxC,QAAM,cAAc,IAAI,MAAM,YAAY;AAC1C,MAAI,CAAC,cAAc,CAAC,YAAa,QAAO;AACxC,QAAM,QAAQ,WAAW,WAAW,CAAC,CAAC;AACtC,QAAM,SAAS,WAAW,YAAY,CAAC,CAAC;AACxC,SAAO,OAAO,SAAS,KAAK,KAAK,OAAO,SAAS,MAAM,KAAK,QAAQ,KAAK,SAAS;AACpF;AAeO,SAAS,gBAAgB,OAAwB;AACtD,MAAI,iBAAiB,OAAO;AAC1B,WAAO,MAAM;AAAA,EACf;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/mermaid/mermaid-utils.ts"],"sourcesContent":["/**\n * Utility functions for Mermaid diagram processing.\n * These are pure functions that can be easily unit tested.\n * @module\n */\n\n/** Hoisted regex patterns to avoid recreation on each function call. */\nconst TRAILING_SEMICOLON_REGEX = /;(\\s*)$/;\nconst ARROW_LEFT_REGEX = /(\\w)-->/g;\nconst ARROW_RIGHT_REGEX = /-->(\\w)/g;\nconst WIDTH_REGEX = /width=\"([^\"]+)\"/;\nconst HEIGHT_REGEX = /height=\"([^\"]+)\"/;\n\n/**\n * Normalize mermaid code for beautiful-mermaid compatibility.\n * - Removes trailing semicolons from each line\n * - Adds spaces around arrows (e.g., A-->B becomes A --> B)\n *\n * @param code - Raw mermaid diagram code\n * @returns Normalized code string\n *\n * @example\n * ```ts\n * normalizeCode('A-->B;') // returns 'A --> B'\n * ```\n */\nexport function normalizeCode(code: string): string {\n return code\n .split('\\n')\n .map((line) =>\n line\n .replace(TRAILING_SEMICOLON_REGEX, '$1')\n .replace(ARROW_LEFT_REGEX, '$1 -->')\n .replace(ARROW_RIGHT_REGEX, '--> $1')\n )\n .join('\\n');\n}\n\n/**\n * Check if an SVG string has valid dimensions.\n * beautiful-mermaid returns invalid SVGs with negative/infinite dimensions for unsupported diagrams.\n *\n * @param svg - SVG string to validate\n * @returns true if SVG has valid positive finite dimensions\n *\n * @example\n * ```ts\n * hasValidSvgDimensions('<svg width=\"100\" height=\"50\">...</svg>') // returns true\n * hasValidSvgDimensions('<svg width=\"-1\" height=\"Infinity\">...</svg>') // returns false\n * ```\n */\nexport function hasValidSvgDimensions(svg: string): boolean {\n const widthMatch = svg.match(WIDTH_REGEX);\n const heightMatch = svg.match(HEIGHT_REGEX);\n if (!widthMatch || !heightMatch) return false;\n const width = parseFloat(widthMatch[1]);\n const height = parseFloat(heightMatch[1]);\n return Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,MAAM,2BAA2B;AACjC,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;AAC1B,MAAM,cAAc;AACpB,MAAM,eAAe;AAed,SAAS,cAAc,MAAsB;AAClD,SAAO,KACJ,MAAM,IAAI,EACV;AAAA,IAAI,CAAC,SACJ,KACG,QAAQ,0BAA0B,IAAI,EACtC,QAAQ,kBAAkB,QAAQ,EAClC,QAAQ,mBAAmB,QAAQ;AAAA,EACxC,EACC,KAAK,IAAI;AACd;AAeO,SAAS,sBAAsB,KAAsB;AAC1D,QAAM,aAAa,IAAI,MAAM,WAAW;AACxC,QAAM,cAAc,IAAI,MAAM,YAAY;AAC1C,MAAI,CAAC,cAAc,CAAC,YAAa,QAAO;AACxC,QAAM,QAAQ,WAAW,WAAW,CAAC,CAAC;AACtC,QAAM,SAAS,WAAW,YAAY,CAAC,CAAC;AACxC,SAAO,OAAO,SAAS,KAAK,KAAK,OAAO,SAAS,MAAM,KAAK,QAAQ,KAAK,SAAS;AACpF;","names":[]}
@@ -3,12 +3,13 @@ import { MermaidComponentProps } from '@hackersheet/react-document-content';
3
3
 
4
4
  /**
5
5
  * Mermaid diagram component that renders diagrams using beautiful-mermaid.
6
- * Falls back to the original mermaid library if beautiful-mermaid fails.
6
+ * Falls back to a sandboxed iframe renderer if beautiful-mermaid fails.
7
7
  * Automatically switches between light and dark themes based on the current theme.
8
8
  *
9
9
  * @remarks
10
10
  * - Uses dynamic imports to reduce initial bundle size
11
11
  * - Handles hydration mismatch by showing loading state until mounted
12
+ * - Uses sandboxed iframe for fallback to avoid cross-origin issues
12
13
  * - Supports toggling between diagram and code view
13
14
  * - Diagram view shows only the rendered diagram without borders
14
15
  * - Code view shows the source code in a code block style
@@ -34,6 +34,7 @@ __export(mermaid_exports, {
34
34
  module.exports = __toCommonJS(mermaid_exports);
35
35
  var import_next_themes = require("next-themes");
36
36
  var import_react = __toESM(require("react"));
37
+ var import_mermaid_iframe_renderer = require("./mermaid-iframe-renderer");
37
38
  var import_mermaid_renderer = require("./mermaid-renderer");
38
39
  var import_code_block_header = __toESM(require("../code-block/code-block-header"));
39
40
  var import_code_block_icon = __toESM(require("../code-block/code-block-icon"));
@@ -43,8 +44,6 @@ function Mermaid({ code }) {
43
44
  const [renderState, setRenderState] = (0, import_react.useState)({ status: "loading" });
44
45
  const [viewMode, setViewMode] = (0, import_react.useState)("diagram");
45
46
  const { theme, systemTheme } = (0, import_next_themes.useTheme)();
46
- const renderCountRef = (0, import_react.useRef)(0);
47
- const id = (0, import_react.useId)();
48
47
  (0, import_react.useEffect)(() => {
49
48
  setMounted(true);
50
49
  }, []);
@@ -59,14 +58,13 @@ function Mermaid({ code }) {
59
58
  }
60
59
  } catch {
61
60
  }
62
- const uniqueId = `${id}-${++renderCountRef.current}`;
63
- const result = await (0, import_mermaid_renderer.renderWithMermaidFallback)(code, isDark, uniqueId);
61
+ const result = await (0, import_mermaid_iframe_renderer.renderWithIframe)(code, isDark);
64
62
  if (result.success) {
65
63
  setRenderState({ status: "success", svg: result.svg });
66
64
  } else {
67
65
  setRenderState({ status: "error", message: result.error });
68
66
  }
69
- }, [code, id, theme, systemTheme]);
67
+ }, [code, theme, systemTheme]);
70
68
  (0, import_react.useEffect)(() => {
71
69
  if (!mounted) {
72
70
  return;
@@ -105,6 +103,6 @@ function Mermaid({ code }) {
105
103
  },
106
104
  "Diagram"
107
105
  );
108
- return /* @__PURE__ */ import_react.default.createElement("div", { className: `code-block mermaid-block mermaid-code-view ${hasError ? "has-error" : ""}` }, /* @__PURE__ */ import_react.default.createElement(import_code_block_header.default, { icon: /* @__PURE__ */ import_react.default.createElement(import_code_block_icon.default, { language: "mermaid" }), code, actions: toggleButton }), /* @__PURE__ */ import_react.default.createElement("div", { className: "mermaid-code" }, hasError && /* @__PURE__ */ import_react.default.createElement("div", { className: "mermaid-error-message" }, /* @__PURE__ */ import_react.default.createElement("strong", null, "Syntax Error"), /* @__PURE__ */ import_react.default.createElement("span", null, renderState.message)), /* @__PURE__ */ import_react.default.createElement("pre", null, /* @__PURE__ */ import_react.default.createElement("code", null, code))));
106
+ return /* @__PURE__ */ import_react.default.createElement("div", { className: `code-block mermaid-block mermaid-code-view ${hasError ? "has-error" : ""}` }, /* @__PURE__ */ import_react.default.createElement(import_code_block_header.default, { icon: /* @__PURE__ */ import_react.default.createElement(import_code_block_icon.default, { language: "mermaid" }), code, actions: toggleButton }), /* @__PURE__ */ import_react.default.createElement("div", { className: "mermaid-code" }, hasError ? /* @__PURE__ */ import_react.default.createElement("div", { className: "mermaid-error-message" }, /* @__PURE__ */ import_react.default.createElement("strong", null, "Syntax Error"), /* @__PURE__ */ import_react.default.createElement("span", null, renderState.message)) : null, /* @__PURE__ */ import_react.default.createElement("pre", null, /* @__PURE__ */ import_react.default.createElement("code", null, code))));
109
107
  }
110
108
  //# sourceMappingURL=mermaid.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/mermaid/mermaid.tsx"],"sourcesContent":["'use client';\n\nimport { useTheme } from 'next-themes';\nimport React, { useCallback, useEffect, useId, useRef, useState } from 'react';\n\nimport { renderWithBeautifulMermaid, renderWithMermaidFallback } from './mermaid-renderer';\nimport CodeBlockHeader from '../code-block/code-block-header';\nimport CodeBlockIcon from '../code-block/code-block-icon';\n\nimport type { MermaidComponentProps } from '@hackersheet/react-document-content';\n\n\n/**\n * Render state for the mermaid component.\n */\ntype RenderState = { status: 'loading' } | { status: 'success'; svg: string } | { status: 'error'; message: string };\n\n/**\n * View mode for the mermaid component.\n */\ntype ViewMode = 'diagram' | 'code';\n\n/**\n * Hoisted static loading fallback to prevent recreation on each render.\n */\nconst LoadingFallback = (\n <div className=\"mermaid-block mermaid-loading\">\n <div>Loading...</div>\n </div>\n);\n\n/**\n * Mermaid diagram component that renders diagrams using beautiful-mermaid.\n * Falls back to the original mermaid library if beautiful-mermaid fails.\n * Automatically switches between light and dark themes based on the current theme.\n *\n * @remarks\n * - Uses dynamic imports to reduce initial bundle size\n * - Handles hydration mismatch by showing loading state until mounted\n * - Supports toggling between diagram and code view\n * - Diagram view shows only the rendered diagram without borders\n * - Code view shows the source code in a code block style\n */\nexport default function Mermaid({ code }: MermaidComponentProps) {\n const [mounted, setMounted] = useState(false);\n const [renderState, setRenderState] = useState<RenderState>({ status: 'loading' });\n const [viewMode, setViewMode] = useState<ViewMode>('diagram');\n const { theme, systemTheme } = useTheme();\n const renderCountRef = useRef(0);\n const id = useId();\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n const renderDiagram = useCallback(async () => {\n const currentTheme = theme === 'system' ? systemTheme : theme;\n const isDark = currentTheme === 'dark';\n\n try {\n const result = await renderWithBeautifulMermaid(code, isDark);\n if (result) {\n setRenderState({ status: 'success', svg: result });\n return;\n }\n } catch {\n // Fall through to mermaid fallback\n }\n\n const uniqueId = `${id}-${++renderCountRef.current}`;\n const result = await renderWithMermaidFallback(code, isDark, uniqueId);\n if (result.success) {\n setRenderState({ status: 'success', svg: result.svg });\n } else {\n setRenderState({ status: 'error', message: result.error });\n }\n }, [code, id, theme, systemTheme]);\n\n useEffect(() => {\n if (!mounted) {\n return;\n }\n renderDiagram();\n }, [mounted, renderDiagram]);\n\n const toggleViewMode = useCallback(() => {\n setViewMode((prev) => (prev === 'diagram' ? 'code' : 'diagram'));\n }, []);\n\n if (!mounted || renderState.status === 'loading') {\n return LoadingFallback;\n }\n\n const hasError = renderState.status === 'error';\n const showDiagram = viewMode === 'diagram' && !hasError;\n\n if (showDiagram) {\n return (\n <div className=\"mermaid-block mermaid-diagram-view\">\n <div className=\"mermaid-diagram\" dangerouslySetInnerHTML={{ __html: renderState.svg }} />\n <button\n type=\"button\"\n onClick={toggleViewMode}\n className=\"mermaid-toggle-btn\"\n title=\"Show code\"\n aria-label=\"Show code\"\n >\n Code\n </button>\n </div>\n );\n }\n\n const toggleButton = (\n <button\n type=\"button\"\n onClick={toggleViewMode}\n className=\"mermaid-toggle-btn\"\n title=\"Show diagram\"\n disabled={hasError}\n >\n Diagram\n </button>\n );\n\n return (\n <div className={`code-block mermaid-block mermaid-code-view ${hasError ? 'has-error' : ''}`}>\n <CodeBlockHeader icon={<CodeBlockIcon language=\"mermaid\" />} code={code} actions={toggleButton} />\n <div className=\"mermaid-code\">\n {hasError && (\n <div className=\"mermaid-error-message\">\n <strong>Syntax Error</strong>\n <span>{renderState.message}</span>\n </div>\n )}\n <pre>\n <code>{code}</code>\n </pre>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["React","result","CodeBlockHeader","CodeBlockIcon"]}
1
+ {"version":3,"sources":["../../../../src/components/mermaid/mermaid.tsx"],"sourcesContent":["'use client';\n\nimport { useTheme } from 'next-themes';\nimport React, { useCallback, useEffect, useState } from 'react';\n\nimport { renderWithIframe } from './mermaid-iframe-renderer';\nimport { renderWithBeautifulMermaid } from './mermaid-renderer';\nimport CodeBlockHeader from '../code-block/code-block-header';\nimport CodeBlockIcon from '../code-block/code-block-icon';\n\nimport type { MermaidComponentProps } from '@hackersheet/react-document-content';\n\n/**\n * Render state for the mermaid component.\n */\ntype RenderState = { status: 'loading' } | { status: 'success'; svg: string } | { status: 'error'; message: string };\n\n/**\n * View mode for the mermaid component.\n */\ntype ViewMode = 'diagram' | 'code';\n\n/**\n * Hoisted static loading fallback to prevent recreation on each render.\n */\nconst LoadingFallback = (\n <div className=\"mermaid-block mermaid-loading\">\n <div>Loading...</div>\n </div>\n);\n\n/**\n * Mermaid diagram component that renders diagrams using beautiful-mermaid.\n * Falls back to a sandboxed iframe renderer if beautiful-mermaid fails.\n * Automatically switches between light and dark themes based on the current theme.\n *\n * @remarks\n * - Uses dynamic imports to reduce initial bundle size\n * - Handles hydration mismatch by showing loading state until mounted\n * - Uses sandboxed iframe for fallback to avoid cross-origin issues\n * - Supports toggling between diagram and code view\n * - Diagram view shows only the rendered diagram without borders\n * - Code view shows the source code in a code block style\n */\nexport default function Mermaid({ code }: MermaidComponentProps) {\n const [mounted, setMounted] = useState(false);\n const [renderState, setRenderState] = useState<RenderState>({ status: 'loading' });\n const [viewMode, setViewMode] = useState<ViewMode>('diagram');\n const { theme, systemTheme } = useTheme();\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n const renderDiagram = useCallback(async () => {\n const currentTheme = theme === 'system' ? systemTheme : theme;\n const isDark = currentTheme === 'dark';\n\n try {\n const result = await renderWithBeautifulMermaid(code, isDark);\n if (result) {\n setRenderState({ status: 'success', svg: result });\n return;\n }\n } catch {\n // Fall through to iframe fallback\n }\n\n const result = await renderWithIframe(code, isDark);\n if (result.success) {\n setRenderState({ status: 'success', svg: result.svg });\n } else {\n setRenderState({ status: 'error', message: result.error });\n }\n }, [code, theme, systemTheme]);\n\n useEffect(() => {\n if (!mounted) {\n return;\n }\n renderDiagram();\n }, [mounted, renderDiagram]);\n\n const toggleViewMode = useCallback(() => {\n setViewMode((prev) => (prev === 'diagram' ? 'code' : 'diagram'));\n }, []);\n\n if (!mounted || renderState.status === 'loading') {\n return LoadingFallback;\n }\n\n const hasError = renderState.status === 'error';\n const showDiagram = viewMode === 'diagram' && !hasError;\n\n if (showDiagram) {\n return (\n <div className=\"mermaid-block mermaid-diagram-view\">\n <div className=\"mermaid-diagram\" dangerouslySetInnerHTML={{ __html: renderState.svg }} />\n <button\n type=\"button\"\n onClick={toggleViewMode}\n className=\"mermaid-toggle-btn\"\n title=\"Show code\"\n aria-label=\"Show code\"\n >\n Code\n </button>\n </div>\n );\n }\n\n const toggleButton = (\n <button\n type=\"button\"\n onClick={toggleViewMode}\n className=\"mermaid-toggle-btn\"\n title=\"Show diagram\"\n disabled={hasError}\n >\n Diagram\n </button>\n );\n\n return (\n <div className={`code-block mermaid-block mermaid-code-view ${hasError ? 'has-error' : ''}`}>\n <CodeBlockHeader icon={<CodeBlockIcon language=\"mermaid\" />} code={code} actions={toggleButton} />\n <div className=\"mermaid-code\">\n {hasError ? (\n <div className=\"mermaid-error-message\">\n <strong>Syntax Error</strong>\n <span>{renderState.message}</span>\n </div>\n ) : null}\n <pre>\n <code>{code}</code>\n </pre>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["React","result","CodeBlockHeader","CodeBlockIcon"]}
@@ -1,5 +1,6 @@
1
1
  export { default as Mermaid, default } from './mermaid.mjs';
2
- export { getErrorMessage, hasValidSvgDimensions, normalizeCode } from './mermaid-utils.mjs';
3
- export { MermaidRenderResult, renderWithBeautifulMermaid, renderWithMermaidFallback, withSafeJsonStringify } from './mermaid-renderer.mjs';
2
+ export { hasValidSvgDimensions, normalizeCode } from './mermaid-utils.mjs';
3
+ export { MermaidRenderResult, renderWithBeautifulMermaid } from './mermaid-renderer.mjs';
4
+ export { destroyIframe, renderWithIframe } from './mermaid-iframe-renderer.mjs';
4
5
  import 'react';
5
6
  import '@hackersheet/react-document-content';
@@ -1,15 +1,15 @@
1
1
  import { default as default2 } from "./mermaid.mjs";
2
2
  import { default as default3 } from "./mermaid.mjs";
3
- import { getErrorMessage, hasValidSvgDimensions, normalizeCode } from "./mermaid-utils.mjs";
4
- import { renderWithBeautifulMermaid, renderWithMermaidFallback, withSafeJsonStringify } from "./mermaid-renderer.mjs";
3
+ import { hasValidSvgDimensions, normalizeCode } from "./mermaid-utils.mjs";
4
+ import { renderWithBeautifulMermaid } from "./mermaid-renderer.mjs";
5
+ import { destroyIframe, renderWithIframe } from "./mermaid-iframe-renderer.mjs";
5
6
  export {
6
7
  default3 as Mermaid,
7
8
  default2 as default,
8
- getErrorMessage,
9
+ destroyIframe,
9
10
  hasValidSvgDimensions,
10
11
  normalizeCode,
11
12
  renderWithBeautifulMermaid,
12
- renderWithMermaidFallback,
13
- withSafeJsonStringify
13
+ renderWithIframe
14
14
  };
15
15
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/mermaid/index.ts"],"sourcesContent":["/**\n * Mermaid diagram component and utilities.\n * @module\n */\n\nexport { default } from \"./mermaid.mjs\";\nexport { default as Mermaid } from \"./mermaid.mjs\";\nexport { getErrorMessage, hasValidSvgDimensions, normalizeCode } from \"./mermaid-utils.mjs\";\nexport { renderWithBeautifulMermaid, renderWithMermaidFallback, withSafeJsonStringify } from \"./mermaid-renderer.mjs\";\nexport type { MermaidRenderResult } from \"./mermaid-renderer.mjs\";\n"],"mappings":"AAKA,SAAS,WAAAA,gBAAe;AACxB,SAAoB,WAAXA,gBAA0B;AACnC,SAAS,iBAAiB,uBAAuB,qBAAqB;AACtE,SAAS,4BAA4B,2BAA2B,6BAA6B;","names":["default"]}
1
+ {"version":3,"sources":["../../../../src/components/mermaid/index.ts"],"sourcesContent":["/**\n * Mermaid diagram component and utilities.\n * @module\n */\n\nexport { default } from \"./mermaid.mjs\";\nexport { default as Mermaid } from \"./mermaid.mjs\";\nexport { hasValidSvgDimensions, normalizeCode } from \"./mermaid-utils.mjs\";\nexport { renderWithBeautifulMermaid } from \"./mermaid-renderer.mjs\";\nexport { destroyIframe, renderWithIframe } from \"./mermaid-iframe-renderer.mjs\";\nexport type { MermaidRenderResult } from \"./mermaid-renderer.mjs\";\n"],"mappings":"AAKA,SAAS,WAAAA,gBAAe;AACxB,SAAoB,WAAXA,gBAA0B;AACnC,SAAS,uBAAuB,qBAAqB;AACrD,SAAS,kCAAkC;AAC3C,SAAS,eAAe,wBAAwB;","names":["default"]}
@@ -0,0 +1,33 @@
1
+ import { MermaidRenderResult } from './mermaid-renderer.mjs';
2
+
3
+ /**
4
+ * Sandboxed iframe-based mermaid renderer.
5
+ * Isolates mermaid rendering from cross-origin iframes on the page.
6
+ * @module
7
+ */
8
+
9
+ /**
10
+ * Render mermaid diagram using a sandboxed iframe.
11
+ * This isolates the rendering from any cross-origin content on the page.
12
+ *
13
+ * @param code - Mermaid diagram code
14
+ * @param isDark - Whether to use dark theme
15
+ * @param timeout - Timeout in milliseconds (default: 10000)
16
+ * @returns Promise resolving to render result
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const result = await renderWithIframe('graph TD; A-->B;', false);
21
+ * if (result.success) {
22
+ * console.log(result.svg);
23
+ * }
24
+ * ```
25
+ */
26
+ declare function renderWithIframe(code: string, isDark: boolean, timeout?: number): Promise<MermaidRenderResult>;
27
+ /**
28
+ * Clean up the iframe instance.
29
+ * Call this when the mermaid component is no longer needed.
30
+ */
31
+ declare function destroyIframe(): void;
32
+
33
+ export { destroyIframe, renderWithIframe };