From ec23dfa48b3f6ce12414f7face94b69cbd0d8ddb Mon Sep 17 00:00:00 2001 From: Felipe Lima Date: Thu, 12 Feb 2026 19:02:13 -0500 Subject: [PATCH] fix intermittent mermaid rendering failures Remove custom Mermaid swizzle that had race conditions (startOnLoad + contentLoaded in empty-dep useEffect). The official @docusaurus/theme-mermaid component handles rendering correctly via mermaid.render() with proper React lifecycle management. - Delete src/theme/Mermaid.tsx and src/components/mermaid.tsx - Convert JSX to ```mermaid code fences - Remove Mermaid lazy wrapper from MDXComponents - Update CSS selectors from .mermaid to .docusaurus-mermaid-container - Move font config to mermaid themeVariables so node sizes are calculated correctly during rendering --- docs/tagocore/plugins/create/lifecycle.md | 11 +-- .../create/sdk/module-payload-encoder.md | 8 +- docs/tagocore/plugins/create/sdk/module.md | 45 ++++++++++- docusaurus.config.ts | 2 + src/components/mermaid.tsx | 15 ---- src/css/custom.css | 74 +++++++++---------- src/theme/MDXComponents.tsx | 11 --- src/theme/Mermaid.tsx | 16 ---- 8 files changed, 86 insertions(+), 96 deletions(-) delete mode 100644 src/components/mermaid.tsx delete mode 100644 src/theme/Mermaid.tsx diff --git a/docs/tagocore/plugins/create/lifecycle.md b/docs/tagocore/plugins/create/lifecycle.md index 545b8d63..4652fe74 100644 --- a/docs/tagocore/plugins/create/lifecycle.md +++ b/docs/tagocore/plugins/create/lifecycle.md @@ -4,8 +4,6 @@ title: Lifecycle slug: /tagocore/plugin/create/lifecycle --- -import Mermaid from '@theme/Mermaid'; - # Lifecycle It's important to understand how Plugins run and how TagoCore manages Plugins. @@ -19,7 +17,7 @@ which means your **Plugin should have at least one module**. ## How Plugins are Started ->Plugin Env: Start Plugin Env->>Module1: onLoad @@ -27,7 +25,7 @@ sequenceDiagram Module2-->>Plugin Env: Success Module1-->>Plugin Env: Success Plugin Env-->>TagoCore: Success -`}/> +``` After TagoCore is started, it will iterate through each Plugin environment and send a message for it to load. Once that message is received, the Plugin environment will make a call to the `onLoad` function of each module. @@ -45,7 +43,7 @@ will be terminated. ## How Plugins are Stopped ->Plugin Env: Stop Plugin Env->>Module1: onDestroy @@ -53,8 +51,7 @@ sequenceDiagram Module2-->>Plugin Env: Success Module1-->>Plugin Env: Success Plugin Env-->>TagoCore: Success -`}/> - +``` The Stop flow for each Plugin environment is very similar to the Start flow. diff --git a/docs/tagocore/plugins/create/sdk/module-payload-encoder.md b/docs/tagocore/plugins/create/sdk/module-payload-encoder.md index d15ba2c1..759bd5bb 100644 --- a/docs/tagocore/plugins/create/sdk/module-payload-encoder.md +++ b/docs/tagocore/plugins/create/sdk/module-payload-encoder.md @@ -4,20 +4,18 @@ title: Module - Payload Encoder slug: /tagocore/plugins/create/encoder --- -import Mermaid from '@theme/Mermaid'; - # Payload Encoder Module This Module allows you to encode data before it reaches a device. - B[Payload Encoder] B[Payload Encoder] --> C[Payload Parser] C[Payload Parser] --> D[Data added to Device] - + classDef default fill:#333,stroke:#333,stroke-width:2px,color:#fff,font-weight:bold -`}/> +``` Once a Device sends data, the data is immediately forwarded to the first `PayloadEncoderModule` found. The Payload Encoder order is defined by the `encoder_stack` field of the Device. diff --git a/docs/tagocore/plugins/create/sdk/module.md b/docs/tagocore/plugins/create/sdk/module.md index fdb74e79..615abb30 100644 --- a/docs/tagocore/plugins/create/sdk/module.md +++ b/docs/tagocore/plugins/create/sdk/module.md @@ -4,8 +4,6 @@ title: Module slug: /tagocore/plugins/create/module --- -import Mermaid from '@theme/Mermaid'; - # Module Modules are JavaScript classes that allow you to add a specific functionality for your Plugin. @@ -41,11 +39,50 @@ new ServiceModule(setup); This Module allows you to encode data before it reaches a device. Learn more about it [here](/docs/tagocore/plugins/create/encoder). - B[Payload Encoder] B[Payload Encoder] --> C[Payload Parser] C[Payload Parser] --> D[Data added to Device] classDef default fill:#333,stroke:#333,stroke-width:2px,color:#fff,font-weight:bold -`}/> +``` + +## Service Module + +This Module allows you to create a service that will run in your Plugin. Learn more about it [here](/docs/tagocore/plugins/create/service). + +## Action Trigger Module + +This Module allows you to create a new trigger for Actions. Learn more about it [here](/docs/tagocore/plugins/create/action-trigger). + +## The `configs` property + +If your Module has a `configs` property in the `setup` object, you can access the current values of those configurations +using the `.configs` getter. + +The `.configs` getter retrieves the latest configuration values from TagoCore, so you should have the latest values +every time. Below is a sample code of how to use it: + +```js +const { ServiceModule } = require("@tago-io/tcore-sdk"); + +const service = new ServiceModule({ + id: "my-service", + name: "Service", + configs: [ + { + name: "Token", + field: "token", + type: "string", + required: true, + }, + ], +}); + +service.onLoad = async () => { + // Retrieves the latest config values from TagoCore + const configs = await service.configs; + const token = configs.token; +}; +``` diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 37c14957..b5b5fecf 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -230,6 +230,8 @@ const config: Config = { edgeLabelBackground: "transparent", clusterBkg: "transparent", clusterBorder: "#2a2a2a", + fontFamily: "Menlo, Consolas, 'Liberation Mono', Courier, monospace", + fontSize: "16px", }, }, }, diff --git a/src/components/mermaid.tsx b/src/components/mermaid.tsx deleted file mode 100644 index 049f5642..00000000 --- a/src/components/mermaid.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import mermaid from "mermaid"; -import { useEffect } from "react"; - -mermaid.initialize({ - startOnLoad: true, -}); - -const Mermaid = ({ chart }) => { - useEffect(() => { - mermaid.contentLoaded(); - }, []); - return
{chart}
; -}; - -export default Mermaid; diff --git a/src/css/custom.css b/src/css/custom.css index cd7c8112..47326963 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -1054,51 +1054,49 @@ html[data-theme="dark"] .youtube-container { vertical-align: bottom; } -.mermaid { +.docusaurus-mermaid-container { display: flex; align-items: center; justify-content: center; margin-bottom: var(--ifm-paragraph-margin-bottom); + overflow-x: auto; } /* keep rounded rectangles, selector placed before more specific rules to avoid specificity issues */ -.mermaid rect { +.docusaurus-mermaid-container rect { ry: 3; rx: 3; } -.mermaid rect.actor, -.mermaid .node rect { +.docusaurus-mermaid-container rect.actor, +.docusaurus-mermaid-container .node rect { stroke: none !important; fill: #17888d !important; } -.mermaid .actor tspan { +.docusaurus-mermaid-container .actor tspan { fill: white !important; font-weight: bold; } -.mermaid line:not([class^="messageLin"]) { +.docusaurus-mermaid-container line:not([class^="messageLin"]) { stroke: rgba(0, 0, 0, 0.2) !important; } -html[data-theme="dark"] .mermaid line:not([class^="messageLin"]) { +html[data-theme="dark"] .docusaurus-mermaid-container line:not([class^="messageLin"]) { stroke: rgba(255, 255, 255, 0.2) !important; } -html[data-theme="dark"] .mermaid [class^="messageLin"] { +html[data-theme="dark"] .docusaurus-mermaid-container [class^="messageLin"] { stroke: rgba(255, 255, 255, 1) !important; } -.mermaid .messageText { +.docusaurus-mermaid-container .messageText { stroke: none !important; } -html[data-theme="dark"] .mermaid .messageText { +html[data-theme="dark"] .docusaurus-mermaid-container .messageText { stroke: rgba(255, 255, 255, 1) !important; } -.mermaid * { - font-family: - Menlo, Consolas, "Liberation Mono", Courier, monospace !important; - font-size: 16px; -} -.mermaid .node div { +/* Font family and size are configured in docusaurus.config.ts mermaid themeVariables + so mermaid calculates node sizes correctly during rendering */ +.docusaurus-mermaid-container .node div { color: white; } /* Allow wide diagrams to scroll instead of shrinking */ -.mermaid svg { +.docusaurus-mermaid-container svg { max-width: none; min-width: fit-content; } @@ -1194,19 +1192,19 @@ html[data-theme="dark"] .alert--danger [class*="admonitionHeading"] { ============================================================ */ /* All node labels white — teal backgrounds need white text */ -.mermaid .nodeLabel { +.docusaurus-mermaid-container .nodeLabel { color: #fff !important; fill: #fff !important; } /* Light mode only: stadium/path nodes have light backgrounds — reset to dark text */ -html[data-theme="light"] .mermaid .node:has(path) .nodeLabel { +html[data-theme="light"] .docusaurus-mermaid-container .node:has(path) .nodeLabel { color: #333 !important; fill: #333 !important; } /* Block-beta text — always white on teal blocks */ -.mermaid .block .nodeLabel { +.docusaurus-mermaid-container .block .nodeLabel { color: #fff !important; } @@ -1215,58 +1213,58 @@ html[data-theme="light"] .mermaid .node:has(path) .nodeLabel { ============================================================ */ /* Default SVG text fill → light for dark backgrounds */ -html[data-theme="dark"] .mermaid svg { +html[data-theme="dark"] .docusaurus-mermaid-container svg { color: #e0e0e0; } -html[data-theme="dark"] .mermaid svg[id^="mermaid"] { +html[data-theme="dark"] .docusaurus-mermaid-container svg[id^="mermaid"] { fill: #e0e0e0 !important; } /* Node labels — white text */ -html[data-theme="dark"] .mermaid .nodeLabel, -html[data-theme="dark"] .mermaid .node .label, -html[data-theme="dark"] .mermaid .label text, -html[data-theme="dark"] .mermaid .label span { +html[data-theme="dark"] .docusaurus-mermaid-container .nodeLabel, +html[data-theme="dark"] .docusaurus-mermaid-container .node .label, +html[data-theme="dark"] .docusaurus-mermaid-container .label text, +html[data-theme="dark"] .docusaurus-mermaid-container .label span { color: #fff !important; fill: #fff !important; } /* Edge labels (e.g. "TagoTiP", "TagoTiP/S") */ -html[data-theme="dark"] .mermaid .labelBkg { +html[data-theme="dark"] .docusaurus-mermaid-container .labelBkg { background: #1e1e1e !important; outline: 1px solid rgba(44, 177, 188, 0.35); border-radius: 3px !important; } -html[data-theme="dark"] .mermaid .labelBkg p, -html[data-theme="dark"] .mermaid .edgeLabel span, -html[data-theme="dark"] .mermaid .edgeLabel span p { +html[data-theme="dark"] .docusaurus-mermaid-container .labelBkg p, +html[data-theme="dark"] .docusaurus-mermaid-container .edgeLabel span, +html[data-theme="dark"] .docusaurus-mermaid-container .edgeLabel span p { color: #fff !important; background: transparent !important; } /* Edge lines/paths — visible on dark backgrounds */ -html[data-theme="dark"] .mermaid .flowchart-link, -html[data-theme="dark"] .mermaid .edge-pattern-solid, -html[data-theme="dark"] .mermaid .edgePath path { +html[data-theme="dark"] .docusaurus-mermaid-container .flowchart-link, +html[data-theme="dark"] .docusaurus-mermaid-container .edge-pattern-solid, +html[data-theme="dark"] .docusaurus-mermaid-container .edgePath path { stroke: #8a8a8a !important; } /* Arrowheads */ -html[data-theme="dark"] .mermaid marker path { +html[data-theme="dark"] .docusaurus-mermaid-container marker path { fill: #8a8a8a !important; stroke: #8a8a8a !important; } /* Secondary/tertiary node shapes (stadium, circle, etc.) — darken light fills */ -html[data-theme="dark"] .mermaid .node path, -html[data-theme="dark"] .mermaid .node circle { +html[data-theme="dark"] .docusaurus-mermaid-container .node path, +html[data-theme="dark"] .docusaurus-mermaid-container .node circle { fill: #1a5c60 !important; stroke: #2cb1bc !important; } /* Block-beta text inside blocks */ -html[data-theme="dark"] .mermaid .block .nodeLabel, -html[data-theme="dark"] .mermaid foreignObject div { +html[data-theme="dark"] .docusaurus-mermaid-container .block .nodeLabel, +html[data-theme="dark"] .docusaurus-mermaid-container foreignObject div { color: #fff !important; } diff --git a/src/theme/MDXComponents.tsx b/src/theme/MDXComponents.tsx index 69d6214f..b6650584 100644 --- a/src/theme/MDXComponents.tsx +++ b/src/theme/MDXComponents.tsx @@ -2,20 +2,9 @@ import YouTube from "@site/src/components/youtube"; import DocCardList from "@theme/DocCardList"; import MDXComponents from "@theme-original/MDXComponents"; -import type React from "react"; -import { lazy, Suspense } from "react"; - -// Lazily load Mermaid to avoid shipping it on pages that don't use it -const MermaidLazy = lazy(async () => await import("@theme/Mermaid")); -const Mermaid = (props: React.ComponentProps) => ( - - - -); export default { ...MDXComponents, YouTube, - Mermaid, DocCardList, }; diff --git a/src/theme/Mermaid.tsx b/src/theme/Mermaid.tsx deleted file mode 100644 index 555358cd..00000000 --- a/src/theme/Mermaid.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import mermaid from "mermaid"; -import { useEffect } from "react"; - -mermaid.initialize({ - startOnLoad: true, -}); - -const Mermaid = ({ chart, value }: { chart?: string; value?: string }) => { - const code = value || chart; - useEffect(() => { - mermaid.contentLoaded(); - }, []); - return
{code}
; -}; - -export default Mermaid;