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

View File

@@ -1,4 +1,5 @@
import { getConfig } from '../../diagram-api/diagramAPI.js';
import * as yaml from 'js-yaml';
import type { DiagramDB } from '../../diagram-api/types.js';
import { log } from '../../logger.js';
import { ImperativeState } from '../../utils/imperativeState.js';
@@ -13,6 +14,7 @@ import {
setDiagramTitle,
} from '../common/commonDb.js';
import type { Actor, AddMessageParams, Box, Message, Note } from './types.js';
import type { ParticipantMetaData } from '../../types.js';
interface SequenceState {
prevActor?: string;
@@ -107,7 +109,6 @@ export class SequenceDB implements DiagramDB {
this.apply = this.apply.bind(this);
this.parseBoxData = this.parseBoxData.bind(this);
this.parseMessage = this.parseMessage.bind(this);
this.matchAsActorOrParticipant = this.matchAsActorOrParticipant.bind(this);
this.clear();
@@ -131,9 +132,22 @@ export class SequenceDB implements DiagramDB {
id: string,
name: string,
description: { text: string; wrap?: boolean | null; type: string },
type: string
type: string,
metadata?: any
) {
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);
if (old) {
// If already set and trying to set to a new one throw error
@@ -342,22 +356,6 @@ export class SequenceDB implements DiagramDB {
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
// 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
@@ -546,7 +544,7 @@ export class SequenceDB implements DiagramDB {
});
break;
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;
case 'createParticipant':
if (this.state.records.actors.has(param.actor)) {

View File

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

View File

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