Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: move from objects to Maps #5468

Merged
merged 20 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 16 additions & 16 deletions docs/config/setup/modules/mermaidAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ mermaid.initialize(config);

#### Defined in

[mermaidAPI.ts:635](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L635)
[mermaidAPI.ts:634](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L634)

## Functions

Expand Down Expand Up @@ -129,7 +129,7 @@ Return the last node appended

#### Defined in

[mermaidAPI.ts:277](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L277)
[mermaidAPI.ts:276](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L276)

---

Expand All @@ -155,7 +155,7 @@ the cleaned up svgCode

#### Defined in

[mermaidAPI.ts:223](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L223)
[mermaidAPI.ts:222](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L222)

---

Expand All @@ -167,10 +167,10 @@ Create the user styles

#### Parameters

| Name | Type | Description |
| :---------- | :------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------ |
| `config` | `MermaidConfig` | configuration that has style and theme settings to use |
| `classDefs` | `undefined` \| `null` \| `Record`<`string`, `DiagramStyleClassDef`> | the classDefs in the diagram text. Might be null if none were defined. Usually is the result of a call to getClasses(...) |
| Name | Type | Description |
| :---------- | :--------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------ |
| `config` | `MermaidConfig` | configuration that has style and theme settings to use |
| `classDefs` | `undefined` \| `null` \| `Map`<`string`, `DiagramStyleClassDef`> | the classDefs in the diagram text. Might be null if none were defined. Usually is the result of a call to getClasses(...) |

#### Returns

Expand All @@ -190,20 +190,20 @@ the string with all the user styles

#### Parameters

| Name | Type |
| :---------- | :-------------------------------------------------------- |
| `config` | `MermaidConfig` |
| `graphType` | `string` |
| `classDefs` | `undefined` \| `Record`<`string`, `DiagramStyleClassDef`> |
| `svgId` | `string` |
| Name | Type |
| :---------- | :----------------------------------------------------- |
| `config` | `MermaidConfig` |
| `graphType` | `string` |
| `classDefs` | `undefined` \| `Map`<`string`, `DiagramStyleClassDef`> |
| `svgId` | `string` |

#### Returns

`string`

#### Defined in

[mermaidAPI.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L200)
[mermaidAPI.ts:199](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L199)

---

Expand Down Expand Up @@ -256,7 +256,7 @@ Put the svgCode into an iFrame. Return the iFrame code

#### Defined in

[mermaidAPI.ts:254](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L254)
[mermaidAPI.ts:253](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L253)

---

Expand All @@ -281,4 +281,4 @@ Remove any existing elements from the given document

#### Defined in

[mermaidAPI.ts:327](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L327)
[mermaidAPI.ts:326](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L326)
6 changes: 3 additions & 3 deletions packages/mermaid-flowchart-elk/src/flowRenderer-elk.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@
export const addVertices = async function (vert, svgId, root, doc, diagObj, parentLookupDb, graph) {
const svg = root.select(`[id="${svgId}"]`);
const nodes = svg.insert('g').attr('class', 'nodes');
const keys = Object.keys(vert);
const keys = [...vert.keys()];

// Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
await Promise.all(
keys.map(async function (id) {
const vertex = vert[id];
const vertex = vert.get(id);

/**
* Variable for storing the classes for the vertex
Expand All @@ -64,7 +64,7 @@
let vertexText = vertex.text !== undefined ? vertex.text : vertex.id;

// We create a SVG label, either by delegating to addHtmlLabel or manually
let vertexNode;

Check warning on line 67 in packages/mermaid-flowchart-elk/src/flowRenderer-elk.js

View workflow job for this annotation

GitHub Actions / lint

'vertexNode' is defined but never used

Check warning on line 67 in packages/mermaid-flowchart-elk/src/flowRenderer-elk.js

View workflow job for this annotation

GitHub Actions / lint

'vertexNode' is defined but never used
const labelData = { width: 0, height: 0 };

const ports = [
Expand Down Expand Up @@ -188,7 +188,7 @@
nodeEl = await insertNode(nodes, node, vertex.dir);
boundingBox = nodeEl.node().getBBox();
} else {
const svgLabel = doc.createElementNS('http://www.w3.org/2000/svg', 'text');

Check warning on line 191 in packages/mermaid-flowchart-elk/src/flowRenderer-elk.js

View workflow job for this annotation

GitHub Actions / lint

'svgLabel' is assigned a value but never used

Check warning on line 191 in packages/mermaid-flowchart-elk/src/flowRenderer-elk.js

View workflow job for this annotation

GitHub Actions / lint

'svgLabel' is assigned a value but never used
// svgLabel.setAttribute('style', styles.labelStyle.replace('color:', 'fill:'));
// const rows = vertexText.split(common.lineBreakRegex);
// for (const row of rows) {
Expand Down Expand Up @@ -394,7 +394,7 @@
* Add edges to graph based on parsed graph definition
*
* @param {object} edges The edges to add to the graph
* @param {object} g The graph object

Check warning on line 397 in packages/mermaid-flowchart-elk/src/flowRenderer-elk.js

View workflow job for this annotation

GitHub Actions / lint

Expected @param names to be "edges, diagObj, graph, svg". Got "edges, g, cy, diagObj, graph, svg"

Check warning on line 397 in packages/mermaid-flowchart-elk/src/flowRenderer-elk.js

View workflow job for this annotation

GitHub Actions / lint

Expected @param names to be "edges, diagObj, graph, svg". Got "edges, g, cy, diagObj, graph, svg"
* @param cy
* @param diagObj
* @param graph
Expand Down Expand Up @@ -595,7 +595,7 @@
*
* @param text
* @param diagObj
* @returns {Record<string, import('../../mermaid/src/diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles
* @returns {Map<string, import('../../mermaid/src/diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles
*/
export const getClasses = function (text, diagObj) {
log.info('Extracting classes');
Expand Down Expand Up @@ -677,7 +677,7 @@
/**
* Recursive function that iterates over an array of nodes and inserts the children of each node.
* It also recursively populates the inserts the children of the children and so on.
* @param {*} graph

Check warning on line 680 in packages/mermaid-flowchart-elk/src/flowRenderer-elk.js

View workflow job for this annotation

GitHub Actions / lint

Expected @param names to be "nodeArray, parentLookupDb". Got "graph, nodeArray, parentLookupDb"

Check warning on line 680 in packages/mermaid-flowchart-elk/src/flowRenderer-elk.js

View workflow job for this annotation

GitHub Actions / lint

Expected @param names to be "nodeArray, parentLookupDb". Got "graph, nodeArray, parentLookupDb"
* @param nodeArray
* @param parentLookupDb
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/diagram-api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export interface DiagramRenderer {
getClasses?: (
text: string,
diagram: Pick<DiagramDefinition, 'db'>
) => Record<string, DiagramStyleClassDef>;
) => Map<string, DiagramStyleClassDef>;
}

export interface DiagramDefinition {
Expand Down
59 changes: 29 additions & 30 deletions packages/mermaid/src/diagrams/block/blockDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import { clear as commonClear } from '../common/commonDb.js';
import type { Block, ClassDef } from './blockTypes.js';

// Initialize the node database for simple lookups
let blockDatabase: Record<string, Block> = {};
let blockDatabase: Map<string, Block> = new Map();
let edgeList: Block[] = [];
let edgeCount: Record<string, number> = {};
let edgeCount: Map<string, number> = new Map();

const COLOR_KEYWORD = 'color';
const FILL_KEYWORD = 'fill';
const BG_FILL = 'bgFill';
const STYLECLASS_SEP = ',';

let classes = {} as Record<string, ClassDef>;
let classes: Map<string, ClassDef> = new Map();

/**
* Called when the parser comes across a (style) class definition
Expand All @@ -26,10 +26,11 @@ let classes = {} as Record<string, ClassDef>;
*/
export const addStyleClass = function (id: string, styleAttributes = '') {
// create a new style class object with this id
if (classes[id] === undefined) {
classes[id] = { id: id, styles: [], textStyles: [] }; // This is a classDef
let foundClass = classes.get(id);
if (!foundClass) {
foundClass = { id: id, styles: [], textStyles: [] };
classes.set(id, foundClass); // This is a classDef
}
const foundClass = classes[id];
if (styleAttributes !== undefined && styleAttributes !== null) {
styleAttributes.split(STYLECLASS_SEP).forEach((attrib) => {
// remove any trailing ;
Expand All @@ -54,7 +55,7 @@ export const addStyleClass = function (id: string, styleAttributes = '') {
* @param styles - the string with 1 or more style attributes (each separated by a comma)
*/
export const addStyle2Node = function (id: string, styles = '') {
const foundBlock = blockDatabase[id];
const foundBlock = blockDatabase.get(id)!;
if (styles !== undefined && styles !== null) {
foundBlock.styles = styles.split(STYLECLASS_SEP);
}
Expand All @@ -70,11 +71,11 @@ export const addStyle2Node = function (id: string, styles = '') {
*/
export const setCssClass = function (itemIds: string, cssClassName: string) {
itemIds.split(',').forEach(function (id: string) {
let foundBlock = blockDatabase[id];
let foundBlock = blockDatabase.get(id);
if (foundBlock === undefined) {
const trimmedId = id.trim();
blockDatabase[trimmedId] = { id: trimmedId, type: 'na', children: [] } as Block;
foundBlock = blockDatabase[trimmedId];
foundBlock = { id: trimmedId, type: 'na', children: [] } as Block;
blockDatabase.set(trimmedId, foundBlock);
}
if (!foundBlock.classes) {
foundBlock.classes = [];
Expand Down Expand Up @@ -104,12 +105,9 @@ const populateBlockDatabase = (_blockList: Block[] | Block[][], parent: Block):
if (block.type === 'column-setting') {
parent.columns = block.columns || -1;
} else if (block.type === 'edge') {
if (edgeCount[block.id]) {
edgeCount[block.id]++;
} else {
edgeCount[block.id] = 1;
}
block.id = edgeCount[block.id] + '-' + block.id;
const count = (edgeCount.get(block.id) ?? 0) + 1;
edgeCount.set(block.id, count);
block.id = count + '-' + block.id;
edgeList.push(block);
} else {
if (!block.label) {
Expand All @@ -120,16 +118,17 @@ const populateBlockDatabase = (_blockList: Block[] | Block[][], parent: Block):
block.label = block.id;
}
}
const newBlock = !blockDatabase[block.id];
if (newBlock) {
blockDatabase[block.id] = block;
const existingBlock = blockDatabase.get(block.id);

if (existingBlock === undefined) {
blockDatabase.set(block.id, block);
} else {
// Add newer relevant data to aggregated node
if (block.type !== 'na') {
blockDatabase[block.id].type = block.type;
existingBlock.type = block.type;
}
if (block.label !== block.id) {
blockDatabase[block.id].label = block.label;
existingBlock.label = block.label;
}
}

Expand All @@ -142,10 +141,10 @@ const populateBlockDatabase = (_blockList: Block[] | Block[][], parent: Block):
for (let j = 0; j < w; j++) {
const newBlock = clone(block);
newBlock.id = newBlock.id + '-' + j;
blockDatabase[newBlock.id] = newBlock;
blockDatabase.set(newBlock.id, newBlock);
children.push(newBlock);
}
} else if (newBlock) {
} else if (existingBlock === undefined) {
children.push(block);
}
}
Expand All @@ -160,12 +159,12 @@ const clear = (): void => {
log.debug('Clear called');
commonClear();
rootBlock = { id: 'root', type: 'composite', children: [], columns: -1 } as Block;
blockDatabase = { root: rootBlock };
blockDatabase = new Map([['root', rootBlock]]);
blocks = [] as Block[];
classes = {} as Record<string, ClassDef>;
classes = new Map();

edgeList = [];
edgeCount = {};
edgeCount = new Map();
};

export function typeStr2Type(typeStr: string) {
Expand Down Expand Up @@ -241,7 +240,7 @@ const setHierarchy = (block: Block[]): void => {
};

const getColumns = (blockId: string): number => {
const block = blockDatabase[blockId];
const block = blockDatabase.get(blockId);
if (!block) {
return -1;
}
Expand All @@ -259,7 +258,7 @@ const getColumns = (blockId: string): number => {
* @returns
*/
const getBlocksFlat = () => {
return [...Object.values(blockDatabase)];
return [...blockDatabase.values()];
};
/**
* Returns the hierarchy of blocks
Expand All @@ -273,11 +272,11 @@ const getEdges = () => {
return edgeList;
};
const getBlock = (id: string) => {
return blockDatabase[id];
return blockDatabase.get(id);
};

const setBlock = (block: Block) => {
blockDatabase[block.id] = block;
blockDatabase.set(block.id, block);
};

const getLogger = () => console;
Expand Down
19 changes: 18 additions & 1 deletion packages/mermaid/src/diagrams/block/parser/block.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ describe('Block diagram', function () {
const mc = blocks[0];
expect(mc.classes).toContain('black');
const classes = db.getClasses();
const black = classes.black;
const black = classes.get('black')!;
expect(black.id).toBe('black');
expect(black.styles[0]).toEqual('color:#ffffff');
});
Expand All @@ -406,4 +406,21 @@ columns 1
expect(B.styles).toContain('fill:#f9F');
});
});

describe('prototype properties', function () {
function validateProperty(prop: string) {
expect(() => block.parse(`block-beta\n${prop}`)).not.toThrow();
expect(() =>
block.parse(`block-beta\nA; classDef ${prop} color:#ffffff,fill:#000000; class A ${prop}`)
).not.toThrow();
}

it('should work with a __proto__ property', function () {
validateProperty('__proto__');
});

it('should work with a constructor property', function () {
validateProperty('constructor');
});
});
});