mermaid/src/diagrams/state/stateDb.js

282 lines
6.0 KiB
JavaScript
Raw Normal View History

2021-02-06 15:56:05 +05:30
import { log } from '../../logger';
import { generateId } from '../../utils';
import mermaidAPI from '../../mermaidAPI';
2021-09-29 08:45:07 +02:00
import common from '../common/common';
import * as configApi from '../../config';
2021-07-15 11:35:12 +02:00
const clone = (o) => JSON.parse(JSON.stringify(o));
let rootDoc = [];
2021-07-15 11:35:12 +02:00
export const parseDirective = function (statement, context, type) {
mermaidAPI.parseDirective(this, statement, context, type);
};
2021-07-15 11:35:12 +02:00
const setRootDoc = (o) => {
2021-02-06 15:56:05 +05:30
log.info('Setting root doc', o);
2020-03-30 22:08:48 +02:00
// rootDoc = { id: 'root', doc: o };
rootDoc = o;
};
const getRootDoc = () => rootDoc;
const docTranslator = (parent, node, first) => {
if (node.stmt === 'relation') {
docTranslator(parent, node.state1, true);
docTranslator(parent, node.state2, false);
} else {
if (node.stmt === 'state') {
if (node.id === '[*]') {
node.id = first ? parent.id + '_start' : parent.id + '_end';
node.start = first;
}
}
if (node.doc) {
const doc = [];
// Check for concurrency
let i = 0;
let currentDoc = [];
for (i = 0; i < node.doc.length; i++) {
if (node.doc[i].type === 'divider') {
// debugger;
const newNode = clone(node.doc[i]);
newNode.doc = clone(currentDoc);
doc.push(newNode);
currentDoc = [];
} else {
currentDoc.push(node.doc[i]);
}
}
// If any divider was encountered
if (doc.length > 0 && currentDoc.length > 0) {
const newNode = {
stmt: 'state',
id: generateId(),
type: 'divider',
2021-07-15 11:35:12 +02:00
doc: clone(currentDoc),
};
doc.push(clone(newNode));
node.doc = doc;
}
2021-07-15 11:35:12 +02:00
node.doc.forEach((docNode) => docTranslator(node, docNode, true));
}
}
};
const getRootDocV2 = () => {
2020-03-30 22:08:48 +02:00
docTranslator({ id: 'root' }, { id: 'root', doc: rootDoc }, true);
return { id: 'root', doc: rootDoc };
// Here
};
2021-07-15 11:35:12 +02:00
const extract = (_doc) => {
2019-10-27 15:24:56 +01:00
// const res = { states: [], relations: [] };
let doc;
if (_doc.doc) {
doc = _doc.doc;
} else {
doc = _doc;
}
2020-03-30 22:08:48 +02:00
// let doc = root.doc;
// if (!doc) {
// doc = root;
// }
2021-02-06 15:56:05 +05:30
log.info(doc);
clear();
2021-02-06 15:56:05 +05:30
log.info('Extract', doc);
2021-07-15 11:35:12 +02:00
doc.forEach((item) => {
if (item.stmt === 'state') {
2019-10-06 10:52:37 +02:00
addState(item.id, item.type, item.doc, item.description, item.note);
}
if (item.stmt === 'relation') {
addRelation(item.state1.id, item.state2.id, item.description);
}
});
};
const newDoc = () => {
return {
relations: [],
states: {},
2021-07-15 11:35:12 +02:00
documents: {},
};
};
let documents = {
2021-07-15 11:35:12 +02:00
root: newDoc(),
};
let currentDocument = documents.root;
2019-09-25 21:29:32 +02:00
let startCnt = 0;
2019-10-27 15:24:56 +01:00
let endCnt = 0; // eslint-disable-line
// let stateCnt = 0;
2019-09-25 21:29:32 +02:00
/**
* Function called by parser when a node definition has been found.
* @param id
* @param text
* @param type
* @param style
*/
2021-07-15 11:35:12 +02:00
export const addState = function (id, type, doc, descr, note) {
if (typeof currentDocument.states[id] === 'undefined') {
currentDocument.states[id] = {
id: id,
2019-09-25 21:29:32 +02:00
descriptions: [],
type,
2019-10-06 10:52:37 +02:00
doc,
2021-07-15 11:35:12 +02:00
note,
};
} else {
if (!currentDocument.states[id].doc) {
currentDocument.states[id].doc = doc;
}
if (!currentDocument.states[id].type) {
currentDocument.states[id].type = type;
}
}
if (descr) {
2021-02-06 15:56:05 +05:30
log.info('Adding state ', id, descr);
if (typeof descr === 'string') addDescription(id, descr.trim());
if (typeof descr === 'object') {
2021-07-15 11:35:12 +02:00
descr.forEach((des) => addDescription(id, des.trim()));
}
}
if (note) {
currentDocument.states[id].note = note;
currentDocument.states[id].note.text = common.sanitizeText(
currentDocument.states[id].note.text,
configApi.getConfig()
);
}
};
2021-07-15 11:35:12 +02:00
export const clear = function () {
documents = {
2021-07-15 11:35:12 +02:00
root: newDoc(),
};
currentDocument = documents.root;
2020-05-27 22:18:59 +02:00
currentDocument = documents.root;
startCnt = 0;
endCnt = 0; // eslint-disable-line
classes = [];
};
2021-07-15 11:35:12 +02:00
export const getState = function (id) {
return currentDocument.states[id];
};
2021-07-15 11:35:12 +02:00
export const getStates = function () {
return currentDocument.states;
};
2021-07-15 11:35:12 +02:00
export const logDocuments = function () {
2021-02-06 15:56:05 +05:30
log.info('Documents = ', documents);
};
2021-07-15 11:35:12 +02:00
export const getRelations = function () {
return currentDocument.relations;
};
2021-07-15 11:35:12 +02:00
export const addRelation = function (_id1, _id2, title) {
2019-09-25 21:29:32 +02:00
let id1 = _id1;
let id2 = _id2;
let type1 = 'default';
let type2 = 'default';
if (_id1 === '[*]') {
startCnt++;
id1 = 'start' + startCnt;
type1 = 'start';
}
if (_id2 === '[*]') {
endCnt++;
id2 = 'end' + startCnt;
type2 = 'end';
}
addState(id1, type1);
addState(id2, type2);
2021-09-29 09:35:14 +02:00
currentDocument.relations.push({
id1,
id2,
title: common.sanitizeText(title, configApi.getConfig()),
});
};
2021-07-15 11:35:12 +02:00
const addDescription = function (id, _descr) {
const theState = currentDocument.states[id];
2019-09-29 15:50:43 +02:00
let descr = _descr;
if (descr[0] === ':') {
descr = descr.substr(1).trim();
}
2021-09-29 09:35:14 +02:00
theState.descriptions.push(common.sanitizeText(descr, configApi.getConfig()));
};
2021-07-15 11:35:12 +02:00
export const cleanupLabel = function (label) {
if (label.substring(0, 1) === ':') {
return label.substr(2).trim();
} else {
return label.trim();
}
};
export const lineType = {
LINE: 0,
2021-07-15 11:35:12 +02:00
DOTTED_LINE: 1,
};
2019-10-06 15:44:31 +02:00
let dividerCnt = 0;
const getDividerId = () => {
dividerCnt++;
return 'divider-id-' + dividerCnt;
};
2020-05-27 22:18:59 +02:00
let classes = [];
const getClasses = () => classes;
let direction = 'TB';
const getDirection = () => direction;
2021-07-15 11:35:12 +02:00
const setDirection = (dir) => {
direction = dir;
};
export const relationType = {
AGGREGATION: 0,
EXTENSION: 1,
COMPOSITION: 2,
2021-07-15 11:35:12 +02:00
DEPENDENCY: 3,
};
2021-07-15 11:35:12 +02:00
const trimColon = (str) => (str && str[0] === ':' ? str.substr(1).trim() : str.trim());
export default {
parseDirective,
getConfig: () => configApi.getConfig().state,
2019-09-25 21:01:21 +02:00
addState,
clear,
2019-09-25 21:01:21 +02:00
getState,
2019-09-25 21:29:32 +02:00
getStates,
getRelations,
getClasses,
getDirection,
addRelation,
2019-10-06 15:44:31 +02:00
getDividerId,
setDirection,
2019-10-05 12:15:14 +02:00
// addDescription,
cleanupLabel,
lineType,
relationType,
logDocuments,
getRootDoc,
setRootDoc,
getRootDocV2,
extract,
2021-07-15 11:35:12 +02:00
trimColon,
};