mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
commit
ffcb73ad5f
@ -73,6 +73,7 @@
|
||||
"fast-clone": "^1.5.13",
|
||||
"graphlib": "^2.1.8",
|
||||
"khroma": "^2.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"moment-mini": "^2.24.0",
|
||||
"non-layered-tidy-tree-layout": "^2.0.2",
|
||||
"stylis": "^4.0.10"
|
||||
@ -88,6 +89,7 @@
|
||||
"@types/d3": "^7.4.0",
|
||||
"@types/dompurify": "^2.3.4",
|
||||
"@types/jest": "^28.1.7",
|
||||
"@types/lodash": "^4.14.184",
|
||||
"@types/stylis": "^4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
||||
"@typescript-eslint/parser": "^5.36.1",
|
||||
|
@ -2,6 +2,7 @@ import utils from './utils';
|
||||
import assignWithDepth from './assignWithDepth';
|
||||
import { detectType } from './diagram-api/detectType';
|
||||
import { addDiagrams } from './diagram-api/diagram-orchestration';
|
||||
import memoize from 'lodash/memoize';
|
||||
addDiagrams();
|
||||
|
||||
describe('when assignWithDepth: should merge objects within objects', function () {
|
||||
@ -121,20 +122,30 @@ describe('when assignWithDepth: should merge objects within objects', function (
|
||||
});
|
||||
describe('when memoizing', function () {
|
||||
it('should return the same value', function () {
|
||||
const fib = utils.memoize(function (n, canary) {
|
||||
canary.flag = true;
|
||||
if (n < 2) {
|
||||
return 1;
|
||||
} else {
|
||||
//We'll console.log a loader every time we have to recurse
|
||||
return fib(n - 2, canary) + fib(n - 1, canary);
|
||||
}
|
||||
});
|
||||
const fib = memoize(
|
||||
function (n, x, canary) {
|
||||
canary.flag = true;
|
||||
if (n < 2) {
|
||||
return 1;
|
||||
} else {
|
||||
//We'll console.log a loader every time we have to recurse
|
||||
return fib(n - 2, x, canary) + fib(n - 1, x, canary);
|
||||
}
|
||||
},
|
||||
(n, x, _) => `${n}${x}`
|
||||
);
|
||||
let canary = { flag: false };
|
||||
fib(10, canary);
|
||||
fib(10, 'a', canary);
|
||||
expect(canary.flag).toBe(true);
|
||||
canary = { flag: false };
|
||||
fib(10, canary);
|
||||
fib(10, 'a', canary);
|
||||
expect(canary.flag).toBe(false);
|
||||
fib(10, 'b', canary);
|
||||
fib(10, 'b', canary);
|
||||
expect(canary.flag).toBe(true);
|
||||
canary = { flag: false };
|
||||
fib(10, 'b', canary);
|
||||
fib(10, 'a', canary);
|
||||
expect(canary.flag).toBe(false);
|
||||
});
|
||||
});
|
||||
|
54
src/utils.ts
54
src/utils.ts
@ -20,6 +20,7 @@ import { log } from './logger';
|
||||
import { detectType } from './diagram-api/detectType';
|
||||
import assignWithDepth from './assignWithDepth';
|
||||
import { MermaidConfig } from './config.type';
|
||||
import memoize from 'lodash/memoize';
|
||||
|
||||
// Effectively an enum of the supported curve types, accessible by name
|
||||
const d3CurveTypes = {
|
||||
@ -43,9 +44,10 @@ const anyComment = /\s*%%.*\n/gm;
|
||||
|
||||
/**
|
||||
* @function detectInit Detects the init config object from the text
|
||||
*
|
||||
* @param config
|
||||
*
|
||||
* ```mermaid
|
||||
*
|
||||
* %%{init: {"theme": "debug", "logLevel": 1 }}%%
|
||||
* graph LR
|
||||
* a-->b
|
||||
@ -165,27 +167,6 @@ export const detectDirective = function (text, type = null) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Caches results of functions based on input
|
||||
*
|
||||
* @param {Function} fn Function to run
|
||||
* @param {Function} resolver Function that resolves to an ID given arguments the `fn` takes
|
||||
* @returns {Function} An optimized caching function
|
||||
*/
|
||||
const memoize = (fn, resolver) => {
|
||||
let cache = {};
|
||||
return (...args) => {
|
||||
let n = resolver ? resolver.apply(this, args) : args[0];
|
||||
if (n in cache) {
|
||||
return cache[n];
|
||||
} else {
|
||||
let result = fn(...args);
|
||||
cache[n] = result;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @function isSubstringInArray Detects whether a substring in present in a given array
|
||||
* @param {string} str The substring to detect
|
||||
@ -594,7 +575,7 @@ export const wrapLabel = memoize(
|
||||
return completedLines.filter((line) => line !== '').join(config.joinWith);
|
||||
},
|
||||
(label, maxWidth, config) =>
|
||||
`${label}-${maxWidth}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}-${config.joinWith}`
|
||||
`${label}${maxWidth}${config.fontSize}${config.fontWeight}${config.fontFamily}${config.joinWith}`
|
||||
);
|
||||
|
||||
const breakString = memoize(
|
||||
@ -622,7 +603,7 @@ const breakString = memoize(
|
||||
return { hyphenatedStrings: lines, remainingWord: currentLine };
|
||||
},
|
||||
(word, maxWidth, hyphenCharacter = '-', config) =>
|
||||
`${word}-${maxWidth}-${hyphenCharacter}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}`
|
||||
`${word}${maxWidth}${hyphenCharacter}${config.fontSize}${config.fontWeight}${config.fontFamily}`
|
||||
);
|
||||
|
||||
/**
|
||||
@ -632,7 +613,8 @@ const breakString = memoize(
|
||||
* If the wrapped text text has greater height, we extend the height, so it's value won't overflow.
|
||||
*
|
||||
* @param {any} text The text to measure
|
||||
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the resulting size
|
||||
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the
|
||||
* resulting size
|
||||
* @returns {any} - The height for the given text
|
||||
*/
|
||||
export const calculateTextHeight = function (text, config) {
|
||||
@ -647,7 +629,8 @@ export const calculateTextHeight = function (text, config) {
|
||||
* This calculates the width of the given text, font size and family.
|
||||
*
|
||||
* @param {any} text - The text to calculate the width of
|
||||
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the resulting size
|
||||
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the
|
||||
* resulting size
|
||||
* @returns {any} - The width for the given text
|
||||
*/
|
||||
export const calculateTextWidth = function (text, config) {
|
||||
@ -656,7 +639,8 @@ export const calculateTextWidth = function (text, config) {
|
||||
};
|
||||
|
||||
/**
|
||||
* This calculates the dimensions of the given text, font size, font family, font weight, and margins.
|
||||
* This calculates the dimensions of the given text, font size, font family, font weight, and
|
||||
* margins.
|
||||
*
|
||||
* @param {any} text - The text to calculate the width of
|
||||
* @param {any} config - The config for fontSize, fontFamily, fontWeight, and margin all impacting
|
||||
@ -720,14 +704,15 @@ export const calculateTextDimensions = memoize(
|
||||
: 1;
|
||||
return dims[index];
|
||||
},
|
||||
(text, config) => `${text}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}`
|
||||
(text, config) => `${text}${config.fontSize}${config.fontWeight}${config.fontFamily}`
|
||||
);
|
||||
|
||||
/**
|
||||
* Applys d3 attributes
|
||||
*
|
||||
* @param {any} d3Elem D3 Element to apply the attributes onto
|
||||
* @param {[string, string][]} attrs Object.keys equivalent format of key to value mapping of attributes
|
||||
* @param {[string, string][]} attrs Object.keys equivalent format of key to value mapping of
|
||||
* attributes
|
||||
*/
|
||||
const d3Attrs = function (d3Elem, attrs) {
|
||||
for (let attr of attrs) {
|
||||
@ -860,18 +845,12 @@ export interface DetailedError {
|
||||
hash: any;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param error
|
||||
*/
|
||||
/** @param error */
|
||||
export function isDetailedError(error: unknown): error is DetailedError {
|
||||
return 'str' in error;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param error
|
||||
*/
|
||||
/** @param error */
|
||||
export function getErrorMessage(error: unknown): string {
|
||||
if (error instanceof Error) return error.message;
|
||||
return String(error);
|
||||
@ -894,7 +873,6 @@ export default {
|
||||
getStylesFromArray,
|
||||
generateId,
|
||||
random,
|
||||
memoize,
|
||||
runFunc,
|
||||
entityDecode,
|
||||
initIdGenerator: initIdGenerator,
|
||||
|
@ -2643,6 +2643,11 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/lodash@^4.14.184":
|
||||
version "4.14.184"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.184.tgz#23f96cd2a21a28e106dc24d825d4aa966de7a9fe"
|
||||
integrity sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q==
|
||||
|
||||
"@types/mdast@^3.0.0":
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af"
|
||||
|
Loading…
x
Reference in New Issue
Block a user