chore: implemented new syntx

on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
This commit is contained in:
omkarht
2025-08-07 20:45:23 +05:30
parent 981829a426
commit 677ff82d13
4 changed files with 150 additions and 270 deletions

View File

@@ -12,7 +12,6 @@
%options case-insensitive %options case-insensitive
// Special states for recognizing aliases // Special states for recognizing aliases
// A special state for grabbing text up to the first comment/newline // A special state for grabbing text up to the first comment/newline
%x ID ALIAS LINE CONFIG CONFIG_DATA %x ID ALIAS LINE CONFIG CONFIG_DATA
@@ -22,92 +21,79 @@
%x acc_descr_multiline %x acc_descr_multiline
%% %%
[\n]+ { console.log("NEWLINE"); return 'NEWLINE'; } [\n]+ return 'NEWLINE';
\s+ { console.log("WHITESPACE"); /* skip whitespace */ } \s+ /* skip all whitespace */
<ID,ALIAS,LINE>((?!\n)\s)+ { console.log("SAME-LINE-WHITESPACE"); /* skip same-line whitespace */ } <ID,ALIAS,LINE>((?!\n)\s)+ /* skip same-line whitespace */
<INITIAL,ID,ALIAS,LINE>\#[^\n]* { console.log("COMMENT"); /* skip comments */ } <INITIAL,ID,ALIAS,LINE>\#[^\n]* /* skip comments */
\%%(?!\{)[^\n]* { console.log("COMMENT"); /* skip comments */ } \%%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* { console.log("COMMENT"); /* skip comments */ } [^\}]\%\%[^\n]* /* skip comments */
[0-9]+(?=[ \n]+) { console.log("NUM:", yytext); return 'NUM'; } [0-9]+(?=[ \n]+) return 'NUM';
// Enhanced config handling rules - moved before other ID rules for proper precedence <ID>\@\{ { this.begin('CONFIG'); return 'CONFIG_START'; }
<ID>\@\{ { console.log("CONFIG_START"); this.begin('CONFIG'); return 'CONFIG_START'; } <CONFIG>[^\}]+ { return 'CONFIG_CONTENT'; }
<CONFIG>[^\}]+ { console.log("CONFIG_CONTENT:", yytext); return 'CONFIG_CONTENT'; } <CONFIG>\} { this.popState(); this.popState(); return 'CONFIG_END'; }
<CONFIG>\} { console.log("CONFIG_END"); this.popState(); this.popState(); return 'CONFIG_END'; } <ID>[^\<->\->:\n,;@]+?([\-]*[^\<->\->:\n,;@]+?)*?(?=\@\{) { yytext = yytext.trim(); return 'ACTOR'; }
// ACTOR_WITH_CONFIG rule must come before general ACTOR rule for proper precedence <ID>[^\<->\->:\n,;@]+?([\-]*[^\<->\->:\n,;@]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
<ID>[^\<->\->:\n,;@]+?([\-]*[^\<->\->:\n,;@]+?)*?(?=\@\{) { console.log("LEXER:ACTOR_WITH_CONFIG_OBJECT:", yytext); yytext = yytext.trim(); return 'ACTOR_WITH_CONFIG'; } "box" { this.begin('LINE'); return 'box'; }
// General ACTOR rule - now comes after the more specific ACTOR_WITH_CONFIG rule "participant" { this.begin('ID'); return 'participant'; }
<ID>[^\<->\->:\n,;@]+?([\-]*[^\<->\->:\n,;@]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { console.log("ACTOR:", yytext); yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; } "actor" { this.begin('ID'); return 'participant_actor'; }
"box" { console.log("BOX"); this.begin('LINE'); return 'box'; } "create" return 'create';
"participant" { console.log("PARTICIPANT"); this.begin('ID'); return 'participant'; } "destroy" { this.begin('ID'); return 'destroy'; }
"actor" { console.log("ACTOR_TYPE_ACTOR"); this.begin('ID'); return 'participant_actor'; } <ALIAS>"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; }
"boundary" { return yy.matchAsActorOrParticipant('boundary', 'participant_boundary', this._input, this); } <ALIAS>(?:) { this.popState(); this.popState(); return 'NEWLINE'; }
"control" { return yy.matchAsActorOrParticipant('control', 'participant_control', this._input, this); } "loop" { this.begin('LINE'); return 'loop'; }
"entity" { return yy.matchAsActorOrParticipant('entity', 'participant_entity', this._input, this); } "rect" { this.begin('LINE'); return 'rect'; }
"database" { return yy.matchAsActorOrParticipant('database', 'participant_database', this._input, this); } "opt" { this.begin('LINE'); return 'opt'; }
"collections" { return yy.matchAsActorOrParticipant('collections', 'participant_collections', this._input, this); } "alt" { this.begin('LINE'); return 'alt'; }
"queue" { return yy.matchAsActorOrParticipant('queue', 'participant_queue', this._input, this); } "else" { this.begin('LINE'); return 'else'; }
"create" { console.log("CREATE"); return 'create'; } "par" { this.begin('LINE'); return 'par'; }
"destroy" { console.log("DESTROY"); this.begin('ID'); return 'destroy'; } "par_over" { this.begin('LINE'); return 'par_over'; }
<ALIAS>"as" { console.log("AS"); this.popState(); this.popState(); this.begin('LINE'); return 'AS'; } "and" { this.begin('LINE'); return 'and'; }
<ALIAS>(?:) { console.log("ALIAS_END"); this.popState(); this.popState(); return 'NEWLINE'; } "critical" { this.begin('LINE'); return 'critical'; }
// // Enhanced config handling rules "option" { this.begin('LINE'); return 'option'; }
// <ID>\@\{ { console.log("CONFIG_START"); this.begin('CONFIG'); return 'CONFIG_START'; } "break" { this.begin('LINE'); return 'break'; }
// <CONFIG>[^\}]+ { console.log("CONFIG_CONTENT:", yytext); return 'CONFIG_CONTENT'; } <LINE>(?:[:]?(?:no)?wrap:)?[^#\n;]* { this.popState(); return 'restOfLine'; }
// <CONFIG>\} { console.log("CONFIG_END"); this.popState(); return 'CONFIG_END'; } "end" return 'end';
"loop" { console.log("LOOP"); this.begin('LINE'); return 'loop'; } "left of" return 'left_of';
"rect" { console.log("RECT"); this.begin('LINE'); return 'rect'; } "right of" return 'right_of';
"opt" { console.log("OPT"); this.begin('LINE'); return 'opt'; } "links" return 'links';
"alt" { console.log("ALT"); this.begin('LINE'); return 'alt'; } "link" return 'link';
"else" { console.log("ELSE"); this.begin('LINE'); return 'else'; } "properties" return 'properties';
"par" { console.log("PAR"); this.begin('LINE'); return 'par'; } "details" return 'details';
"par_over" { console.log("PAR_OVER"); this.begin('LINE'); return 'par_over'; } "over" return 'over';
"and" { console.log("AND"); this.begin('LINE'); return 'and'; } "note" return 'note';
"critical" { console.log("CRITICAL"); this.begin('LINE'); return 'critical'; } "activate" { this.begin('ID'); return 'activate'; }
"option" { console.log("OPTION"); this.begin('LINE'); return 'option'; } "deactivate" { this.begin('ID'); return 'deactivate'; }
"break" { console.log("BREAK"); this.begin('LINE'); return 'break'; } "title"\s[^#\n;]+ return 'title';
<LINE>(?:[:]?(?:no)?wrap:)?[^#\n;]* { console.log("REST_OF_LINE:", yytext); this.popState(); return 'restOfLine'; } "title:"\s[^#\n;]+ return 'legacy_title';
"end" { console.log("END"); return 'end'; } accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
"left of" { console.log("LEFT_OF"); return 'left_of'; } <acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
"right of" { console.log("RIGHT_OF"); return 'right_of'; } accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
"links" { console.log("LINKS"); return 'links'; } <acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
"link" { console.log("LINK"); return 'link'; } accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
"properties" { console.log("PROPERTIES"); return 'properties'; } <acc_descr_multiline>[\}] { this.popState(); }
"details" { console.log("DETAILS"); return 'details'; } <acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
"over" { console.log("OVER"); return 'over'; } "sequenceDiagram" return 'SD';
"note" { console.log("NOTE"); return 'note'; } "autonumber" return 'autonumber';
"activate" { console.log("ACTIVATE"); this.begin('ID'); return 'activate'; } "off" return 'off';
"deactivate" { console.log("DEACTIVATE"); this.begin('ID'); return 'deactivate'; } "," return ',';
"title"\s[^#\n;]+ { console.log("TITLE"); return 'title'; } ";" return 'NEWLINE';
"title:"\s[^#\n;]+ { console.log("LEGACY_TITLE"); return 'legacy_title'; } [^\+\<->\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+\<->\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; }
accTitle\s*":"\s* { console.log("ACC_TITLE"); this.begin("acc_title"); return 'acc_title'; } "->>" return 'SOLID_ARROW';
<acc_title>(?!\n|;|#)*[^\n]* { console.log("ACC_TITLE_VALUE:", yytext); this.popState(); return "acc_title_value"; } "<<->>" return 'BIDIRECTIONAL_SOLID_ARROW';
accDescr\s*":"\s* { console.log("ACC_DESCR"); this.begin("acc_descr"); return 'acc_descr'; } "-->>" return 'DOTTED_ARROW';
<acc_descr>(?!\n|;|#)*[^\n]* { console.log("ACC_DESCR_VALUE:", yytext); this.popState(); return "acc_descr_value"; } "<<-->>" return 'BIDIRECTIONAL_DOTTED_ARROW';
accDescr\s*"{"\s* { console.log("ACC_DESCR_MULTILINE_START"); this.begin("acc_descr_multiline"); } "->" return 'SOLID_OPEN_ARROW';
<acc_descr_multiline>[\}] { console.log("ACC_DESCR_MULTILINE_END"); this.popState(); } "-->" return 'DOTTED_OPEN_ARROW';
<acc_descr_multiline>[^\}]* { console.log("ACC_DESCR_MULTILINE_VALUE:", yytext); return "acc_descr_multiline_value"; } \-[x] return 'SOLID_CROSS';
"sequenceDiagram" { console.log("SEQUENCE_DIAGRAM"); return 'SD'; } \-\-[x] return 'DOTTED_CROSS';
"autonumber" { console.log("AUTONUMBER"); return 'autonumber'; } \-[\)] return 'SOLID_POINT';
"off" { console.log("OFF"); return 'off'; } \-\-[\)] return 'DOTTED_POINT';
"," { console.log("COMMA"); return ','; } ":"(?:(?:no)?wrap:)?[^#\n;]* return 'TXT';
";" { console.log("SEMICOLON"); return 'NEWLINE'; } ":" return 'TXT';
[^\+\<->\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+\<->\->:\n,;]+)* { console.log("ACTOR_GENERIC:", yytext); yytext = yytext.trim(); return 'ACTOR'; } "+" return '+';
"->>" { console.log("SOLID_ARROW"); return 'SOLID_ARROW'; } "-" return '-';
"<<->>" { console.log("BIDIRECTIONAL_SOLID_ARROW"); return 'BIDIRECTIONAL_SOLID_ARROW'; } <<EOF>> return 'NEWLINE';
"-->>" { console.log("DOTTED_ARROW"); return 'DOTTED_ARROW'; } . return 'INVALID';
"<<-->>" { console.log("BIDIRECTIONAL_DOTTED_ARROW"); return 'BIDIRECTIONAL_DOTTED_ARROW'; }
"->" { console.log("SOLID_OPEN_ARROW"); return 'SOLID_OPEN_ARROW'; }
"-->" { console.log("DOTTED_OPEN_ARROW"); return 'DOTTED_OPEN_ARROW'; }
\-[x] { console.log("SOLID_CROSS"); return 'SOLID_CROSS'; }
\-\-[x] { console.log("DOTTED_CROSS"); return 'DOTTED_CROSS'; }
\-[\)] { console.log("SOLID_POINT"); return 'SOLID_POINT'; }
\-\-[\)] { console.log("DOTTED_POINT"); return 'DOTTED_POINT'; }
":"(?:(?:no)?wrap:)?[^#\n;]* { console.log("TEXT_WITH_WRAP:", yytext); return 'TXT'; }
":" { console.log("TEXT"); return 'TXT'; }
"+" { console.log("PLUS"); return '+'; }
"-" { console.log("MINUS"); return '-'; }
<<EOF>> { console.log("EOF"); return 'NEWLINE'; }
. { console.log("INVALID:", yytext); return 'INVALID'; }
/lex /lex
@@ -244,56 +230,12 @@ else_sections
; ;
participant_statement participant_statement
: 'participant' actor_with_config 'AS' restOfLine 'NEWLINE' : 'participant' actor 'AS' restOfLine 'NEWLINE' {$2.draw='participant'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
{ | 'participant' actor 'NEWLINE' {$2.draw='participant'; $2.type='addParticipant';$$=$2;}
console.log('Participant with config and alias:', $2, $4); | 'participant_actor' actor 'AS' restOfLine 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
$2.draw = 'participant'; | 'participant_actor' actor 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant'; $$=$2;}
$2.type = 'addParticipant'; | 'destroy' actor 'NEWLINE' {$2.type='destroyParticipant'; $$=$2;}
$2.description = yy.parseMessage($4); | 'participant' actor_with_config 'NEWLINE' { $2.draw = 'participant'; $2.type = 'addParticipant'; $$ = $2;}
$$ = $2;
}
| 'participant' actor_with_config 'NEWLINE'
{
console.log('Participant with config without alias:', $2);
$2.draw = 'participant';
$2.type = 'addParticipant';
$$ = $2;
}
| 'participant_actor' actor_with_config 'AS' restOfLine 'NEWLINE'
{
$2.draw = 'actor';
$2.type = 'addParticipant';
$2.description = yy.parseMessage($4);
$$ = $2;
}
| 'participant_actor' actor_with_config 'NEWLINE'
{
$2.draw = 'actor';
$2.type = 'addParticipant';
$$ = $2;
}
| 'destroy' actor 'NEWLINE'
{
$2.type = 'destroyParticipant';
$$ = $2;
}
| 'participant_boundary' actor 'AS' restOfLine 'NEWLINE' {$2.draw='boundary'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
| 'participant_boundary' actor 'NEWLINE' {$2.draw='boundary'; $2.type='addParticipant'; $$=$2;}
| 'participant_control' actor 'AS' restOfLine 'NEWLINE' {$2.draw='control'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
| 'participant_control' actor 'NEWLINE' {$2.draw='control'; $2.type='addParticipant'; $$=$2;}
| 'participant_entity' actor 'AS' restOfLine 'NEWLINE' {$2.draw='entity'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
| 'participant_entity' actor 'NEWLINE' {$2.draw='entity'; $2.type='addParticipant'; $$=$2;}
| 'participant_database' actor 'AS' restOfLine 'NEWLINE' {$2.draw='database'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
| 'participant_database' actor 'NEWLINE' {$2.draw='database'; $2.type='addParticipant'; $$=$2;}
| 'participant_collections' actor 'AS' restOfLine 'NEWLINE' {$2.draw='collections'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
| 'participant_collections' actor 'NEWLINE' {$2.draw='collections'; $2.type='addParticipant'; $$=$2;}
| 'participant_queue' actor 'AS' restOfLine 'NEWLINE' {$2.draw='queue'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
| 'participant_queue' actor 'NEWLINE' {$2.draw='queue'; $2.type='addParticipant'; $$=$2;}
; ;
@@ -366,76 +308,35 @@ signal
; ;
actor_with_config actor_with_config
: ACTOR_WITH_CONFIG config_object // Changed from ACTOR : ACTOR config_object
{ {
console.log("ACTOR_WITH_CONFIG Actor with config:", $1, $2);
$$ = { $$ = {
type: 'addParticipant', type: 'addParticipant',
actor: $1, actor: $1,
config: $2 config: $2
}; };
} }
| ACTOR config_object
{
console.log("Actor with config:", $1, $2);
$$ = {
type: 'addParticipant',
actor: $1,
config: $2
};
}
| ACTOR
{
console.log("Actor without config:", $1);
$$ = {
type: 'addParticipant',
actor: $1,
};
}
; ;
config_object config_object
: CONFIG_START CONFIG_CONTENT CONFIG_END : CONFIG_START CONFIG_CONTENT CONFIG_END
{ {
console.log("Parsing config content:", $2); $$ = $2.trim();
try {
// Remove any trailing whitespace/newlines
const content = $2.trim();
$$ = JSON.parse(content);
console.log("Successfully parsed JSON config:", $$);
} catch (e) {
console.log("JSON parse failed, using raw content");
$$ = $2.trim();
}
}
;
actor
: ACTOR_WITH_CONFIG // Add this case
{
console.log("Actor with config flag:", $1);
$$ = { type: 'addParticipant', actor: $1 };
}
| actor config_object
{
console.log("Actor with config:", $1, $2);
$$ = {
type: 'addParticipant',
actor: $1.actor,
config: $2
};
}
| ACTOR
{
console.log("Basic actor:", $1);
$$ = { type: 'addParticipant', actor: $1 };
} }
; ;
// actor
// : actor_participant
// | actor_actor
// ;
actor: ACTOR {$$={ type: 'addParticipant', actor:$1}};
// actor_actor: ACTOR {$$={type: 'addActor', actor:$1}};
signaltype signaltype
: SOLID_OPEN_ARROW { $$ = yy.LINETYPE.SOLID_OPEN; } : SOLID_OPEN_ARROW { $$ = yy.LINETYPE.SOLID_OPEN; }
| DOTTED_OPEN_ARROW { $$ = yy.LINETYPE.DOTTED_OPEN; } | DOTTED_OPEN_ARROW { $$ = yy.LINETYPE.DOTTED_OPEN; }
| SOLID_ARROW { $$ = yy.LINETYPE.SOLID; } | SOLID_ARROW { $$ = yy.LINETYPE.SOLID; }
| BIDIRECTIONAL_SOLID_ARROW { $$ = yy.LINETYPE.BIDIRECTIONAL_SOLID; } | BIDIRECTIONAL_SOLID_ARROW { $$ = yy.LINETYPE.BIDIRECTIONAL_SOLID; }
| DOTTED_ARROW { $$ = yy.LINETYPE.DOTTED; } | DOTTED_ARROW { $$ = yy.LINETYPE.DOTTED; }
| BIDIRECTIONAL_DOTTED_ARROW { $$ = yy.LINETYPE.BIDIRECTIONAL_DOTTED; } | BIDIRECTIONAL_DOTTED_ARROW { $$ = yy.LINETYPE.BIDIRECTIONAL_DOTTED; }
| SOLID_CROSS { $$ = yy.LINETYPE.SOLID_CROSS; } | SOLID_CROSS { $$ = yy.LINETYPE.SOLID_CROSS; }

View File

@@ -1,4 +1,5 @@
import { getConfig } from '../../diagram-api/diagramAPI.js'; import { getConfig } from '../../diagram-api/diagramAPI.js';
import * as yaml from 'js-yaml';
import type { DiagramDB } from '../../diagram-api/types.js'; import type { DiagramDB } from '../../diagram-api/types.js';
import { log } from '../../logger.js'; import { log } from '../../logger.js';
import { ImperativeState } from '../../utils/imperativeState.js'; import { ImperativeState } from '../../utils/imperativeState.js';
@@ -13,6 +14,7 @@ import {
setDiagramTitle, setDiagramTitle,
} from '../common/commonDb.js'; } from '../common/commonDb.js';
import type { Actor, AddMessageParams, Box, Message, Note } from './types.js'; import type { Actor, AddMessageParams, Box, Message, Note } from './types.js';
import type { ParticipantMetaData } from '../../types.js';
interface SequenceState { interface SequenceState {
prevActor?: string; prevActor?: string;
@@ -107,7 +109,6 @@ export class SequenceDB implements DiagramDB {
this.apply = this.apply.bind(this); this.apply = this.apply.bind(this);
this.parseBoxData = this.parseBoxData.bind(this); this.parseBoxData = this.parseBoxData.bind(this);
this.parseMessage = this.parseMessage.bind(this); this.parseMessage = this.parseMessage.bind(this);
this.matchAsActorOrParticipant = this.matchAsActorOrParticipant.bind(this);
this.clear(); this.clear();
@@ -131,9 +132,22 @@ export class SequenceDB implements DiagramDB {
id: string, id: string,
name: string, name: string,
description: { text: string; wrap?: boolean | null; type: string }, description: { text: string; wrap?: boolean | null; type: string },
type: string type: string,
metadata?: any
) { ) {
let assignedBox = this.state.records.currentBox; let assignedBox = this.state.records.currentBox;
let doc;
if (metadata !== undefined) {
let yamlData;
// detect if shapeData contains a newline character
if (!metadata.includes('\n')) {
yamlData = '{\n' + metadata + '\n}';
} else {
yamlData = metadata + '\n';
}
doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA }) as ParticipantMetaData;
}
type = doc?.type ?? type;
const old = this.state.records.actors.get(id); const old = this.state.records.actors.get(id);
if (old) { if (old) {
// If already set and trying to set to a new one throw error // If already set and trying to set to a new one throw error
@@ -342,22 +356,6 @@ export class SequenceDB implements DiagramDB {
return message; return message;
} }
public matchAsActorOrParticipant(
tokenName: string,
tokenType: string,
inputRemainder: string,
lexer: any
): string {
const arrowLike = /^\s*(->>|-->>|->|-->|<<->>|<<-->>|-x|--x|-\))/;
const colonLike = /^\s*:/;
if (arrowLike.test(inputRemainder) || colonLike.test(inputRemainder)) {
return 'ACTOR';
}
lexer.begin('ID'); // used the passed lexer
return tokenType;
}
// We expect the box statement to be color first then description // We expect the box statement to be color first then description
// The color can be rgb,rgba,hsl,hsla, or css code names #hex codes are not supported for now because of the way the char # is handled // The color can be rgb,rgba,hsl,hsla, or css code names #hex codes are not supported for now because of the way the char # is handled
// We extract first segment as color, the rest of the line is considered as text // We extract first segment as color, the rest of the line is considered as text
@@ -546,7 +544,7 @@ export class SequenceDB implements DiagramDB {
}); });
break; break;
case 'addParticipant': case 'addParticipant':
this.addActor(param.actor, param.actor, param.description, param.draw); this.addActor(param.actor, param.actor, param.description, param.draw, param.config);
break; break;
case 'createParticipant': case 'createParticipant':
if (this.state.records.actors.has(param.actor)) { if (this.state.records.actors.has(param.actor)) {

View File

@@ -2043,8 +2043,8 @@ Bob->>Alice:Got it!
const actor1 = 'database'; const actor1 = 'database';
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
database Alice participant Alice@{ "type" : "database" }
database Bob participant Bob@{ "type" : "database" }
Bob->>+Alice: Hi Alice Bob->>+Alice: Hi Alice
Alice->>+Bob: Hi Bob Alice->>+Bob: Hi Bob
`); `);
@@ -2057,10 +2057,10 @@ Bob->>Alice:Got it!
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
participant lead participant lead
queue dsa participant dsa@{ "type" : "queue" }
API->>+Database: getUserb API->>+Database: getUserb
Database-->>-API: userb Database-->>-API: userb
queue --> Database: hello dsa --> Database: hello
`); `);
const messages = diagram.db.getMessages(); const messages = diagram.db.getMessages();
@@ -2070,67 +2070,67 @@ Bob->>Alice:Got it!
it('should parse boundary participant', async () => { it('should parse boundary participant', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
boundary B as Boundary Box participant boundary@{ "type" : "boundary" }
B->B: test boundary->boundary: test
`); `);
const actors = diagram.db.getActors(); const actors = diagram.db.getActors();
expect(actors.get('B').type).toBe('boundary'); expect(actors.get('boundary').type).toBe('boundary');
expect(actors.get('B').description).toBe('Boundary Box'); expect(actors.get('boundary').description).toBe('boundary');
}); });
it('should parse control participant', async () => { it('should parse control participant', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
control C as Controller participant C@{ "type" : "control" }
C->C: test C->C: test
`); `);
const actors = diagram.db.getActors(); const actors = diagram.db.getActors();
expect(actors.get('C').type).toBe('control'); expect(actors.get('C').type).toBe('control');
expect(actors.get('C').description).toBe('Controller'); expect(actors.get('C').description).toBe('C');
}); });
it('should parse entity participant', async () => { it('should parse entity participant', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
entity E as Entity participant E@{ "type" : "entity" }
E->E: test E->E: test
`); `);
const actors = diagram.db.getActors(); const actors = diagram.db.getActors();
expect(actors.get('E').type).toBe('entity'); expect(actors.get('E').type).toBe('entity');
expect(actors.get('E').description).toBe('Entity'); expect(actors.get('E').description).toBe('E');
}); });
it('should parse database participant', async () => { it('should parse database participant', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
database D as Database participant D@{ "type" : "database" }
D->D: test D->D: test
`); `);
const actors = diagram.db.getActors(); const actors = diagram.db.getActors();
expect(actors.get('D').type).toBe('database'); expect(actors.get('D').type).toBe('database');
expect(actors.get('D').description).toBe('Database'); expect(actors.get('D').description).toBe('D');
}); });
it('should parse collections participant', async () => { it('should parse collections participant', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
collections L as List participant L@{ "type" : "collections" }
L->L: test L->L: test
`); `);
const actors = diagram.db.getActors(); const actors = diagram.db.getActors();
expect(actors.get('L').type).toBe('collections'); expect(actors.get('L').type).toBe('collections');
expect(actors.get('L').description).toBe('List'); expect(actors.get('L').description).toBe('L');
}); });
it('should parse queue participant', async () => { it('should parse queue participant', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
queue Q as Jobs participant Q@{ "type" : "queue" }
Q->Q: test Q->Q: test
`); `);
const actors = diagram.db.getActors(); const actors = diagram.db.getActors();
expect(actors.get('Q').type).toBe('queue'); expect(actors.get('Q').type).toBe('queue');
expect(actors.get('Q').description).toBe('Jobs'); expect(actors.get('Q').description).toBe('Q');
}); });
}); });
@@ -2138,89 +2138,58 @@ Bob->>Alice:Got it!
it('should parse actor participant', async () => { it('should parse actor participant', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
queue A as ActorName participant A@{ "type" : "queue" }
A->A: test A->A: test
`); `);
const actors = diagram.db.getActors(); const actors = diagram.db.getActors();
expect(actors.get('A').type).toBe('queue'); expect(actors.get('A').type).toBe('queue');
expect(actors.get('A').description).toBe('ActorName'); expect(actors.get('A').description).toBe('A');
}); });
it('should parse participant participant', async () => { it('should parse participant participant', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
database P as PartName participant P@{ "type" : "database" }
P->P: test P->P: test
`); `);
const actors = diagram.db.getActors(); const actors = diagram.db.getActors();
expect(actors.get('P').type).toBe('database'); expect(actors.get('P').type).toBe('database');
expect(actors.get('P').description).toBe('PartName'); expect(actors.get('P').description).toBe('P');
}); });
it('should parse boundary using actor keyword', async () => { it('should parse boundary using actor keyword', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
collections B as Boundary participant Alice@{ "type" : "collections" }
B->B: test participant Bob@{ "type" : "control" }
Alice->>Bob: Hello Bob, how are you?
`); `);
const actors = diagram.db.getActors(); const actors = diagram.db.getActors();
expect(actors.get('B').type).toBe('collections'); expect(actors.get('Alice').type).toBe('collections');
expect(actors.get('B').description).toBe('Boundary'); expect(actors.get('Bob').type).toBe('control');
expect(actors.get('Bob').description).toBe('Bob');
}); });
it('should parse control using participant keyword', async () => { it('should parse control using participant keyword', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
control C as Controller participant C@{ "type" : "control" }
C->C: test C->C: test
`); `);
const actors = diagram.db.getActors(); const actors = diagram.db.getActors();
expect(actors.get('C').type).toBe('control'); expect(actors.get('C').type).toBe('control');
expect(actors.get('C').description).toBe('Controller'); expect(actors.get('C').description).toBe('C');
}); });
it('should parse entity using actor keyword', async () => { it('should parse entity using actor keyword', async () => {
const diagram = await Diagram.fromText(` const diagram = await Diagram.fromText(`
sequenceDiagram sequenceDiagram
entity E as Entity participant E@{ "type" : "entity" }
E->E: test E->E: test
`); `);
const actors = diagram.db.getActors(); const actors = diagram.db.getActors();
expect(actors.get('E').type).toBe('entity'); expect(actors.get('E').type).toBe('entity');
expect(actors.get('E').description).toBe('Entity'); expect(actors.get('E').description).toBe('E');
});
it('should parse database using participant keyword', async () => {
const diagram = await Diagram.fromText(`
sequenceDiagram
participant D as Database
D->D: test
`);
const actors = diagram.db.getActors();
expect(actors.get('D').type).toBe('participant');
expect(actors.get('D').description).toBe('Database');
});
it('should parse collections using actor keyword', async () => {
const diagram = await Diagram.fromText(`
sequenceDiagram
actor L as List
L->L: test
`);
const actors = diagram.db.getActors();
expect(actors.get('L').type).toBe('actor');
expect(actors.get('L').description).toBe('List');
});
it('should parse queue using participant keyword', async () => {
const diagram = await Diagram.fromText(`
sequenceDiagram
participant Q as Jobs
Q->Q: test
`);
const actors = diagram.db.getActors();
expect(actors.get('Q').type).toBe('participant');
expect(actors.get('Q').description).toBe('Jobs');
}); });
}); });
}); });

View File

@@ -13,6 +13,18 @@ export interface NodeMetaData {
ticket?: string; ticket?: string;
} }
export interface ParticipantMetaData {
type?:
| 'actor'
| 'participant'
| 'boundary'
| 'control'
| 'entity'
| 'database'
| 'collections'
| 'queue';
}
export interface EdgeMetaData { export interface EdgeMetaData {
animation?: 'fast' | 'slow'; animation?: 'fast' | 'slow';
animate?: boolean; animate?: boolean;