feat(theme-mermaid): upgrade Mermaid to v10.4 - handle async rendering (#9305)

This commit is contained in:
Sébastien Lorber 2023-09-14 17:23:07 +02:00 committed by GitHub
parent dc7ae426ac
commit 58be496da2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 327 additions and 86 deletions

View file

@ -29,6 +29,7 @@
"website/src/data/users.tsx",
"website/src/data/tweets.tsx",
"website/docusaurus.config.localized.json",
"website/_dogfooding/_pages tests/diagrams.mdx",
"*.xyz",
"*.docx",
"*.gitignore",

View file

@ -107,5 +107,6 @@ export {
export {
ErrorBoundaryTryAgainButton,
ErrorBoundaryError,
ErrorBoundaryErrorMessageFallback,
ErrorCauseBoundary,
} from './utils/errorBoundaryUtils';

View file

@ -9,3 +9,8 @@
white-space: pre-wrap;
color: red;
}
.errorBoundaryFallback {
color: red;
padding: 0.55rem;
}

View file

@ -8,6 +8,7 @@
import React, {type ComponentProps} from 'react';
import Translate from '@docusaurus/Translate';
import {getErrorCausalChain} from '@docusaurus/utils-common';
import type {Props as ErrorProps} from '@theme/Error';
import styles from './errorBoundaryUtils.module.css';
export function ErrorBoundaryTryAgainButton(
@ -23,6 +24,20 @@ export function ErrorBoundaryTryAgainButton(
</button>
);
}
// A very simple reusable ErrorBoundary fallback component
export function ErrorBoundaryErrorMessageFallback({
error,
tryAgain,
}: ErrorProps): JSX.Element {
return (
<div className={styles.errorBoundaryFallback}>
<p>{error.message}</p>
<ErrorBoundaryTryAgainButton onClick={tryAgain} />
</div>
);
}
export function ErrorBoundaryError({error}: {error: Error}): JSX.Element {
const causalChain = getErrorCausalChain(error);
const fullMessage = causalChain.map((e) => e.message).join('\n\nCause:\n');

View file

@ -13,13 +13,12 @@ import Translate from '@docusaurus/Translate';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import BrowserOnly from '@docusaurus/BrowserOnly';
import {
ErrorBoundaryTryAgainButton,
ErrorBoundaryErrorMessageFallback,
usePrismTheme,
} from '@docusaurus/theme-common';
import ErrorBoundary from '@docusaurus/ErrorBoundary';
import type {Props} from '@theme/Playground';
import type {Props as ErrorProps} from '@theme/Error';
import type {ThemeConfig} from '@docusaurus/theme-live-codeblock';
import styles from './styles.module.css';
@ -34,15 +33,6 @@ function LivePreviewLoader() {
return <div>Loading...</div>;
}
function ErrorFallback({error, tryAgain}: ErrorProps): JSX.Element {
return (
<div className={styles.errorFallback}>
<p>{error.message}</p>
<ErrorBoundaryTryAgainButton onClick={tryAgain} />
</div>
);
}
function Preview() {
// No SSR for the live preview
// See https://github.com/facebook/docusaurus/issues/5747
@ -50,7 +40,10 @@ function Preview() {
<BrowserOnly fallback={<LivePreviewLoader />}>
{() => (
<>
<ErrorBoundary fallback={(params) => <ErrorFallback {...params} />}>
<ErrorBoundary
fallback={(params) => (
<ErrorBoundaryErrorMessageFallback {...params} />
)}>
<LivePreview />
</ErrorBoundary>
<LiveError />

View file

@ -38,7 +38,3 @@
padding: 1rem;
background-color: var(--ifm-pre-background);
}
.errorFallback {
padding: 0.55rem;
}

View file

@ -38,7 +38,7 @@
"@docusaurus/theme-common": "3.0.0-alpha.0",
"@docusaurus/types": "3.0.0-alpha.0",
"@docusaurus/utils-validation": "3.0.0-alpha.0",
"mermaid": "^9.4.3",
"mermaid": "^10.4.0",
"tslib": "^2.6.0"
},
"devDependencies": {

View file

@ -5,9 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/
import {useMemo} from 'react';
import {useState, useEffect, useMemo, useRef} from 'react';
import {useColorMode, useThemeConfig} from '@docusaurus/theme-common';
import mermaid, {type MermaidConfig} from 'mermaid';
import mermaid from 'mermaid';
import type {RenderResult, MermaidConfig} from 'mermaid';
import type {ThemeConfig} from '@docusaurus/theme-mermaid';
// Stable className to allow users to easily target with CSS
@ -30,48 +31,84 @@ export function useMermaidConfig(): MermaidConfig {
);
}
export function useMermaidSvg(
txt: string,
mermaidConfigParam?: MermaidConfig,
): string {
function useMermaidId(): string {
/*
Random client-only id, we don't care much but mermaid want an id so...
Note: Mermaid doesn't like values provided by Rect.useId() and throws
*/
// return useId(); // tried that, doesn't work ('#d:re:' is not a valid selector.)
return useRef(`mermaid-svg-${Math.round(Math.random() * 10000000)}`).current!;
}
async function renderMermaid({
id,
text,
config,
}: {
id: string;
text: string;
config: MermaidConfig;
}): Promise<RenderResult> {
/*
Mermaid API is really weird :s
It is a big mutable singleton with multiple config levels
Note: most recent API type definitions are missing
There are 2 kind of configs:
- siteConfig: some kind of global/protected shared config
you can only set with "initialize"
- config/currentConfig
the config the renderer will use
it is reset to siteConfig before each render
but it can be altered by the mermaid txt content itself through directives
To use a new mermaid config (on colorMode change for example) we should
update siteConfig, and it can only be done with initialize()
*/
mermaid.mermaidAPI.initialize(config);
try {
return await mermaid.render(id, text);
} catch (e) {
// Because Mermaid add a weird SVG/Message to the DOM on error
// https://github.com/mermaid-js/mermaid/issues/3205#issuecomment-1719620183
document.querySelector(`#d${id}`)?.remove();
throw e;
}
}
export function useMermaidRenderResult({
text,
config: providedConfig,
}: {
text: string;
config?: MermaidConfig;
}): RenderResult | null {
const [result, setResult] = useState<RenderResult | null>(null);
const id = useMermaidId();
/*
For flexibility, we allow the hook to receive a custom Mermaid config
The user could inject a modified version of the default config for example
*/
const defaultMermaidConfig = useMermaidConfig();
const mermaidConfig = mermaidConfigParam ?? defaultMermaidConfig;
const config = providedConfig ?? defaultMermaidConfig;
return useMemo(() => {
/*
Mermaid API is really weird :s
It is a big mutable singleton with multiple config levels
Note: most recent API type definitions are missing
useEffect(() => {
renderMermaid({id, text, config})
// TODO maybe try to use Suspense here and throw the promise?
// See also https://github.com/pmndrs/suspend-react
.then(setResult)
.catch((e) => {
// Funky way to trigger parent React error boundary
// See https://twitter.com/sebastienlorber/status/1628340871899893768
setResult(() => {
throw e;
});
});
}, [id, text, config]);
There are 2 kind of configs:
- siteConfig: some kind of global/protected shared config
you can only set with "initialize"
- config/currentConfig
the config the renderer will use
it is reset to siteConfig before each render
but it can be altered by the mermaid txt content itself through directives
To use a new mermaid config (on colorMode change for example) we should
update siteConfig, and it can only be done with initialize()
*/
mermaid.mermaidAPI.initialize(mermaidConfig);
/*
Random client-only id, we don't care much about it
But mermaid want an id so...
*/
const mermaidId = `mermaid-svg-${Math.round(Math.random() * 10000000)}`;
/*
Not even documented: mermaid.render returns the svg string
Using the documented form is un-necessary
*/
return mermaid.render(mermaidId, txt);
}, [txt, mermaidConfig]);
return result;
}

View file

@ -5,28 +5,54 @@
* LICENSE file in the root directory of this source tree.
*/
import React from 'react';
import BrowserOnly from '@docusaurus/BrowserOnly';
import React, {useEffect, useRef} from 'react';
import type {ReactNode} from 'react';
import ErrorBoundary from '@docusaurus/ErrorBoundary';
import {ErrorBoundaryErrorMessageFallback} from '@docusaurus/theme-common';
import {
MermaidContainerClassName,
useMermaidSvg,
useMermaidRenderResult,
} from '@docusaurus/theme-mermaid/client';
import type {Props} from '@theme/Mermaid';
import type {RenderResult} from 'mermaid';
import styles from './styles.module.css';
function MermaidDiagram({value}: Props): JSX.Element {
const svg = useMermaidSvg(value);
function MermaidRenderResult({
renderResult,
}: {
renderResult: RenderResult;
}): JSX.Element {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const div = ref.current!;
renderResult.bindFunctions?.(div);
}, [renderResult]);
return (
<div
ref={ref}
className={`${MermaidContainerClassName} ${styles.container}`}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{__html: svg}}
dangerouslySetInnerHTML={{__html: renderResult.svg}}
/>
);
}
export default function Mermaid(props: Props): JSX.Element {
return <BrowserOnly>{() => <MermaidDiagram {...props} />}</BrowserOnly>;
function MermaidRenderer({value}: Props): ReactNode {
const renderResult = useMermaidRenderResult({text: value});
if (renderResult === null) {
return null;
}
return <MermaidRenderResult renderResult={renderResult} />;
}
export default function Mermaid(props: Props): JSX.Element {
return (
<ErrorBoundary
fallback={(params) => <ErrorBoundaryErrorMessageFallback {...params} />}>
<MermaidRenderer {...props} />
</ErrorBoundary>
);
}

View file

@ -1,5 +1,25 @@
# Diagram Examples
## Invalid Diagrams
Those errors should not crash the whole page
### Invalid type
```mermaid
badType
participant Alice
participant Bob
```
### Invalid content
```mermaid
sequenceDiagram
badInstruction Alice
participant Bob
```
## Sequence Diagram
```mermaid
@ -66,6 +86,17 @@ flowchart TD
B ---->|No| E[End]
```
### With Markdown:
```mermaid
flowchart LR
markdown["`This **is** _Markdown_`"]
newLines["`Line1
Line 2
Line 3`"]
markdown --> newLines
```
## Class Diagram
```mermaid
@ -314,3 +345,86 @@ graph LR
</TabItem>
</Tabs>
````
## Mindmap
```mermaid
mindmap
root((conda-forge))
(Repos)
(Package building)
[*-feedstock]
[staged-recipes]
[cdt-builds]
[msys2-recipes]
(Maintenance)
[admin-requests]
[repodata-patches]
(Configuration)
[.github]
[.cirun]
[conda-forge-pinning]
[conda-forge-ci-setup]
[docker-images]
[conda-smithy]
(Automations)
[admin-migrations]
[artifact-validation]
[regro/cf-scripts]
[conda-forge-webservices]
[regro/cf-graph-countyfair]
[regro/libcfgraph + regro/libcflib]
[feedstock-outputs]
(Communications)
[conda-forge.github.io]
[blog]
[status]
[by-the-numbers]
[conda-forge-status-monitor]
[feedstocks]
(Bots & apps)
[conda-forge-admin]
[conda-forge-bot]
[conda-forge-coordinator]
[conda-forge-daemon]
[conda-forge-linter]
[conda-forge-manager]
[conda-forge-status]
[regro-cf-autotick-bot]
[conda-forge-curator]
[conda-forge-webservices]
(Delivery)
[anaconda.org]
[ghcr.io]
[quay.io]
(Installers)
Miniforge
Mambaforge
(CI for builds)
Azure Pipelines
Travis CI
cirun.io
(Infra)
Heroku
Github Actions
Circle CI
```
## Quadrant Chart
```mermaid
quadrantChart
title Reach and engagement of campaigns
x-axis Low Reach --> High Reach
y-axis Low Engagement --> High Engagement
quadrant-1 We should expand
quadrant-2 Need to promote
quadrant-3 Re-evaluate
quadrant-4 May be improved
Campaign A: [0.3, 0.6]
Campaign B: [0.45, 0.23]
Campaign C: [0.57, 0.69]
Campaign D: [0.78, 0.34]
Campaign E: [0.40, 0.34]
Campaign F: [0.35, 0.78]
```

View file

@ -1292,10 +1292,10 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
"@braintree/sanitize-url@^6.0.0":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.2.tgz#6110f918d273fe2af8ea1c4398a88774bb9fc12f"
integrity sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg==
"@braintree/sanitize-url@^6.0.1":
version "6.0.4"
resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz#923ca57e173c6b232bbbb07347b1be982f03e783"
integrity sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==
"@colors/colors@1.5.0":
version "1.5.0"
@ -3161,6 +3161,23 @@
dependencies:
"@types/node" "*"
"@types/d3-scale-chromatic@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz#103124777e8cdec85b20b51fd3397c682ee1e954"
integrity sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==
"@types/d3-scale@^4.0.3":
version "4.0.4"
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.4.tgz#3c5e2263eea5a3670cd91043b9f4d150a94c43f1"
integrity sha512-eq1ZeTj0yr72L8MQk6N6heP603ubnywSDRfNpi5enouR112HzGLS6RIvExCzZTraFF4HdzNpJMwA/zGiMoHUUw==
dependencies:
"@types/d3-time" "*"
"@types/d3-time@*":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.0.tgz#e1ac0f3e9e195135361fa1a1d62f795d87e6e819"
integrity sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==
"@types/debug@^4.0.0":
version "4.1.8"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.8.tgz#cef723a5d0a90990313faec2d1e22aee5eecb317"
@ -6256,6 +6273,13 @@ cytoscape@^3.23.0:
heap "^0.2.6"
lodash "^4.17.21"
"d3-array@1 - 2":
version "2.12.1"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81"
integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==
dependencies:
internmap "^1.0.0"
"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0:
version "3.2.4"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5"
@ -6372,6 +6396,11 @@ d3-hierarchy@3:
dependencies:
d3-color "1 - 3"
d3-path@1:
version "1.0.9"
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf"
integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==
"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526"
@ -6392,6 +6421,14 @@ d3-random@3:
resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-3.0.1.tgz#d4926378d333d9c0bfd1e6fa0194d30aebaa20f4"
integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==
d3-sankey@^0.12.3:
version "0.12.3"
resolved "https://registry.yarnpkg.com/d3-sankey/-/d3-sankey-0.12.3.tgz#b3c268627bd72e5d80336e8de6acbfec9d15d01d"
integrity sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==
dependencies:
d3-array "1 - 2"
d3-shape "^1.2.0"
d3-scale-chromatic@3:
version "3.0.0"
resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz#15b4ceb8ca2bb0dcb6d1a641ee03d59c3b62376a"
@ -6423,6 +6460,13 @@ d3-shape@3:
dependencies:
d3-path "^3.1.0"
d3-shape@^1.2.0:
version "1.3.7"
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7"
integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==
dependencies:
d3-path "1"
"d3-time-format@2 - 4", d3-time-format@4:
version "4.1.0"
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a"
@ -6500,10 +6544,10 @@ d3@^7.4.0, d3@^7.8.2:
d3-transition "3"
d3-zoom "3"
dagre-d3-es@7.0.9:
version "7.0.9"
resolved "https://registry.yarnpkg.com/dagre-d3-es/-/dagre-d3-es-7.0.9.tgz#aca12fccd9d09955a4430029ba72ee6934542a8d"
integrity sha512-rYR4QfVmy+sR44IBDvVtcAmOReGBvRCWDpO2QjYwqgh9yijw6eSHBqaPG/LIOEy7aBsniLvtMW6pg19qJhq60w==
dagre-d3-es@7.0.10:
version "7.0.10"
resolved "https://registry.yarnpkg.com/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz#19800d4be674379a3cd8c86a8216a2ac6827cadc"
integrity sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==
dependencies:
d3 "^7.8.2"
lodash-es "^4.17.21"
@ -6846,10 +6890,10 @@ domhandler@^5.0.2, domhandler@^5.0.3:
dependencies:
domelementtype "^2.3.0"
dompurify@2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.3.tgz#f4133af0e6a50297fc8874e2eaedc13a3c308c03"
integrity sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==
dompurify@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.5.tgz#eb3d9cfa10037b6e73f32c586682c4b2ab01fbed"
integrity sha512-F9e6wPGtY+8KNMRAVfxeCOHU0/NPWMSENNq4pQctuXRqqdEPW7q3CrLbR5Nse044WwacyjHGOMlvNsBe1y6z9A==
domutils@^2.5.2, domutils@^2.8.0:
version "2.8.0"
@ -9225,6 +9269,11 @@ internal-slot@^1.0.3, internal-slot@^1.0.5:
resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009"
integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
internmap@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
interpret@^1.0.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
@ -11296,24 +11345,28 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
mermaid@^9.4.3:
version "9.4.3"
resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-9.4.3.tgz#62cf210c246b74972ea98c19837519b6f03427f2"
integrity sha512-TLkQEtqhRSuEHSE34lh5bCa94KATCyluAXmFnNI2PRZwOpXFeqiJWwZl+d2CcemE1RS6QbbueSSq9QIg8Uxcyw==
mermaid@^10.4.0:
version "10.4.0"
resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-10.4.0.tgz#f89bf0ada161cbbe4dba2776e805119f7245a102"
integrity sha512-4QCQLp79lvz7UZxow5HUX7uWTPJOaQBVExduo91tliXC7v78i6kssZOPHxLL+Xs30KU72cpPn3g3imw/xm/gaw==
dependencies:
"@braintree/sanitize-url" "^6.0.0"
"@braintree/sanitize-url" "^6.0.1"
"@types/d3-scale" "^4.0.3"
"@types/d3-scale-chromatic" "^3.0.0"
cytoscape "^3.23.0"
cytoscape-cose-bilkent "^4.1.0"
cytoscape-fcose "^2.1.0"
d3 "^7.4.0"
dagre-d3-es "7.0.9"
d3-sankey "^0.12.3"
dagre-d3-es "7.0.10"
dayjs "^1.11.7"
dompurify "2.4.3"
dompurify "^3.0.5"
elkjs "^0.8.2"
khroma "^2.0.0"
lodash-es "^4.17.21"
mdast-util-from-markdown "^1.3.0"
non-layered-tidy-tree-layout "^2.0.2"
stylis "^4.1.2"
stylis "^4.1.3"
ts-dedent "^2.2.0"
uuid "^9.0.0"
web-worker "^1.2.0"
@ -15712,7 +15765,7 @@ stylelint@^14.16.1:
v8-compile-cache "^2.3.0"
write-file-atomic "^4.0.2"
stylis@^4.1.2:
stylis@^4.1.3:
version "4.3.0"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.0.tgz#abe305a669fc3d8777e10eefcfc73ad861c5588c"
integrity sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ==