Merge branch 'develop' into pr/maxstanley/1412

* develop: (34 commits)
  chore: Add isRough to stats
  Update snapshots
  feat: Add rough mode
  fix(deps): update dependency mermaid to v10.9.1
  chore(deps): update all non-major dependencies
  build: update Browserslist db
  chore(deps): update dependency svelte to v4.2.16
  chore(deps): update all non-major dependencies
  chore(deps): update all non-major dependencies
  chore(deps): update all non-major dependencies
  build: update Browserslist db
  build: update Browserslist db
  chore(deps): update all non-major dependencies
  chore(deps): update all non-major dependencies
  Update README.md
  fix(#1401): Handle error when loading gist
  chore(deps): update all non-major dependencies
  chore(deps): update all non-major dependencies
  Fix clicking issue in diagramUpdate.spec.ts
  Remove pnpm-lock.yaml
  ...
This commit is contained in:
Sidharth Vinod
2024-06-16 19:07:48 +05:30
16 changed files with 1758 additions and 872 deletions
+1 -1
View File
@@ -1 +1 @@
v20.11.1
20.13.1
+1
View File
@@ -19,6 +19,7 @@
"pako",
"panzoom",
"pzoom",
"roughjs",
"Serde",
"serdes",
"tailwindcss",
+1 -1
View File
@@ -1,4 +1,4 @@
[![Mermaid Live Editor](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/detailed/2ckppp/master&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/2ckppp/runs) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)[![Netlify Status](https://api.netlify.com/api/v1/badges/27fa023d-7c73-4a3f-9791-b3b657a47100/deploy-status)](https://app.netlify.com/sites/mermaidjs/deploys)
[![Mermaid Live Editor](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/detailed/2ckppp/master&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/2ckppp/runs) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Netlify Status](https://api.netlify.com/api/v1/badges/27fa023d-7c73-4a3f-9791-b3b657a47100/deploy-status)](https://app.netlify.com/sites/mermaidjs/deploys)
# Contributors are welcome!
+1 -1
View File
@@ -69,7 +69,7 @@ A & B & C & D & E --> F & G & K & Z & i`);
});
it('supports commenting code out/in', () => {
cy.get('#editor').contains('Car').click();
cy.get('#editor').contains('Car').click({ force: true });
cy.get('#editor').get('textarea').type(`${cmd}/`, { force: true });
cy.get('#view').contains('Car').should('not.exist');
+16 -14
View File
@@ -25,38 +25,38 @@
"@cypress/snapshot": "2.1.7",
"@fortawesome/fontawesome-free": "^6.5.1",
"@sveltejs/adapter-static": "3.0.1",
"@sveltejs/kit": "2.5.0",
"@sveltejs/kit": "2.5.9",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@testing-library/svelte": "4.1.0",
"@testing-library/svelte": "4.2.3",
"@types/lodash-es": "^4.17.12",
"@types/pako": "2.0.3",
"@types/uuid": "9.0.8",
"@typescript-eslint/eslint-plugin": "6.20.0",
"@typescript-eslint/parser": "6.20.0",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/parser": "6.21.0",
"@vitest/ui": "^1.1.3",
"autoprefixer": "^10.4.14",
"c8": "7.14.0",
"chai": "^4.3.7",
"cssnano": "^6.0.0",
"cypress": "12.17.4",
"cypress-localstorage-commands": "2.2.5",
"eslint": "8.56.0",
"cypress-localstorage-commands": "2.2.6",
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-cypress": "2.15.1",
"eslint-plugin-cypress": "2.15.2",
"eslint-plugin-es": "^4.1.0",
"eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-postcss-modules": "^2.0.0",
"eslint-plugin-svelte": "^2.35.1",
"eslint-plugin-tailwindcss": "^3.13.1",
"eslint-plugin-unicorn": "^50.0.1",
"eslint-plugin-vitest": "^0.3.20",
"eslint-plugin-vitest": "^0.5.0",
"esserializer": "^1.3.11",
"husky": "^8.0.3",
"jsdom": "^21.1.2",
"lint-staged": "^15.2.0",
"node-html-parser": "^6.1.5",
"postcss": "^8.4.33",
"postcss-load-config": "5.0.2",
"postcss-load-config": "5.1.0",
"prettier": "^3.1.0",
"prettier-plugin-svelte": "^3.1.2",
"prettier-plugin-tailwindcss": "^0.5.11",
@@ -70,16 +70,18 @@
"vitest-dom": "^0.1.1"
},
"dependencies": {
"@mermaid-js/mermaid-zenuml": "^0.2.0",
"daisyui": "2.52.0",
"dayjs": "^1.11.7",
"js-base64": "3.7.6",
"js-base64": "3.7.7",
"lodash-es": "^4.17.21",
"mermaid": "10.8.0",
"monaco-editor": "0.45.0",
"mermaid": "10.9.1",
"monaco-editor": "0.48.0",
"pako": "2.1.0",
"plausible-tracker": "^0.3.8",
"random-word-slugs": "0.1.7",
"svg-pan-zoom": "3.6.1",
"svg2roughjs": "^3.2.0",
"uuid": "9.0.1"
},
"lint-staged": {
@@ -89,8 +91,8 @@
]
},
"volta": {
"node": "18.19.0",
"yarn": "1.22.21"
"node": "18.20.2",
"yarn": "1.22.22"
},
"engines": {
"node": ">=16.7"
+5
View File
@@ -10,3 +10,8 @@
.action-btn {
@apply btn btn-primary;
}
#graph-div sub,
#graph-div sup {
position: initial;
vertical-align: revert;
}
+27 -2
View File
@@ -141,6 +141,30 @@
C --> db
D --> C
style m fill:#d6d,stroke:#333,stroke-width:4px
`,
ZenUML: `zenuml
title Order Service
@Actor Client #FFEBE6
@Boundary OrderController #0747A6
@EC2 <<BFF>> OrderService #E3FCEF
group BusinessService {
@Lambda PurchaseService
@AzureFunction InvoiceService
}
@Starter(Client)
// \`POST /orders\`
OrderController.post(payload) {
OrderService.create(payload) {
order = new Order(payload)
if(order != null) {
par {
PurchaseService.createPO(order)
InvoiceService.createInvoice(order)
}
}
}
}
`
};
@@ -154,7 +178,7 @@
};
// Adding in this array will add an icon to the preset menu
const newDiagrams: SampleTypes[] = ['QuadrantChart', 'XYChart', 'Block'];
const newDiagrams: SampleTypes[] = ['QuadrantChart', 'XYChart', 'Block', 'ZenUML'];
const diagramOrder: SampleTypes[] = [
'Flow',
'Sequence',
@@ -168,7 +192,8 @@
'Mindmap',
'QuadrantChart',
'XYChart',
'Block'
'Block',
'ZenUML'
];
</script>
+39 -15
View File
@@ -1,17 +1,19 @@
<script lang="ts">
import { inputStateStore, stateStore, updateCodeStore } from '$lib/util/state';
import { onMount } from 'svelte';
import panzoom from 'svg-pan-zoom';
import type { State, ValidatedState } from '$lib/types';
import { recordRenderTime, shouldRefreshView } from '$lib/util/autoSync';
import { render as renderDiagram } from '$lib/util/mermaid';
import { inputStateStore, stateStore, updateCodeStore } from '$lib/util/state';
import { logEvent, saveStatistics } from '$lib/util/stats';
import { cmdKey } from '$lib/util/util';
import { render as renderDiagram } from '$lib/util/mermaid';
import type { MermaidConfig } from 'mermaid';
import { recordRenderTime, shouldRefreshView } from '$lib/util/autoSync';
import { onMount } from 'svelte';
import panzoom from 'svg-pan-zoom';
import { Svg2Roughjs } from 'svg2roughjs';
let code = '';
let config = '';
let container: HTMLDivElement;
let rough: boolean;
let view: HTMLDivElement;
let error = false;
let errorLines: string[] = [];
@@ -75,7 +77,12 @@
outOfSync = false;
manualUpdate = true;
// Do not render if there is no change in Code/Config/PanZoom
if (code === state.code && config === state.mermaid && panZoomEnabled === state.panZoom) {
if (
code === state.code &&
config === state.mermaid &&
panZoomEnabled === state.panZoom &&
rough === state.rough
) {
return;
}
@@ -87,6 +94,7 @@
code = state.code;
config = state.mermaid;
panZoomEnabled = state.panZoom;
rough = state.rough;
const scroll = view.parentElement?.scrollTop;
delete container.dataset.processed;
const { svg, bindFunctions } = await renderDiagram(
@@ -98,15 +106,31 @@
if (svg.length > 0) {
handlePanZoom(state);
container.innerHTML = svg;
console.log({ svg });
const graphDiv = document.querySelector<HTMLElement>('#graph-div');
const graphDiv = document.querySelector<SVGSVGElement>('#graph-div');
if (!graphDiv) {
throw new Error('graph-div not found');
}
graphDiv.setAttribute('height', '100%');
graphDiv.style.maxWidth = '100%';
if (bindFunctions) {
bindFunctions(graphDiv);
if (state.rough) {
const svg2roughjs = new Svg2Roughjs('#container');
svg2roughjs.svg = graphDiv;
await svg2roughjs.sketch();
graphDiv.remove();
const sketch = document.querySelector<HTMLElement>('#container > svg');
if (!sketch) {
throw new Error('sketch not found');
}
const height = sketch.getAttribute('height');
const width = sketch.getAttribute('width');
sketch.setAttribute('height', '100%');
sketch.setAttribute('width', '100%');
sketch.setAttribute('viewBox', `0 0 ${width} ${height}`);
sketch.style.maxWidth = '100%';
} else {
graphDiv.setAttribute('height', '100%');
graphDiv.style.maxWidth = '100%';
if (bindFunctions) {
bindFunctions(graphDiv);
}
}
}
if (view.parentElement && scroll) {
@@ -122,9 +146,9 @@
console.error('view fail', error_);
error = true;
}
const timeTaken = Date.now() - startTime;
saveStatistics(code, timeTaken);
recordRenderTime(timeTaken, () => {
const renderTime = Date.now() - startTime;
saveStatistics({ code, renderTime, isRough: state.rough });
recordRenderTime(renderTime, () => {
$inputStateStore.updateDiagram = true;
});
};
+1
View File
@@ -23,6 +23,7 @@ export interface State {
mermaid: string;
updateDiagram: boolean;
autoSync: boolean;
rough: boolean;
editorMode?: EditorMode;
panZoom?: boolean;
pan?: { x: number; y: number };
+7 -3
View File
@@ -2,9 +2,9 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { addHistoryEntry } from '$lib/components/History/history';
import type { State } from '$lib/types';
import { defaultState } from '$lib/util/state';
import { addHistoryEntry } from '$lib/components/History/history';
import { fetchJSON, fetchText } from '$lib/util/util';
const codeFileName = 'code.mmd';
@@ -102,8 +102,12 @@ export const loadGistData = async (gistURL: string): Promise<State> => {
);
const gistHistory: GistData[] = [];
for (const entry of history) {
const data: GistData | undefined = await getGistData(entry.url).catch();
data && gistHistory.push(data);
try {
const data: GistData = await getGistData(entry.url);
gistHistory.push(data);
} catch (error) {
console.error(error);
}
}
if (gistHistory.length === 0) {
throw new Error('Invalid gist provided');
+5
View File
@@ -1,11 +1,16 @@
import mermaid from 'mermaid';
import type { MermaidConfig, RenderResult } from 'mermaid';
import zenuml from '@mermaid-js/mermaid-zenuml';
const init = mermaid.registerExternalDiagrams([zenuml]);
export const render = async (
config: MermaidConfig,
code: string,
id: string
): Promise<RenderResult> => {
await init;
// Should be able to call this multiple times without any issues.
mermaid.initialize(config);
return await mermaid.render(id, code);
+3 -3
View File
@@ -13,19 +13,19 @@ const verifySerde = (state: State, serde?: SerdeType): string => {
describe('Serde tests', () => {
it('should serialize and deserialize with default serde', () => {
expect(verifySerde(defaultState)).toMatchInlineSnapshot(
'"pako:eNpVjk2Lg0AMhv9KyGkL9Q94WGh1t5fCFurN6SFo7AztfDBGpKj_fcd62c0pvM_zhkzY-JYxx-7px0ZTFKhK5SDNoS50NL1Y6m-QZZ_ziQWsd_ya4fhx8tBrH4Jx993mH1cJium8agyijXssGyre_R_HM5T1mYL4cPtLqtHP8FWbi07n_xMdObW-647yjrKGIhQU3wru0XK0ZNr0_rQmCkWzZYV5WlvuaHiKQuWWpNIg_vpyDeYSB97jEFoSLg3dI9ktXH4B_cJWqw"'
`"pako:eNpVjs1qw0AMhF9F6NRC_AI-FBq7zSXQQnPz5iBs2bvE-8NaSwi2373r-NLqJM18M2jG1neMJfajv7eaosClVg7yvDeVjmYSS9MViuJtObGA9Y4fCxxfTh4m7UMwbnjd-eMGQTWfN4xBtHG3dbeqZ_7L8QJ1c6YgPlz_Ope7X-CjMd861_93dOSc-mx6KnsqWopQUXwieEDL0ZLp8vvzpigUzZYVlnntuKc0ikLl1oxSEv_zcC2WEhMfMPo0aMyd45SvFDoSrg0NkeyOrL_WfFuF"`
);
});
it('should serialize and deserialize with base64 serde', () => {
expect(verifySerde(defaultState, 'base64')).toMatchInlineSnapshot(
'"base64:eyJjb2RlIjoiZmxvd2NoYXJ0IFREXG4gICAgQVtDaHJpc3RtYXNdIC0tPnxHZXQgbW9uZXl8IEIoR28gc2hvcHBpbmcpXG4gICAgQiAtLT4gQ3tMZXQgbWUgdGhpbmt9XG4gICAgQyAtLT58T25lfCBEW0xhcHRvcF1cbiAgICBDIC0tPnxUd298IEVbaVBob25lXVxuICAgIEMgLS0-fFRocmVlfCBGW2ZhOmZhLWNhciBDYXJdXG4gICIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0"'
`"base64:eyJjb2RlIjoiZmxvd2NoYXJ0IFREXG4gICAgQVtDaHJpc3RtYXNdIC0tPnxHZXQgbW9uZXl8IEIoR28gc2hvcHBpbmcpXG4gICAgQiAtLT4gQ3tMZXQgbWUgdGhpbmt9XG4gICAgQyAtLT58T25lfCBEW0xhcHRvcF1cbiAgICBDIC0tPnxUd298IEVbaVBob25lXVxuICAgIEMgLS0-fFRocmVlfCBGW2ZhOmZhLWNhciBDYXJdXG4gICIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJhdXRvU3luYyI6dHJ1ZSwicm91Z2giOmZhbHNlLCJ1cGRhdGVEaWFncmFtIjp0cnVlfQ"`
);
});
it('should serialize and deserialize with pako serde', () => {
expect(verifySerde(defaultState, 'pako')).toMatchInlineSnapshot(
'"pako:eNpVjk2Lg0AMhv9KyGkL9Q94WGh1t5fCFurN6SFo7AztfDBGpKj_fcd62c0pvM_zhkzY-JYxx-7px0ZTFKhK5SDNoS50NL1Y6m-QZZ_ziQWsd_ya4fhx8tBrH4Jx993mH1cJium8agyijXssGyre_R_HM5T1mYL4cPtLqtHP8FWbi07n_xMdObW-647yjrKGIhQU3wru0XK0ZNr0_rQmCkWzZYV5WlvuaHiKQuWWpNIg_vpyDeYSB97jEFoSLg3dI9ktXH4B_cJWqw"'
`"pako:eNpVjs1qw0AMhF9F6NRC_AI-FBq7zSXQQnPz5iBs2bvE-8NaSwi2373r-NLqJM18M2jG1neMJfajv7eaosClVg7yvDeVjmYSS9MViuJtObGA9Y4fCxxfTh4m7UMwbnjd-eMGQTWfN4xBtHG3dbeqZ_7L8QJ1c6YgPlz_Ope7X-CjMd861_93dOSc-mx6KnsqWopQUXwieEDL0ZLp8vvzpigUzZYVlnntuKc0ikLl1oxSEv_zcC2WEhMfMPo0aMyd45SvFDoSrg0NkeyOrL_WfFuF"`
);
});
+1
View File
@@ -19,6 +19,7 @@ export const defaultState: State = {
theme: 'default'
}),
autoSync: true,
rough: false,
updateDiagram: true
};
+13 -5
View File
@@ -1,6 +1,6 @@
import { browser } from '$app/environment';
import { env } from './env';
import type PlausibleInstance from 'plausible-tracker';
import { env } from './env';
export let plausible: ReturnType<typeof PlausibleInstance> | undefined;
export const initAnalytics = async (): Promise<void> => {
@@ -47,15 +47,23 @@ export const countLines = (code: string): number => {
return (code.match(/\n/g)?.length ?? 0) + 1;
};
export const saveStatistics = (graph: string, renderTime: number): void => {
const graphType = detectType(graph);
export const saveStatistics = ({
code,
renderTime,
isRough
}: {
code: string;
renderTime: number;
isRough: boolean;
}): void => {
const graphType = detectType(code);
if (!graphType) {
return;
}
const length = countLines(graph);
const length = countLines(code);
const lengthBucket = getBucket(length);
const renderTimeMsBucket = getBucket(renderTime);
logEvent('render', { graphType, length, lengthBucket, renderTimeMsBucket });
logEvent('render', { graphType, length, lengthBucket, renderTimeMsBucket, isRough });
};
const getBucket = (length: number): string => {
+22 -7
View File
@@ -1,17 +1,17 @@
<script lang="ts">
import { dev } from '$app/environment';
import { base } from '$app/paths';
import Actions from '$lib/components/Actions.svelte';
import Card from '$lib/components/Card/Card.svelte';
import Editor from '$lib/components/Editor.svelte';
import History from '$lib/components/History/History.svelte';
import Navbar from '$lib/components/Navbar.svelte';
import Preset from '$lib/components/Preset.svelte';
import Actions from '$lib/components/Actions.svelte';
import View from '$lib/components/View.svelte';
import Card from '$lib/components/Card/Card.svelte';
import History from '$lib/components/History/History.svelte';
import type { DocumentationConfig, EditorMode, Tab, ValidatedState } from '$lib/types';
import { inputStateStore, stateStore, updateCodeStore } from '$lib/util/state';
import { cmdKey, initHandler, syncDiagram } from '$lib/util/util';
import { onMount } from 'svelte';
import { base } from '$app/paths';
import { dev } from '$app/environment';
import type { Tab, DocumentationConfig, EditorMode, ValidatedState } from '$lib/types';
const MCBaseURL = dev ? 'http://localhost:5174' : 'https://mermaidchart.com';
const docURLBase = 'https://mermaid.js.org';
@@ -187,12 +187,27 @@
<div class="flex flex-1 flex-col overflow-hidden">
<Card title="Diagram" isCloseable={false}>
<div slot="actions" class="flex flex-row items-center gap-2">
<label class="label cursor-pointer py-0" for="panZoom">
<label
class="label flex cursor-pointer gap-1 py-0"
title="Rough mode is in beta. Features like clickable nodes, Pan & Zoom, will be disabled."
for="rough">
<span>Rough</span>
<input
type="checkbox"
class="toggle {$stateStore.rough ? 'btn-secondary' : 'toggle-primary'}"
id="rough"
bind:checked={$inputStateStore.rough} />
</label>
<label
class="label flex cursor-pointer gap-1 py-0"
title={$stateStore.rough ? 'Pan & Zoom is disabled in rough mode.' : ''}
for="panZoom">
<span>Pan & Zoom</span>
<input
type="checkbox"
class="toggle {$stateStore.panZoom ? 'btn-secondary' : 'toggle-primary'}"
id="panZoom"
disabled={$stateStore.rough}
bind:checked={$inputStateStore.panZoom} />
</label>
<a
+1615 -820
View File
File diff suppressed because it is too large Load Diff