@dxos/plugin-mermaid 0.9.1-staging.ee54ba693a → 0.11.0

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 (34) hide show
  1. package/PLUGIN.mdl +5 -5
  2. package/dist/lib/MermaidPlugin.mjs +21 -0
  3. package/dist/lib/MermaidPlugin.mjs.map +1 -0
  4. package/dist/lib/capabilities.mjs +7 -0
  5. package/dist/lib/capabilities.mjs.map +1 -0
  6. package/dist/lib/chunk-markdown-extension.mjs +158 -0
  7. package/dist/lib/chunk-markdown-extension.mjs.map +1 -0
  8. package/dist/lib/{neutral/chunk-ZBARIEVA.mjs → chunk-meta.mjs} +19 -23
  9. package/dist/lib/chunk-meta.mjs.map +1 -0
  10. package/dist/lib/index.mjs +2 -0
  11. package/dist/lib/meta.mjs +2 -0
  12. package/dist/lib/plugin.mjs +8 -0
  13. package/dist/lib/plugin.mjs.map +1 -0
  14. package/dist/types/src/capabilities/markdown-extension.d.ts +1 -1
  15. package/dist/types/src/extensions/mermaid-extension.d.ts +6 -1
  16. package/dist/types/src/extensions/mermaid-extension.d.ts.map +1 -1
  17. package/dist/types/tsconfig.tsbuildinfo +1 -1
  18. package/dx.config.ts +1 -0
  19. package/package.json +24 -24
  20. package/src/extensions/mermaid-extension.ts +10 -5
  21. package/dist/lib/neutral/MermaidPlugin.mjs +0 -29
  22. package/dist/lib/neutral/MermaidPlugin.mjs.map +0 -7
  23. package/dist/lib/neutral/capabilities/index.mjs +0 -7
  24. package/dist/lib/neutral/capabilities/index.mjs.map +0 -7
  25. package/dist/lib/neutral/chunk-ZBARIEVA.mjs.map +0 -7
  26. package/dist/lib/neutral/index.mjs +0 -7
  27. package/dist/lib/neutral/index.mjs.map +0 -7
  28. package/dist/lib/neutral/markdown-extension-7YWEUNWO.mjs +0 -172
  29. package/dist/lib/neutral/markdown-extension-7YWEUNWO.mjs.map +0 -7
  30. package/dist/lib/neutral/meta.json +0 -1
  31. package/dist/lib/neutral/meta.mjs +0 -7
  32. package/dist/lib/neutral/meta.mjs.map +0 -7
  33. package/dist/lib/neutral/plugin.mjs +0 -11
  34. package/dist/lib/neutral/plugin.mjs.map +0 -7
package/PLUGIN.mdl CHANGED
@@ -14,11 +14,11 @@ Each extension is defined in the Appendix or resolved via its URI.
14
14
 
15
15
  | Term | URI |
16
16
  |-------------|-------------------------------|
17
- | `type` | `org.dxos.mdl.type@1.0` |
18
- | `feat` | `org.dxos.mdl.feat@1.0` |
19
- | `test` | `org.dxos.mdl.test@1.0` |
20
- | `component` | `org.dxos.mdl.component@1.0` |
21
- | `op` | `org.dxos.mdl.op@1.0` |
17
+ | `type` | `org.dxos.mdl.type@1.0` |
18
+ | `feat` | `org.dxos.mdl.feat@1.0` |
19
+ | `test` | `org.dxos.mdl.test@1.0` |
20
+ | `component` | `org.dxos.mdl.component@1.0` |
21
+ | `op` | `org.dxos.mdl.op@1.0` |
22
22
 
23
23
  ## Types
24
24
 
@@ -0,0 +1,21 @@
1
+ import { Plugin } from "@dxos/app-framework";
2
+ import { AppPlugin } from "@dxos/app-toolkit";
3
+ import { MarkdownEvents } from "@dxos/plugin-markdown";
4
+ import { MarkdownExtension } from "#capabilities";
5
+ import { meta } from "#meta";
6
+ //#endregion
7
+ //#region src/MermaidPlugin.tsx
8
+ var MermaidPlugin = Plugin.define(meta).pipe(Plugin.addModule({
9
+ id: "markdown",
10
+ activatesOn: MarkdownEvents.SetupExtensions,
11
+ activate: MarkdownExtension
12
+ }), AppPlugin.addPluginAssetModule({ asset: {
13
+ pluginId: meta.profile.key,
14
+ path: "PLUGIN.mdl",
15
+ content: "---\nid: org.dxos.plugin.mermaid\nname: MermaidPlugin\nversion: 0.1.0\n---\n\nA CodeMirror extension plugin for DXOS Composer that renders Mermaid diagram\ndefinitions as live SVG previews inside the markdown editor.\n\n## Extensions\n\nThe following extension dialects are used in this document.\nEach extension is defined in the Appendix or resolved via its URI.\n\n| Term | URI |\n|-------------|-------------------------------|\n| `type` | `org.dxos.mdl.type@1.0` |\n| `feat` | `org.dxos.mdl.feat@1.0` |\n| `test` | `org.dxos.mdl.test@1.0` |\n| `component` | `org.dxos.mdl.component@1.0` |\n| `op` | `org.dxos.mdl.op@1.0` |\n\n## Types\n\n```mdl\ntype DiagramKind\n literals: flowchart | sequenceDiagram | classDiagram | stateDiagram | erDiagram | gantt | pie | gitGraph | mindmap | timeline\n```\n\n```mdl\ntype DiagramTheme\n literals: default | neutral | dark | forest | base\n```\n\n```mdl\ntype RenderResult\n fields:\n svg: string # rendered SVG markup\n id: string # unique widget id used by the Mermaid API\n```\n\n```mdl\ntype RenderError\n fields:\n message: string # human-readable parse or render error text\n source: string # the Mermaid source that caused the error\n```\n\n## Components\n\n```mdl\ncomponent MermaidWidget\n desc: |\n An inline CodeMirror widget that replaces a ```mermaid fenced code block\n with its rendered SVG diagram. The source code block is hidden while the\n cursor is outside it; moving the cursor inside restores the raw text for\n editing.\n props:\n id: string # unique widget id (mermaid-<offset>)\n source: string # raw Mermaid diagram source\n label?: string # first token of source used as a diagram-type badge\n darkMode: boolean # mirrors the editor dark-theme facet\n state:\n svg?: string # last successfully rendered SVG\n error?: string # last render error message; shown in place of diagram\n layout: |\n ┌────────────────────────────────┐\n │ [rendered SVG diagram] │\n │ [label] │\n └────────────────────────────────┘\n (on error)\n ┌────────────────────────────────┐\n │ error text │\n └────────────────────────────────┘\n```\n\n## Operations\n\n```mdl\nop renderDiagram\n desc: Parses a Mermaid source string and renders it to SVG via the Mermaid JS API.\n input:\n id: string # unique element id required by the Mermaid render API\n source: string # raw Mermaid diagram definition\n darkMode?: boolean # sets darkMode / theme on the Mermaid config\n output: RenderResult\n errors:\n ParseError: source does not conform to Mermaid syntax\n RenderError: SVG generation failed after successful parse\n```\n\n## Features\n\n```mdl\nfeat F-1: Diagram Rendering\n\n req F-1.1:\n when: a fenced code block with language tag `mermaid` is present in the document\n then: the block is replaced by a rendered SVG diagram widget\n\n req F-1.2:\n when: the cursor moves inside the fenced code block\n then: raw source text is revealed for editing and the widget is hidden\n\n req F-1.3:\n when: the cursor moves outside the fenced code block\n then: the widget is restored and the raw text is hidden\n\n req F-1.4:\n when: the editor is in read-only mode\n then: widgets are always shown regardless of cursor position\n```\n\n```mdl\nfeat F-2: Error Handling\n\n req F-2.1:\n when: Mermaid fails to parse the source\n then: an inline error message is shown in place of the diagram\n\n req F-2.2:\n when: a previously failing source is corrected\n then: the widget re-renders and displays the valid diagram\n```\n\n```mdl\nfeat F-3: Theme Integration\n\n req F-3.1:\n when: the editor's dark-theme facet is true\n then: the Mermaid diagram is initialized with darkMode enabled\n\n req F-3.2: The rendered widget uses the editor's group-surface background token.\n```\n\n```mdl\nfeat F-4: Markdown Editor Integration\n\n req F-4.1:\n when: the MermaidPlugin is loaded\n then: it registers the mermaid CodeMirror extension via MarkdownCapabilities.ExtensionProvider\n\n req F-4.2: The plugin activates on MarkdownEvents.SetupExtensions.\n```\n\n## Acceptance\n\n```mdl\ntest T-1: Valid flowchart renders\n given: a document containing a ```mermaid fenced block with a valid flowchart definition\n then:\n - the raw code block lines are hidden\n - an SVG widget is injected immediately after the block\n - no error text is visible\n```\n\n```mdl\ntest T-2: Cursor-in/out toggle\n given: a rendered Mermaid widget is visible\n when: the cursor moves inside the fenced code block\n then:\n - the cm-mermaid-hidden class is removed from the block lines\n - the widget is no longer rendered in the viewport\n\n when: the cursor moves back outside the block\n then:\n - block lines are hidden again\n - widget is rendered again\n```\n\n```mdl\ntest T-3: Invalid syntax shows error\n given: a document containing a ```mermaid block with invalid syntax\n then:\n - no SVG is rendered\n - an inline error message is shown with class cm-mermaid-error\n```\n\n```mdl\ntest T-4: Read-only always shows widget\n given: the editor is in read-only mode\n when: any cursor position\n then: widgets are rendered and raw source lines remain hidden\n```\n\n```mdl\ntest T-5: Plugin activates on markdown event\n given: MermaidPlugin and ProcessManagerPlugin are loaded\n when: MarkdownEvents.SetupExtensions fires\n then: the markdown module is in the active module list\n```\n\n---\n\n## Appendix: Extension Definitions\n\nExtension block types used in this document are defined below using\nthe core `ext` primitive — the only construct the base language provides.\n\n```mdl\next type\n uri: org.dxos.mdl.type@1.0\n desc: A named data structure with typed fields and optional literals.\n fields:\n desc?: Prose\n fields?: FieldMap # name[?]: TypeExpr (# inline comment)\n literals?: UnionList # a | b | c\n extends?: TypeRef[]\n```\n\n```mdl\next feat\n uri: org.dxos.mdl.feat@1.0\n desc: A named feature grouping one or more requirements.\n fields:\n desc?: Prose\n req: RequirementList\n nesting: self\n```\n\n```mdl\next test\n uri: org.dxos.mdl.test@1.0\n desc: An acceptance scenario expressed as given / when / then steps.\n fields:\n given?: Step | Step[]\n when?: Step | Step[]\n then: Step | Step[]\n tags?: TagList\n```\n\n```mdl\next component\n uri: org.dxos.mdl.component@1.0\n desc: A UI component with props, internal state, slots, actions, and events.\n fields:\n desc?: Prose\n props?: FieldMap\n state?: FieldMap\n slots?: FieldMap\n actions?: ActionMap\n emits?: EventMap\n layout?: CodeBlock\n```\n\n```mdl\next op\n uri: org.dxos.mdl.op@1.0\n desc: |\n A named operation with typed inputs, outputs, and declared errors.\n Pure ops have no effects or requires. Effectful ops declare both.\n fields:\n desc?: Prose\n input?: FieldMap\n output?: TypeExpr\n errors?: ErrorMap\n effects?: EffectList\n requires?: ServiceList\n note?: Prose\n```\n",
16
+ mimeType: "application/x-mdl"
17
+ } }), Plugin.make);
18
+ //#endregion
19
+ export { MermaidPlugin, MermaidPlugin as default };
20
+
21
+ //# sourceMappingURL=MermaidPlugin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MermaidPlugin.mjs","names":[],"sources":["../../src/MermaidPlugin.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\nimport { AppPlugin } from '@dxos/app-toolkit';\nimport { MarkdownEvents } from '@dxos/plugin-markdown';\n\nimport { MarkdownExtension } from '#capabilities';\nimport { meta } from '#meta';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../PLUGIN.mdl?raw';\n\nexport const MermaidPlugin = Plugin.define(meta).pipe(\n Plugin.addModule({\n id: 'markdown',\n activatesOn: MarkdownEvents.SetupExtensions,\n activate: MarkdownExtension,\n }),\n AppPlugin.addPluginAssetModule({\n asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },\n }),\n Plugin.make,\n);\n\nexport default MermaidPlugin;\n"],"mappings":";;;;;;;AAcA,IAAa,gBAAgB,OAAO,OAAO,IAAI,CAAC,CAAC,KAC/C,OAAO,UAAU;CACf,IAAI;CACJ,aAAa,eAAe;CAC5B,UAAU;AACZ,CAAC,GACD,UAAU,qBAAqB,EAC7B,OAAO;CAAE,UAAU,KAAK,QAAQ;CAAK,MAAM;CAAc,SAAS;CAAY,UAAU;AAAoB,EAC9G,CAAC,GACD,OAAO,IACT"}
@@ -0,0 +1,7 @@
1
+ import { Capability } from "@dxos/app-framework";
2
+ //#region src/capabilities/index.ts
3
+ var MarkdownExtension = Capability.lazy("MarkdownExtension", () => import("./chunk-markdown-extension.mjs"));
4
+ //#endregion
5
+ export { MarkdownExtension };
6
+
7
+ //# sourceMappingURL=capabilities.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Capability } from '@dxos/app-framework';\n\nexport const MarkdownExtension = Capability.lazy('MarkdownExtension', () => import('./markdown-extension'));\n"],"mappings":";;AAMA,IAAa,oBAAoB,WAAW,KAAK,2BAA2B,OAAO,iCAAuB"}
@@ -0,0 +1,158 @@
1
+ import { Capability } from "@dxos/app-framework";
2
+ import * as Effect from "effect/Effect";
3
+ import { MarkdownCapabilities } from "@dxos/plugin-markdown/types";
4
+ import { syntaxTree } from "@codemirror/language";
5
+ import { Decoration, EditorView, ViewPlugin, WidgetType } from "@codemirror/view";
6
+ import Mermaid from "mermaid";
7
+ //#region src/extensions/mermaid-extension.ts
8
+ /**
9
+ * Extension to create mermaid diagrams.
10
+ *
11
+ * The fenced source is highlighted while the cursor is inside the block (where this extension
12
+ * suppresses the widget). That highlighting comes from `mermaidLanguageDescription`, registered in
13
+ * `@dxos/ui-editor`'s markdown bundle rather than here: `codeLanguages` is read once when the
14
+ * markdown parser is built, so an extension contributed afterwards cannot add a fenced-code language.
15
+ */
16
+ var mermaid = (_ = {}) => {
17
+ return [ViewPlugin.fromClass(class {
18
+ decorations;
19
+ constructor(view) {
20
+ this.decorations = this.buildDecorations(view);
21
+ }
22
+ update(update) {
23
+ if (update.docChanged || update.viewportChanged || update.selectionSet || update.focusChanged) this.decorations = this.buildDecorations(update.view);
24
+ }
25
+ buildDecorations(view) {
26
+ const decorations = [];
27
+ syntaxTree(view.state).iterate({ enter: (node) => {
28
+ if (node.name === "FencedCode") {
29
+ const cursor = view.state.selection.main.head;
30
+ if (view.state.readOnly || cursor < node.from - 1 || cursor > node.to + 1) {
31
+ const info = node.node.getChild("CodeInfo");
32
+ if (info) {
33
+ const type = view.state.sliceDoc(info.from, info.to);
34
+ const text = node.node.getChild("CodeText");
35
+ if (type === "mermaid" && text) {
36
+ const content = view.state.sliceDoc(text.from, text.to).trim();
37
+ const label = content.split(" ")[0];
38
+ const widget = new MermaidWidget(`mermaid-${node.from}`, content, label);
39
+ const endLine = view.state.doc.lineAt(node.to);
40
+ const nextLinePos = endLine.to + 1;
41
+ if (nextLinePos <= view.state.doc.length) decorations.push({
42
+ from: nextLinePos,
43
+ to: nextLinePos,
44
+ decoration: Decoration.widget({ widget })
45
+ });
46
+ else decorations.push({
47
+ from: endLine.to,
48
+ to: endLine.to,
49
+ decoration: Decoration.widget({
50
+ widget,
51
+ side: 1
52
+ })
53
+ });
54
+ const startLine = view.state.doc.lineAt(node.from);
55
+ for (let lineNum = startLine.number; lineNum <= endLine.number; lineNum++) {
56
+ const line = view.state.doc.line(lineNum);
57
+ decorations.push({
58
+ from: line.from,
59
+ to: line.from,
60
+ decoration: Decoration.line({ class: "cm-mermaid-hidden" })
61
+ });
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
67
+ } });
68
+ return Decoration.set(decorations.sort((a, b) => a.from - b.from || a.to - b.to).map((d) => d.decoration.range(d.from, d.to)));
69
+ }
70
+ }, { decorations: (v) => v.decorations }), EditorView.theme({
71
+ "& .cm-mermaid": {
72
+ position: "relative",
73
+ display: "inline-flex",
74
+ width: "100%",
75
+ maring: "4px 0",
76
+ padding: "16px",
77
+ justifyContent: "center",
78
+ backgroundColor: "var(--color-group-surface)",
79
+ borderRadius: "8px"
80
+ },
81
+ "& .cm-mermaid-label": {
82
+ position: "absolute",
83
+ right: "16px",
84
+ fontFamily: "unset",
85
+ color: "var(--color-subdued)"
86
+ },
87
+ "& .cm-mermaid-error": {
88
+ display: "inline-block",
89
+ color: "var(--color-error)"
90
+ },
91
+ "& .cm-mermaid-hidden": { display: "none !important" }
92
+ })];
93
+ };
94
+ var MermaidWidget = class extends WidgetType {
95
+ _id;
96
+ _source;
97
+ _label;
98
+ _svg;
99
+ _error;
100
+ constructor(_id, _source, _label) {
101
+ super();
102
+ this._id = _id;
103
+ this._source = _source;
104
+ this._label = _label;
105
+ }
106
+ eq(other) {
107
+ return this._source === other._source;
108
+ }
109
+ ignoreEvent(ev) {
110
+ return !/^mouse/.test(ev.type);
111
+ }
112
+ toDOM(view) {
113
+ const div = document.createElement("div");
114
+ div.className = "cm-mermaid";
115
+ setTimeout(async () => {
116
+ Mermaid.initialize({
117
+ darkMode: view.state.facet(EditorView.darkTheme),
118
+ theme: "neutral"
119
+ });
120
+ const svg = await this.render(div);
121
+ if (this._error) {
122
+ div.className = "cm-mermaid-error";
123
+ div.innerText = this._error;
124
+ } else {
125
+ div.className = "cm-mermaid";
126
+ div.innerHTML = svg;
127
+ if (this._label) {
128
+ const label = document.createElement("span");
129
+ label.innerText = this._label;
130
+ label.className = "cm-mermaid-label";
131
+ div.appendChild(label);
132
+ view.requestMeasure();
133
+ }
134
+ }
135
+ });
136
+ return div;
137
+ }
138
+ async render(_container) {
139
+ try {
140
+ if (await Mermaid.parse(this._source)) {
141
+ const result = await Mermaid.render(this._id, this._source);
142
+ this._error = void 0;
143
+ this._svg = result.svg;
144
+ return result.svg;
145
+ }
146
+ } catch (err) {
147
+ this._error = String(err);
148
+ this._svg = void 0;
149
+ }
150
+ }
151
+ };
152
+ //#endregion
153
+ //#region src/capabilities/markdown-extension.ts
154
+ var markdown_extension_default = Capability.makeModule(() => Effect.succeed(Capability.contributes(MarkdownCapabilities.ExtensionProvider, [mermaid])));
155
+ //#endregion
156
+ export { markdown_extension_default as default };
157
+
158
+ //# sourceMappingURL=chunk-markdown-extension.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-markdown-extension.mjs","names":[],"sources":["../../src/extensions/mermaid-extension.ts","../../src/capabilities/markdown-extension.ts"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { type Extension } from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate, WidgetType } from '@codemirror/view';\nimport Mermaid from 'mermaid';\n\nexport type MermaidOptions = {};\n\n/**\n * Extension to create mermaid diagrams.\n *\n * The fenced source is highlighted while the cursor is inside the block (where this extension\n * suppresses the widget). That highlighting comes from `mermaidLanguageDescription`, registered in\n * `@dxos/ui-editor`'s markdown bundle rather than here: `codeLanguages` is read once when the\n * markdown parser is built, so an extension contributed afterwards cannot add a fenced-code language.\n */\nexport const mermaid = (_: MermaidOptions = {}): Extension => {\n return [\n ViewPlugin.fromClass(\n class {\n decorations: DecorationSet;\n\n constructor(view: EditorView) {\n this.decorations = this.buildDecorations(view);\n }\n\n update(update: ViewUpdate) {\n // Always rebuild decorations when selection changes to handle arrow key navigation.\n if (update.docChanged || update.viewportChanged || update.selectionSet || update.focusChanged) {\n this.decorations = this.buildDecorations(update.view);\n }\n }\n\n buildDecorations(view: EditorView): DecorationSet {\n const decorations: Array<{ from: number; to: number; decoration: Decoration }> = [];\n\n syntaxTree(view.state).iterate({\n enter: (node) => {\n if (node.name === 'FencedCode') {\n const cursor = view.state.selection.main.head;\n // Show widget when cursor is outside the code block.\n // Add a buffer of 1 position before and after to handle edge cases.\n const showWidget = view.state.readOnly || cursor < node.from - 1 || cursor > node.to + 1;\n if (showWidget) {\n const info = node.node.getChild('CodeInfo');\n if (info) {\n const type = view.state.sliceDoc(info.from, info.to);\n const text = node.node.getChild('CodeText');\n if (type === 'mermaid' && text) {\n const content = view.state.sliceDoc(text.from, text.to).trim();\n const label = content.split(' ')[0];\n\n // Create widget.\n const widget = new MermaidWidget(`mermaid-${node.from}`, content, label);\n\n // Find the line after the code block to place the widget.\n const endLine = view.state.doc.lineAt(node.to);\n const nextLinePos = endLine.to + 1;\n\n // Add widget after the code block.\n if (nextLinePos <= view.state.doc.length) {\n decorations.push({\n from: nextLinePos,\n to: nextLinePos,\n decoration: Decoration.widget({\n widget,\n }),\n });\n } else {\n // Check if at the end of the document.\n decorations.push({\n from: endLine.to,\n to: endLine.to,\n decoration: Decoration.widget({\n widget,\n side: 1,\n }),\n });\n }\n\n // Hide each line of the code block.\n const startLine = view.state.doc.lineAt(node.from);\n for (let lineNum = startLine.number; lineNum <= endLine.number; lineNum++) {\n const line = view.state.doc.line(lineNum);\n decorations.push({\n from: line.from,\n to: line.from,\n decoration: Decoration.line({\n class: 'cm-mermaid-hidden',\n }),\n });\n }\n }\n }\n }\n }\n },\n });\n\n return Decoration.set(\n decorations.sort((a, b) => a.from - b.from || a.to - b.to).map((d) => d.decoration.range(d.from, d.to)),\n );\n }\n },\n {\n decorations: (v) => v.decorations,\n },\n ),\n EditorView.theme({\n '& .cm-mermaid': {\n position: 'relative',\n display: 'inline-flex',\n width: '100%',\n maring: '4px 0',\n padding: '16px',\n justifyContent: 'center',\n backgroundColor: 'var(--color-group-surface)',\n borderRadius: '8px',\n },\n '& .cm-mermaid-label': {\n position: 'absolute',\n right: '16px',\n fontFamily: 'unset',\n color: 'var(--color-subdued)',\n },\n '& .cm-mermaid-error': {\n display: 'inline-block',\n color: 'var(--color-error)',\n },\n '& .cm-mermaid-hidden': {\n display: 'none !important',\n },\n }),\n ];\n};\n\nclass MermaidWidget extends WidgetType {\n _svg: string | undefined;\n _error: string | undefined;\n\n // TODO(burdon): Mermaid API requires unique id.\n constructor(\n private readonly _id: string,\n private readonly _source: string,\n private readonly _label?: string,\n ) {\n super();\n }\n\n override eq(other: this) {\n return this._source === other._source;\n }\n\n override ignoreEvent(ev: Event) {\n return !/^mouse/.test(ev.type);\n }\n\n override toDOM(view: EditorView) {\n const div = document.createElement('div');\n div.className = 'cm-mermaid';\n\n setTimeout(async () => {\n // https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts\n Mermaid.initialize({\n darkMode: view.state.facet(EditorView.darkTheme),\n theme: 'neutral',\n // TODO(burdon): Styles.\n // NOTE: Must specify 'base' in order to override.\n // theme: 'base',\n // themeVariables: {\n // primaryColor: getToken('extend.colors.red.100'),\n // primaryBorderColor: getToken('extend.colors.neutral.200'),\n // },\n // https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagrams/flowchart/styles.ts\n // https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagrams/sequence/styles.js\n // https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagrams/state/styles.js\n // themeCSS: '.node rect { fill: red; }',\n });\n\n // TODO(burdon): Cache?\n const svg = await this.render(div);\n if (this._error) {\n div.className = 'cm-mermaid-error';\n div.innerText = this._error;\n } else {\n div.className = 'cm-mermaid';\n div.innerHTML = svg!;\n\n if (this._label) {\n const label = document.createElement('span');\n label.innerText = this._label;\n label.className = 'cm-mermaid-label';\n div.appendChild(label);\n view.requestMeasure();\n }\n }\n });\n\n return div;\n }\n\n async render(_container: Element): Promise<string | undefined> {\n try {\n // https://github.com/mermaid-js/mermaid\n const valid = await Mermaid.parse(this._source);\n if (valid) {\n const result = await Mermaid.render(this._id, this._source);\n this._error = undefined;\n this._svg = result.svg;\n return result.svg;\n }\n } catch (err: any) {\n this._error = String(err);\n this._svg = undefined;\n }\n }\n}\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { MarkdownCapabilities } from '@dxos/plugin-markdown/types';\n\nimport { mermaid } from '../extensions';\n\nexport default Capability.makeModule(() =>\n Effect.succeed(Capability.contributes(MarkdownCapabilities.ExtensionProvider, [mermaid])),\n);\n"],"mappings":"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"}
@@ -1,15 +1,12 @@
1
- // src/meta.ts
2
1
  import { Plugin } from "@dxos/app-framework";
3
-
4
- // dx.config.ts
5
2
  import { Config2 } from "@dxos/app-framework/config";
6
3
  import { trim } from "@dxos/util";
7
- var dx_config_default = Config2.make({
8
- plugin: {
9
- key: "org.dxos.plugin.mermaid",
10
- name: "Mermaid",
11
- author: "DXOS",
12
- description: trim`
4
+ //#region dx.config.ts
5
+ var dx_config_default = Config2.make({ plugin: {
6
+ key: "org.dxos.plugin.mermaid",
7
+ name: "Mermaid",
8
+ author: "DXOS",
9
+ description: trim`
13
10
  Generate diagrams from simple text-based definitions using Mermaid syntax.
14
11
  Create flowcharts, sequence diagrams, class diagrams, state diagrams, entity-relationship
15
12
  diagrams, Gantt charts, pie charts, Git graphs, mindmaps, and timelines — all from
@@ -27,19 +24,18 @@ var dx_config_default = Config2.make({
27
24
  Parse and render errors are shown inline in place of the diagram so that
28
25
  invalid syntax is immediately visible without disrupting the rest of the document.
29
26
  `,
30
- source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-mermaid",
31
- icon: {
32
- key: "ph--anchor-simple--regular",
33
- hue: "cyan"
34
- },
35
- spec: "PLUGIN.mdl"
36
- }
37
- });
38
-
39
- // src/meta.ts
27
+ source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-mermaid",
28
+ icon: {
29
+ key: "ph--anchor-simple--regular",
30
+ hue: "cyan"
31
+ },
32
+ spec: "PLUGIN.mdl",
33
+ tags: ["alpha"]
34
+ } });
35
+ //#endregion
36
+ //#region src/meta.ts
40
37
  var meta = Plugin.getMetaFromConfig(dx_config_default);
38
+ //#endregion
39
+ export { meta as t };
41
40
 
42
- export {
43
- meta
44
- };
45
- //# sourceMappingURL=chunk-ZBARIEVA.mjs.map
41
+ //# sourceMappingURL=chunk-meta.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-meta.mjs","names":[],"sources":["../../dx.config.ts","../../src/meta.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Config2 } from '@dxos/app-framework/config';\nimport { trim } from '@dxos/util';\n\nexport default Config2.make({\n plugin: {\n key: 'org.dxos.plugin.mermaid',\n name: 'Mermaid',\n author: 'DXOS',\n description: trim`\n Generate diagrams from simple text-based definitions using Mermaid syntax.\n Create flowcharts, sequence diagrams, class diagrams, state diagrams, entity-relationship\n diagrams, Gantt charts, pie charts, Git graphs, mindmaps, and timelines — all from\n plain-text source embedded directly in your documents.\n\n The plugin integrates with the markdown editor as a CodeMirror extension.\n Any fenced code block tagged with the \\`mermaid\\` language identifier is automatically\n detected and replaced with a live SVG preview rendered by the Mermaid JS library.\n The raw source is revealed for editing whenever the cursor moves inside the block,\n then the rendered diagram is restored when the cursor moves away, providing a seamless\n live-preview experience without leaving the editor.\n\n Diagram rendering adapts to the editor's current color scheme: dark-mode documents\n use Mermaid's dark theme while light-mode documents use the neutral theme.\n Parse and render errors are shown inline in place of the diagram so that\n invalid syntax is immediately visible without disrupting the rest of the document.\n `,\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-mermaid',\n icon: { key: 'ph--anchor-simple--regular', hue: 'cyan' },\n spec: 'PLUGIN.mdl',\n tags: ['alpha'],\n },\n});\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\n\nimport config from '../dx.config';\n\nexport const meta = Plugin.getMetaFromConfig(config);\n"],"mappings":";;;;AAOA,IAAA,oBAAe,QAAQ,KAAK,EAC1B,QAAQ;CACN,KAAK;CACL,MAAM;CACN,QAAQ;CACR,aAAa,IAAI;;;;;;;;;;;;;;;;;;CAkBjB,QAAQ;CACR,MAAM;EAAE,KAAK;EAA8B,KAAK;CAAO;CACvD,MAAM;CACN,MAAM,CAAC,OAAO;AAChB,EACF,CAAC;;;AC3BD,IAAa,OAAO,OAAO,kBAAkB,iBAAM"}
@@ -0,0 +1,2 @@
1
+ import { t as meta } from "./chunk-meta.mjs";
2
+ export { meta };
@@ -0,0 +1,2 @@
1
+ import { t as meta } from "./chunk-meta.mjs";
2
+ export { meta };
@@ -0,0 +1,8 @@
1
+ import { t as meta } from "./chunk-meta.mjs";
2
+ import { Plugin } from "@dxos/app-framework";
3
+ //#region src/plugin.ts
4
+ var MermaidPlugin = Plugin.lazy(meta, () => import("#plugin"));
5
+ //#endregion
6
+ export { MermaidPlugin };
7
+
8
+ //# sourceMappingURL=plugin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.mjs","names":[],"sources":["../../src/plugin.ts"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\n\nimport { meta } from './meta';\n\nexport const MermaidPlugin = Plugin.lazy(meta, () => import('#plugin'));\n"],"mappings":";;;AAQA,IAAa,gBAAgB,OAAO,KAAK,YAAY,OAAO,UAAU"}
@@ -1,5 +1,5 @@
1
1
  import * as Effect from 'effect/Effect';
2
2
  import { Capability } from '@dxos/app-framework';
3
- declare const _default: (props: void) => Effect.Effect<Capability.Any, never, never>;
3
+ declare const _default: (props: void) => Effect.Effect<Capability.Any, never, import("effect/Scope").Scope>;
4
4
  export default _default;
5
5
  //# sourceMappingURL=markdown-extension.d.ts.map
@@ -2,6 +2,11 @@ import { type Extension } from '@codemirror/state';
2
2
  export type MermaidOptions = {};
3
3
  /**
4
4
  * Extension to create mermaid diagrams.
5
+ *
6
+ * The fenced source is highlighted while the cursor is inside the block (where this extension
7
+ * suppresses the widget). That highlighting comes from `mermaidLanguageDescription`, registered in
8
+ * `@dxos/ui-editor`'s markdown bundle rather than here: `codeLanguages` is read once when the
9
+ * markdown parser is built, so an extension contributed afterwards cannot add a fenced-code language.
5
10
  */
6
- export declare const mermaid: (_options?: MermaidOptions) => Extension;
11
+ export declare const mermaid: (_?: MermaidOptions) => Extension;
7
12
  //# sourceMappingURL=mermaid-extension.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mermaid-extension.d.ts","sourceRoot":"","sources":["../../../../src/extensions/mermaid-extension.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAInD,MAAM,MAAM,cAAc,GAAG,EAAE,CAAC;AAEhC;;GAEG;AACH,eAAO,MAAM,OAAO,cAAc,cAAc,KAAQ,SAsHvD,CAAC"}
1
+ {"version":3,"file":"mermaid-extension.d.ts","sourceRoot":"","sources":["../../../../src/extensions/mermaid-extension.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAInD,MAAM,MAAM,cAAc,GAAG,EAAE,CAAC;AAEhC;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,OAAO,cAAc,KAAQ,SAsHhD,CAAC"}