Compare commits

...
26 Commits
Author SHA1 Message Date
Sidharth Vinod 449dead2e5 fix: Race condition with async queue. 2022-10-19 00:27:36 +05:30
Sidharth Vinod aaec5912b4 fix: features spelling 2022-10-18 14:39:42 +05:30
Sidharth Vinod 187edf0f9f Merge branch 'sidv/tsMermaid' into sidv/mindmap
* sidv/tsMermaid:
  feat: New diagrams
  Rename samples
  Remove mermaid types
  Mermaid 9.2.0-rc1
2022-10-18 14:37:59 +05:30
Sidharth Vinod 5efc9ae10d Merge branch 'develop' into sidv/tsMermaid
* develop: (40 commits)
  Add tabindex
  chore: A11y changes
  chore(deps): update all non-major dependencies
  fix: favicon size
  Update Browserslist
  chore: Update favicon
  Update Browserslist
  chore(deps): update all non-major dependencies
  Update Browserslist
  Fix an issue where the image is jpg format on mermaid.ink
  chore(deps): update all non-major dependencies
  chore(deps): update all non-major dependencies
  chore: Remove stability days from renovate
  Update Browserslist
  chore(deps): update all non-major dependencies
  Update Browserslist
  chore(deps): update all non-major dependencies
  Update Browserslist
  chore(deps): update all non-major dependencies
  Update Browserslist
  ...
2022-10-18 14:36:20 +05:30
Sidharth Vinod 77522abef6 Merge branch 'develop' into sidv/mindmap
* develop:
  Add tabindex
2022-10-18 14:34:20 +05:30
Sidharth Vinod 90a4db2644 Merge branch 'develop' into sidv/mindmap
* develop:
  chore: A11y changes
2022-10-18 14:30:01 +05:30
Sidharth Vinod 7de5b3bfb1 Merge branch 'sidv/mindmap' of https://github.com/mermaid-js/mermaid-live-editor into sidv/mindmap
* 'sidv/mindmap' of https://github.com/mermaid-js/mermaid-live-editor:
  Update Browserslist
2022-10-18 12:26:05 +05:30
sidharthv96 826ccd983f Update Browserslist 2022-10-18 06:45:53 +00:00
Sidharth Vinod 78d3ed6e6c Merge branch 'develop' into sidv/mindmap
* develop:
  chore(deps): update all non-major dependencies
  fix: favicon size
  Update Browserslist
  chore: Update favicon
  Update Browserslist
  chore(deps): update all non-major dependencies
2022-10-18 12:15:42 +05:30
Sidharth Vinod 36083c849b fix: state url 2022-10-18 12:14:40 +05:30
Sidharth Vinod 29fc3fef21 fix: Ignore handle empty serialized state 2022-10-18 11:42:40 +05:30
Sidharth Vinod 1f3c74ae19 Merge branch 'sidv/mindmap' of https://github.com/mermaid-js/mermaid-live-editor into sidv/mindmap
* 'sidv/mindmap' of https://github.com/mermaid-js/mermaid-live-editor:
  Update Browserslist
2022-10-17 14:11:35 +05:30
Sidharth Vinod 433fd4d045 chore: ENV types, mindmap rc4 2022-10-17 14:11:26 +05:30
sidharthv96 814ce1aee3 Update Browserslist 2022-10-17 07:00:59 +00:00
Sidharth Vinod ce0517b782 Merge branch 'develop' into sidv/mindmap
* develop:
  Update Browserslist
  Fix an issue where the image is jpg format on mermaid.ink
2022-10-17 12:29:46 +05:30
sidharthv96 260d4970ae Update Browserslist 2022-10-17 06:31:20 +00:00
Sidharth Vinod 7f22aea3eb Async statestore, Update mermaid version 2022-10-17 12:00:02 +05:30
Sidharth Vinod b90cf45eff 9.2.0-rc5 2022-10-12 13:08:58 +05:30
Sidharth Vinod 020075da92 feat: lazy load 2022-10-12 12:26:04 +05:30
Sidharth Vinod de41008284 feat: Add lazyload 2022-10-11 13:49:20 +05:30
Sidharth Vinod bc9d53b701 feat: New diagrams 2022-09-09 23:18:02 +05:30
Sidharth Vinod c21db93399 Merge branch 'master' into sidv/tsMermaid
* master:
  chore(deps): update all non-major dependencies
  chore(deps): update dependency node-html-parser to v6
  chore(deps): update dependency font-awesome to v6
  chore(deps): update actions/setup-node action to v3
  fix(deps): pin dependency analytics-plugin-plausible to 0.0.6
2022-09-09 20:58:44 +05:30
Sidharth Vinod 9777be9a7b Rename samples 2022-09-09 20:58:32 +05:30
Sidharth Vinod 00b80d224c Remove mermaid types 2022-09-09 18:51:59 +05:30
Sidharth Vinod 2aa4666dab Merge branch 'master' into sidv/tsMermaid
* master:
  chore(deps): update all non-major dependencies
  chore(deps): update dependency @types/pako to v2
2022-09-09 18:49:48 +05:30
Sidharth Vinod 19c0c698ce Mermaid 9.2.0-rc1 2022-09-09 18:49:13 +05:30
13 changed files with 273 additions and 112 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ describe('Check actions', () => {
// Verify downloaded file is different for different diagrams // Verify downloaded file is different for different diagrams
cy.contains('Sample Diagrams').click(); cy.contains('Sample Diagrams').click();
cy.contains('ER Diagram').click(); cy.contains('ER').click();
cy.get(`#downloadPNG`).click(); cy.get(`#downloadPNG`).click();
verifyFileSize('diagram', 'png', 46_000); verifyFileSize('diagram', 'png', 46_000);
+3 -3
View File
@@ -13,13 +13,13 @@ describe('Editor docs tests', () => {
}); });
it('Test to see if the correct URL loads when changing from one diagram to other', () => { it('Test to see if the correct URL loads when changing from one diagram to other', () => {
cy.contains('Flow Chart').click(); cy.contains('Flow').click();
cy.get(`[data-cy=docs][href$="/#/flowchart"]`).should('exist'); cy.get(`[data-cy=docs][href$="/#/flowchart"]`).should('exist');
cy.contains('Config').click(); cy.contains('Config').click();
cy.get(`[data-cy=docs][href$="/#/flowchart?id=configuration"]`).should('exist'); cy.get(`[data-cy=docs][href$="/#/flowchart?id=configuration"]`).should('exist');
cy.contains('Sequence Diagram').click(); cy.contains('Sequence').click();
cy.get(`[data-cy=docs][href$="/#/sequenceDiagram?id=configuration"]`).should('exist'); cy.get(`[data-cy=docs][href$="/#/sequenceDiagram?id=configuration"]`).should('exist');
cy.contains('Code').click(); cy.contains('Code').click();
@@ -27,7 +27,7 @@ describe('Editor docs tests', () => {
}); });
it("Test to check URLs for a case where config URL doesn't exist", () => { it("Test to check URLs for a case where config URL doesn't exist", () => {
cy.contains('State Diagram').click(); cy.contains('State').click();
cy.get(`[data-cy=docs][href$="/#/stateDiagram"]`).should('exist'); cy.get(`[data-cy=docs][href$="/#/stateDiagram"]`).should('exist');
cy.contains('Config').click(); cy.contains('Config').click();
+2 -2
View File
@@ -20,9 +20,9 @@ describe('Site Loads', () => {
it('should load sample diagrams when clicked', () => { it('should load sample diagrams when clicked', () => {
cy.contains('Sample Diagrams').click(); cy.contains('Sample Diagrams').click();
cy.contains('Pie Chart').click(); cy.contains('Pie').click();
cy.contains('pie title Pets adopted by volunteers'); cy.contains('pie title Pets adopted by volunteers');
cy.contains('Class Diagram').click(); cy.contains('Class').click();
cy.contains('classDiagram'); cy.contains('classDiagram');
}); });
+4 -2
View File
@@ -5,6 +5,7 @@
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"dev": "vite dev", "dev": "vite dev",
"dev:force": "MERMAID_LOCAL=true yarn dev --force",
"dev:test": "yarn dev", "dev:test": "yarn dev",
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
@@ -26,7 +27,7 @@
"@sveltejs/kit": "1.0.0-next.516", "@sveltejs/kit": "1.0.0-next.516",
"@testing-library/jest-dom": "5.16.5", "@testing-library/jest-dom": "5.16.5",
"@testing-library/svelte": "3.2.2", "@testing-library/svelte": "3.2.2",
"@types/mermaid": "9.1.0", "@types/async": "^3.2.15",
"@types/pako": "2.0.0", "@types/pako": "2.0.0",
"@types/uuid": "8.3.4", "@types/uuid": "8.3.4",
"@typescript-eslint/eslint-plugin": "5.40.1", "@typescript-eslint/eslint-plugin": "5.40.1",
@@ -67,9 +68,10 @@
"dependencies": { "dependencies": {
"analytics": "0.8.1", "analytics": "0.8.1",
"analytics-plugin-plausible": "0.0.6", "analytics-plugin-plausible": "0.0.6",
"async": "^3.2.4",
"daisyui": "2.31.0", "daisyui": "2.31.0",
"js-base64": "3.7.2", "js-base64": "3.7.2",
"mermaid": "9.1.7", "mermaid": "9.2.0-rc6",
"moment": "2.29.4", "moment": "2.29.4",
"monaco-editor": "0.34.1", "monaco-editor": "0.34.1",
"monaco-mermaid": "1.0.6", "monaco-mermaid": "1.0.6",
+14
View File
@@ -0,0 +1,14 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly MERMAID_RENDERER_URL: string;
readonly MERMAID_KROKI_RENDERER_URL: string;
readonly MERMAID_CDN_URL: string;
readonly MERMAID_BASE_URL: string;
readonly MERMAID_LOCAL: boolean;
// more env variables...
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
+2 -1
View File
@@ -1,12 +1,13 @@
<script lang="ts"> <script lang="ts">
import { browser } from '$app/environment'; import { browser } from '$app/environment';
import Card from '$lib/components/card/card.svelte'; import Card from '$lib/components/card/card.svelte';
import { krokiRendererUrl, rendererUrl } from '$lib/util/env'; import { env } from '$lib/util/env';
import { pakoSerde } from '$lib/util/serde'; import { pakoSerde } from '$lib/util/serde';
import { stateStore } from '$lib/util/state'; import { stateStore } from '$lib/util/state';
import { logEvent } from '$lib/util/stats'; import { logEvent } from '$lib/util/stats';
import { toBase64 } from 'js-base64'; import { toBase64 } from 'js-base64';
import moment from 'moment'; import moment from 'moment';
const { krokiRendererUrl, rendererUrl } = env;
type Exporter = (context: CanvasRenderingContext2D, image: HTMLImageElement) => () => void; type Exporter = (context: CanvasRenderingContext2D, image: HTMLImageElement) => () => void;
+5 -5
View File
@@ -53,15 +53,15 @@
}; };
const loadMonaco = async () => { const loadMonaco = async () => {
console.log('Loading Monaco...');
let i = 0; let i = 0;
while (i++ < 500) { while (i++ < 500) {
try { // @ts-ignore : This is a hack to handle a svelte-kit error when importing monaco.
// @ts-ignore : This is a hack to handle a svelte-kit error when importing monaco. Monaco = window.monaco;
Monaco = window.monaco; if (Monaco !== undefined) {
return; return;
} catch {
await new Promise((r) => setTimeout(r, 100));
} }
await new Promise((r) => setTimeout(r, 100));
} }
alert('Loading Monaco Editor failed. Please try refreshing the page.'); alert('Loading Monaco Editor failed. Please try refreshing the page.');
}; };
+75 -45
View File
@@ -4,19 +4,18 @@
import { logEvent } from '$lib/util/stats'; import { logEvent } from '$lib/util/stats';
const samples = { const samples = {
'Flow Chart': `graph TD Flow: `graph TD
A[Christmas] -->|Get money| B(Go shopping) A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think} B --> C{Let me think}
C -->|One| D[Laptop] C -->|One| D[Laptop]
C -->|Two| E[iPhone] C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]`, C -->|Three| F[fa:fa-car Car]`,
'Sequence Diagram': `sequenceDiagram Sequence: `sequenceDiagram
Alice->>+John: Hello John, how are you? Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me? Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you! John-->>-Alice: Hi Alice, I can hear you!
John-->>-Alice: I feel great! John-->>-Alice: I feel great!`,
`, Class: `classDiagram
'Class Diagram': `classDiagram
Animal <|-- Duck Animal <|-- Duck
Animal <|-- Fish Animal <|-- Fish
Animal <|-- Zebra Animal <|-- Zebra
@@ -36,17 +35,15 @@
class Zebra{ class Zebra{
+bool is_wild +bool is_wild
+run() +run()
} }`,
`, State: `stateDiagram-v2
'State Diagram': `stateDiagram-v2
[*] --> Still [*] --> Still
Still --> [*] Still --> [*]
Still --> Moving Still --> Moving
Moving --> Still Moving --> Still
Moving --> Crash Moving --> Crash
Crash --> [*] Crash --> [*]`,
`, Gantt: `gantt
'Gantt Chart': `gantt
title A Gantt Diagram title A Gantt Diagram
dateFormat YYYY-MM-DD dateFormat YYYY-MM-DD
section Section section Section
@@ -54,24 +51,21 @@
Another task :after a1 , 20d Another task :after a1 , 20d
section Another section Another
Task in sec :2014-01-12 , 12d Task in sec :2014-01-12 , 12d
another task : 24d another task : 24d`,
`, Pie: `pie title Pets adopted by volunteers
'Pie Chart': `pie title Pets adopted by volunteers
"Dogs" : 386 "Dogs" : 386
"Cats" : 85 "Cats" : 85
"Rats" : 15 "Rats" : 15`,
`, ER: `erDiagram
'ER Diagram': `erDiagram CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER }|..|{ DELIVERY-ADDRESS : has CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ ORDER : places CUSTOMER ||--o{ INVOICE : "liable for"
CUSTOMER ||--o{ INVOICE : "liable for" DELIVERY-ADDRESS ||--o{ ORDER : receives
DELIVERY-ADDRESS ||--o{ ORDER : receives INVOICE ||--|{ ORDER : covers
INVOICE ||--|{ ORDER : covers ORDER ||--|{ ORDER-ITEM : includes
ORDER ||--|{ ORDER-ITEM : includes PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT-CATEGORY ||--|{ PRODUCT : contains PRODUCT ||--o{ ORDER-ITEM : "ordered in"`,
PRODUCT ||--o{ ORDER-ITEM : "ordered in" 'User Journey': `journey
`,
'User Journey': ` journey
title My working day title My working day
section Go to work section Go to work
Make tea: 5: Me Make tea: 5: Me
@@ -79,20 +73,35 @@
Do work: 1: Me, Cat Do work: 1: Me, Cat
section Go home section Go home
Go downstairs: 5: Me Go downstairs: 5: Me
Sit down: 3: Me Sit down: 3: Me`,
`, Git: `gitGraph
'Git Graph': ` gitGraph commit
commit commit
commit branch develop
branch develop checkout develop
checkout develop commit
commit commit
commit checkout main
checkout main merge develop
merge develop commit
commit commit`,
commit Mindmap: `mindmap
` root((mindmap))
Origins
Long history
::icon(fa fa-book)
Popularisation
British popular psychology author Tony Buzan
Research
On effectivness<br/>and features
On Automatic creation
Uses
Creative techniques
Strategic planning
Argument mapping
Tools
Pen and paper
Mermaid`
}; };
const loadSampleDiagram = (diagramType: string): void => { const loadSampleDiagram = (diagramType: string): void => {
@@ -102,13 +111,34 @@
}); });
logEvent('loadSampleDiagram', { diagramType }); logEvent('loadSampleDiagram', { diagramType });
}; };
// Adding in this array will add an icon to the preset menu
const newDiagrams: Array<keyof typeof samples> = ['Mindmap'];
const diagramOrder: Array<keyof typeof samples> = [
'Sequence',
'Flow',
'Class',
'State',
'ER',
'Gantt',
'User Journey',
'Git',
'Pie',
'Mindmap'
];
</script> </script>
<Card title="Sample Diagrams" isOpen={false}> <Card title="Sample Diagrams" isOpen={false}>
<div class="flex gap-2 flex-wrap p-2"> <div class="flex flex-wrap p-2 gap-2">
{#each Object.keys(samples) as sample} {#each diagramOrder as sample}
<button class="btn btn-primary normal-case btn-sm" on:click={() => loadSampleDiagram(sample)} <button
>{sample}</button> class="btn btn-sm btn-primary w-28 normal-case flex-grow"
on:click={() => loadSampleDiagram(sample)}>
{sample}
{#if newDiagrams.includes(sample)}
<span class="ml-2 fa fa-heart" />
{/if}
</button>
{/each} {/each}
</div> </div>
</Card> </Card>
+33 -21
View File
@@ -1,12 +1,12 @@
<script lang="ts"> <script lang="ts">
import { inputStateStore, stateStore, updateCodeStore } from '$lib/util/state'; import { inputStateStore, stateStore, updateCodeStore } from '$lib/util/state';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import mermaid from 'mermaid';
import panzoom from 'svg-pan-zoom'; import panzoom from 'svg-pan-zoom';
import type { State, ValidatedState } from '$lib/types'; import type { State, ValidatedState } from '$lib/types';
import { logEvent } from '$lib/util/stats'; import { logEvent } from '$lib/util/stats';
import { cmdKey } from '$lib/util/util'; import { cmdKey } from '$lib/util/util';
import { render as renderDiagram, init as mermaidInit } from '$lib/util/mermaid';
const init = mermaidInit();
let code = ''; let code = '';
let config = ''; let config = '';
let container: HTMLDivElement; let container: HTMLDivElement;
@@ -72,14 +72,21 @@
panZoomEnabled = state.panZoom; panZoomEnabled = state.panZoom;
const scroll = view.parentElement.scrollTop; const scroll = view.parentElement.scrollTop;
delete container.dataset.processed; delete container.dataset.processed;
mermaid.initialize(Object.assign({}, JSON.parse(state.mermaid))); renderDiagram({
mermaid.render('graph-div', code, (svgCode) => { config: Object.assign({}, JSON.parse(state.mermaid)),
if (svgCode.length > 0) { code,
handlePanZoom(state); id: 'graph-div',
container.innerHTML = svgCode; callback: (svgCode, bindFunctions) => {
const graphDiv = document.getElementById('graph-div'); if (svgCode.length > 0) {
graphDiv.setAttribute('height', '100%'); handlePanZoom(state);
graphDiv.style.maxWidth = '100%'; container.innerHTML = svgCode;
const graphDiv = document.getElementById('graph-div');
graphDiv.setAttribute('height', '100%');
graphDiv.style.maxWidth = '100%';
if (bindFunctions) {
bindFunctions(graphDiv);
}
}
} }
}); });
view.parentElement.scrollTop = scroll; view.parentElement.scrollTop = scroll;
@@ -94,6 +101,7 @@
error = true; error = true;
} }
}; };
onMount(() => { onMount(() => {
stateStore.subscribe((state) => { stateStore.subscribe((state) => {
handleStateChange(state); handleStateChange(state);
@@ -106,19 +114,23 @@
}); });
</script> </script>
{#if error && $stateStore.error instanceof Error} {#await init}
<div class="p-2 text-red-600" id="errorContainer">{$stateStore.error}</div> Loading...
{/if} {:then}
{#if error && $stateStore.error instanceof Error}
<div class="p-2 text-red-600" id="errorContainer">{$stateStore.error}</div>
{/if}
{#if outOfSync} {#if outOfSync}
<div class="absolute w-full p-2 z-10 text-yellow-600 bg-base-100 bg-opacity-80 text-center"> <div class="absolute w-full p-2 z-10 text-yellow-600 bg-base-100 bg-opacity-80 text-center">
Diagram out of sync. <br /> Diagram out of sync. <br />
Press <i class="fas fa-sync" /> (Sync button) or <kbd>{cmdKey} + Enter</kbd> to sync. Press <i class="fas fa-sync" /> (Sync button) or <kbd>{cmdKey} + Enter</kbd> to sync.
</div>
{/if}
<div id="view" bind:this={view} class="p-2 h-full" class:error class:outOfSync>
<div id="container" bind:this={container} class="h-full overflow-auto" class:hide />
</div> </div>
{/if} {/await}
<div id="view" bind:this={view} class="p-2 h-full" class:error class:outOfSync>
<div id="container" bind:this={container} class="h-full overflow-auto" class:hide />
</div>
<style> <style>
#view { #view {
+9 -4
View File
@@ -1,4 +1,9 @@
export const rendererUrl: string = export const env = {
(import.meta.env.MERMAID_RENDERER_URL as string) ?? 'https://mermaid.ink'; rendererUrl: import.meta.env.MERMAID_RENDERER_URL ?? 'https://mermaid.ink',
export const krokiRendererUrl: string = krokiRendererUrl: import.meta.env.MERMAID_KROKI_RENDERER_URL ?? 'https://kroki.io',
(import.meta.env.MERMAID_KROKI_RENDERER_URL as string) ?? 'https://kroki.io'; mermaidCDNUrl: import.meta.env.MERMAID_CDN_URL ?? 'https://unpkg.com/@mermaid-js',
mermaidBaseURL: import.meta.env.MERMAID_BASE_URL ?? 'http://localhost:9000',
useLocalMermaid: import.meta.env.MERMAID_LOCAL ?? false,
isDev: import.meta.env.DEV,
baseURL: import.meta.env.BASE_URL
};
+74
View File
@@ -0,0 +1,74 @@
import mermaid from 'mermaid';
// We need to export MermaidConfig and all related types from mermaid.
import type { MermaidConfig } from 'mermaid/dist/config.type';
import { env } from './env';
import queue from 'async/queue';
import type { QueueObject } from 'async';
const { mermaidBaseURL, mermaidCDNUrl, useLocalMermaid } = env;
const getDiagramURL = (name: string, version: string): string => {
if (useLocalMermaid) {
return `${mermaidBaseURL}/${name}-detector.esm.mjs`;
}
return `${mermaidCDNUrl}/${name}@${version}/dist/${name}-detector.esm.mjs`;
};
const initialize = mermaid.initializeAsync({
logLevel: 0,
lazyLoadedDiagrams: [getDiagramURL('mermaid-mindmap', '9.2.0-rc4')],
loadExternalDiagramsAtStartup: true
});
export const init = async () => {
await initialize;
};
interface RenderPayload {
config: MermaidConfig;
code: string;
id: string;
callback: Parameters<typeof mermaid.render>[2];
}
interface ParsePayload {
code: string;
}
interface MermaidTask {
action: 'render' | 'parse';
payload: RenderPayload | ParsePayload;
}
const mermaidQueue: QueueObject<MermaidTask> = queue(async (task: MermaidTask) => {
console.log('adding ', task);
if (task.action === 'render') {
const { config, code, id, callback } = task.payload as RenderPayload;
await mermaid.mermaidAPI.renderAsync(id, code, callback);
}
console.log('done', task);
}, 1);
mermaidQueue.error(function (err, task) {
console.error('task experienced an error', task, err);
});
export const render = async (payload: RenderPayload): Promise<void> => {
// Should be able to call this multiple times without any issues.
// await mermaid.initialize({
// ...config,
// lazyLoadedDiagrams: [
// // We should make SRI mandatory for all lazy-loaded diagrams.
// 'https://unpkg.com/@mermaid-js/mermaid-mindmap@9.2.0-rc2/dist/mermaid-mindmap-detector.esm.mjs'
// ]
// });
// console.log('Rendering', code);
// mermaid.mermaidAPI.render(id, code, callback);
await mermaidQueue.push({
action: 'render',
payload
});
};
export const parse = async (code: string): Promise<boolean> => {
await init();
return mermaid.parseAsync(code);
};
+9 -5
View File
@@ -3,11 +3,13 @@ import { persist, localStorage } from './persist';
import { saveStatistics, countLines } from './stats'; import { saveStatistics, countLines } from './stats';
import { serializeState, deserializeState } from './serde'; import { serializeState, deserializeState } from './serde';
import { cmdKey } from './util'; import { cmdKey } from './util';
import mermaid from 'mermaid'; import { parse, init } from './mermaid';
import type { Readable } from 'svelte/store'; import type { Readable } from 'svelte/store';
import type { MarkerData, State, ValidatedState } from '$lib/types'; import type { MarkerData, State, ValidatedState } from '$lib/types';
void init();
export const defaultState: State = { export const defaultState: State = {
code: `graph TD code: `graph TD
A[Christmas] -->|Get money| B(Go shopping) A[Christmas] -->|Get money| B(Go shopping)
@@ -54,7 +56,7 @@ export const stateStore: Readable<ValidatedState> = derived([inputStateStore], (
// No changes should be done to fields part of `state`. // No changes should be done to fields part of `state`.
try { try {
processed.serialized = serializeState(state); processed.serialized = serializeState(state);
mermaid.parse(state.code); // await parse(state.code);
JSON.parse(state.mermaid); JSON.parse(state.mermaid);
} catch (e) { } catch (e) {
processed.error = e; processed.error = e;
@@ -103,12 +105,11 @@ export const loadState = (data: string): void => {
state.mermaid = defaultState.mermaid; state.mermaid = defaultState.mermaid;
} }
} }
updateCodeStore({ ...state }); updateCodeStore(state);
}; };
export const updateCodeStore = (newState: Partial<State>): void => { export const updateCodeStore = (newState: Partial<State>): void => {
inputStateStore.update((state) => { inputStateStore.update((state) => {
// console.log({ newState, state });
return { ...state, ...newState }; return { ...state, ...newState };
}); });
}; };
@@ -164,7 +165,10 @@ export const toggleDarkTheme = (dark: boolean): void => {
let urlDebounce: number; let urlDebounce: number;
export const initURLSubscription = (): void => { export const initURLSubscription = (): void => {
stateStore.subscribe(({ serialized }) => { stateStore.subscribe(({ serialized }: ValidatedState) => {
if (serialized.length < 5) {
return;
}
clearTimeout(urlDebounce); clearTimeout(urlDebounce);
urlDebounce = window.setTimeout(() => { urlDebounce = window.setTimeout(() => {
history.replaceState(undefined, undefined, `#${serialized}`); history.replaceState(undefined, undefined, `#${serialized}`);
+42 -23
View File
@@ -375,6 +375,11 @@
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc" resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc"
integrity sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig== integrity sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==
"@types/async@^3.2.15":
version "3.2.15"
resolved "https://registry.yarnpkg.com/@types/async/-/async-3.2.15.tgz#26d4768fdda0e466f18d6c9918ca28cc89a4e1fe"
integrity sha512-PAmPfzvFA31mRoqZyTVsgJMsvbynR429UTTxhmfsUCrWGh3/fxOrzqBtaTPJsn4UtzTv4Vb0+/O7CARWb69N4g==
"@types/chai-subset@^1.3.3": "@types/chai-subset@^1.3.3":
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/@types/chai-subset/-/chai-subset-1.3.3.tgz#97893814e92abd2c534de422cb377e0e0bdaac94" resolved "https://registry.yarnpkg.com/@types/chai-subset/-/chai-subset-1.3.3.tgz#97893814e92abd2c534de422cb377e0e0bdaac94"
@@ -410,11 +415,6 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
"@types/mermaid@9.1.0":
version "9.1.0"
resolved "https://registry.yarnpkg.com/@types/mermaid/-/mermaid-9.1.0.tgz#e9ba511d8a6793749d6be84f86325f0f58553154"
integrity sha512-rc8QqhveKAY7PouzY/p8ljS+eBSNCv7o79L97RSub/Ic2SQ34ph1Ng3s8wFLWVjvaEt6RLOWtSCsgYWd95NY8A==
"@types/node@*": "@types/node@*":
version "15.0.2" version "15.0.2"
resolved "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz" resolved "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz"
@@ -851,6 +851,11 @@ async@^3.2.0:
resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9" resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g== integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
async@^3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
asynckit@^0.4.0: asynckit@^0.4.0:
version "0.4.0" version "0.4.0"
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
@@ -1031,9 +1036,9 @@ caniuse-api@^3.0.0:
lodash.uniq "^4.5.0" lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001407: caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001407:
version "1.0.30001420" version "1.0.30001421"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001420.tgz" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001421.tgz"
integrity sha512-OnyeJ9ascFA9roEj72ok2Ikp7PHJTKubtEJIQ/VK3fdsS50q4KWy+Z5X0A1/GswEItKX0ctAp8n4SYDE7wTu6A== integrity sha512-Sw4eLbgUJAEhjLs1Fa+mk45sidp1wRn5y6GtDpHGBaNJ9OCDJaVh2tIaWWUnGfuXfKf1JCBaIarak3FkVAvEeA==
caseless@~0.12.0: caseless@~0.12.0:
version "0.12.0" version "0.12.0"
@@ -2740,6 +2745,11 @@ extsprintf@^1.2.0:
resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz" resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz"
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
fast-clone@^1.5.13:
version "1.5.13"
resolved "https://registry.yarnpkg.com/fast-clone/-/fast-clone-1.5.13.tgz#7fe17542ae1c872e71bf80d177d00c11f51c2ea7"
integrity sha512-0ez7coyFBQFjZtId+RJqJ+EQs61w9xARfqjqK0AD9vIUkSxWD4HvPt80+5evebZ1tTnv1GYKrPTipx7kOW5ipA==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3" version "3.1.3"
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
@@ -3672,20 +3682,24 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
mermaid@9.1.7: mermaid@9.2.0-rc6:
version "9.1.7" version "9.2.0-rc6"
resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-9.1.7.tgz#e24de9b2d36c8cb25a09d72ffce966941b24bd6e" resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-9.2.0-rc6.tgz#8c8ab4403c5bb9eca73cb8f1aba6fbd00fd8ede9"
integrity sha512-MRVHXy5FLjnUQUG7YS3UN9jEN6FXCJbFCXVGJQjVIbiR6Vhw0j/6pLIjqsiah9xoHmQU6DEaKOvB3S1g/1nBPA== integrity sha512-zrbaufHxlWs/i81BZePSh3PtQ/FpS3koY3cX9MS2bclchLqXrzO6wJ5S31Tl95j+7fMzV02HFu3sexSRfJOkhQ==
dependencies: dependencies:
"@braintree/sanitize-url" "^6.0.0" "@braintree/sanitize-url" "^6.0.0"
d3 "^7.0.0" d3 "^7.0.0"
dagre "^0.8.5" dagre "^0.8.5"
dagre-d3 "^0.6.4" dagre-d3 "^0.6.4"
dompurify "2.4.0" dompurify "2.4.0"
fast-clone "^1.5.13"
graphlib "^2.1.8" graphlib "^2.1.8"
khroma "^2.0.0" khroma "^2.0.0"
moment-mini "2.24.0" lodash "^4.17.21"
stylis "^4.0.10" moment-mini "^2.24.0"
non-layered-tidy-tree-layout "^2.0.2"
stylis "^4.1.2"
uuid "^9.0.0"
micromatch@^4.0.4, micromatch@^4.0.5: micromatch@^4.0.4, micromatch@^4.0.5:
version "4.0.5" version "4.0.5"
@@ -3746,10 +3760,10 @@ mkdirp@^0.5.1, mkdirp@~0.5.1:
dependencies: dependencies:
minimist "^1.2.5" minimist "^1.2.5"
moment-mini@2.24.0: moment-mini@^2.24.0:
version "2.24.0" version "2.29.4"
resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.24.0.tgz#fa68d98f7fe93ae65bf1262f6abb5fb6983d8d18" resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.29.4.tgz#cbbcdc58ce1b267506f28ea6668dbe060a32758f"
integrity sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ== integrity sha512-uhXpYwHFeiTbY9KSgPPRoo1nt8OxNVdMVoTBYHfSEKeRkIkwGpO+gERmhuhBtzfaeOyTkykSrm2+noJBgqt3Hg==
moment@2.29.4: moment@2.29.4:
version "2.29.4" version "2.29.4"
@@ -3819,6 +3833,11 @@ node-releases@^2.0.6:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503"
integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==
non-layered-tidy-tree-layout@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz#57d35d13c356643fc296a55fb11ac15e74da7804"
integrity sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==
nopt@~4.0.1: nopt@~4.0.1:
version "4.0.3" version "4.0.3"
resolved "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz" resolved "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz"
@@ -4913,10 +4932,10 @@ stylehacks@^5.1.0:
browserslist "^4.16.6" browserslist "^4.16.6"
postcss-selector-parser "^6.0.4" postcss-selector-parser "^6.0.4"
stylis@^4.0.10: stylis@^4.1.2:
version "4.0.10" version "4.1.2"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240" resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.2.tgz#870b3c1c2275f51b702bb3da9e94eedad87bba41"
integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg== integrity sha512-Nn2CCrG2ZaFziDxaZPN43CXqn+j7tcdjPFCkRBkFue8QYXC2HdEwnw5TCBo4yQZ2WxKYeSi0fdoOrtEqgDrXbA==
supports-color@^2.0.0: supports-color@^2.0.0:
version "2.0.0" version "2.0.0"
@@ -5239,7 +5258,7 @@ util-deprecate@^1.0.2:
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
uuid@9.0.0: uuid@9.0.0, uuid@^9.0.0:
version "9.0.0" version "9.0.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==