Merge pull request #6804 from mermaid-js/6691-update-packet-diagram-class-based-db

6691: update packet diagram to use new class-based DB approach
This commit is contained in:
Shubham P
2025-07-30 13:36:43 +00:00
committed by GitHub
5 changed files with 70 additions and 59 deletions

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
chore: Update packet diagram to use new class-based database structure

View File

@@ -1,6 +1,7 @@
import { getConfig as commonGetConfig } from '../../config.js'; import { getConfig as commonGetConfig } from '../../config.js';
import type { PacketDiagramConfig } from '../../config.type.js'; import type { PacketDiagramConfig } from '../../config.type.js';
import DEFAULT_CONFIG from '../../defaultConfig.js'; import DEFAULT_CONFIG from '../../defaultConfig.js';
import type { DiagramDB } from '../../diagram-api/types.js';
import { cleanAndMerge } from '../../utils.js'; import { cleanAndMerge } from '../../utils.js';
import { import {
clear as commonClear, clear as commonClear,
@@ -11,17 +12,13 @@ import {
setAccTitle, setAccTitle,
setDiagramTitle, setDiagramTitle,
} from '../common/commonDb.js'; } from '../common/commonDb.js';
import type { PacketDB, PacketData, PacketWord } from './types.js'; import type { PacketWord } from './types.js';
const defaultPacketData: PacketData = {
packet: [],
};
let data: PacketData = structuredClone(defaultPacketData);
const DEFAULT_PACKET_CONFIG: Required<PacketDiagramConfig> = DEFAULT_CONFIG.packet; const DEFAULT_PACKET_CONFIG: Required<PacketDiagramConfig> = DEFAULT_CONFIG.packet;
const getConfig = (): Required<PacketDiagramConfig> => { export class PacketDB implements DiagramDB {
private packet: PacketWord[] = [];
public getConfig() {
const config = cleanAndMerge({ const config = cleanAndMerge({
...DEFAULT_PACKET_CONFIG, ...DEFAULT_PACKET_CONFIG,
...commonGetConfig().packet, ...commonGetConfig().packet,
@@ -30,30 +27,27 @@ const getConfig = (): Required<PacketDiagramConfig> => {
config.paddingY += 10; config.paddingY += 10;
} }
return config; return config;
};
const getPacket = (): PacketWord[] => data.packet;
const pushWord = (word: PacketWord) => {
if (word.length > 0) {
data.packet.push(word);
} }
};
const clear = () => { public getPacket() {
return this.packet;
}
public pushWord(word: PacketWord) {
if (word.length > 0) {
this.packet.push(word);
}
}
public clear() {
commonClear(); commonClear();
data = structuredClone(defaultPacketData); this.packet = [];
}; }
export const db: PacketDB = { public setAccTitle = setAccTitle;
pushWord, public getAccTitle = getAccTitle;
getPacket, public setDiagramTitle = setDiagramTitle;
getConfig, public getDiagramTitle = getDiagramTitle;
clear, public getAccDescription = getAccDescription;
setAccTitle, public setAccDescription = setAccDescription;
getAccTitle, }
setDiagramTitle,
getDiagramTitle,
getAccDescription,
setAccDescription,
};

View File

@@ -1,12 +1,14 @@
import type { DiagramDefinition } from '../../diagram-api/types.js'; import type { DiagramDefinition } from '../../diagram-api/types.js';
import { db } from './db.js'; import { PacketDB } from './db.js';
import { parser } from './parser.js'; import { parser } from './parser.js';
import { renderer } from './renderer.js'; import { renderer } from './renderer.js';
import { styles } from './styles.js'; import { styles } from './styles.js';
export const diagram: DiagramDefinition = { export const diagram: DiagramDefinition = {
parser, parser,
db, get db() {
return new PacketDB();
},
renderer, renderer,
styles, styles,
}; };

View File

@@ -1,24 +1,26 @@
import { it, describe, expect } from 'vitest'; import { it, describe, expect } from 'vitest';
import { db } from './db.js'; import { PacketDB } from './db.js';
import { parser } from './parser.js'; import { parser } from './parser.js';
const { clear, getPacket, getDiagramTitle, getAccTitle, getAccDescription } = db;
describe('packet diagrams', () => { describe('packet diagrams', () => {
let db: PacketDB;
beforeEach(() => { beforeEach(() => {
clear(); db = new PacketDB();
if (parser.parser) {
parser.parser.yy = db;
}
}); });
it('should handle a packet-beta definition', async () => { it('should handle a packet-beta definition', async () => {
const str = `packet-beta`; const str = `packet-beta`;
await expect(parser.parse(str)).resolves.not.toThrow(); await expect(parser.parse(str)).resolves.not.toThrow();
expect(getPacket()).toMatchInlineSnapshot('[]'); expect(db.getPacket()).toMatchInlineSnapshot('[]');
}); });
it('should handle a packet definition', async () => { it('should handle a packet definition', async () => {
const str = `packet`; const str = `packet`;
await expect(parser.parse(str)).resolves.not.toThrow(); await expect(parser.parse(str)).resolves.not.toThrow();
expect(getPacket()).toMatchInlineSnapshot('[]'); expect(db.getPacket()).toMatchInlineSnapshot('[]');
}); });
it('should handle diagram with data and title', async () => { it('should handle diagram with data and title', async () => {
@@ -29,10 +31,10 @@ describe('packet diagrams', () => {
0-10: "test" 0-10: "test"
`; `;
await expect(parser.parse(str)).resolves.not.toThrow(); await expect(parser.parse(str)).resolves.not.toThrow();
expect(getDiagramTitle()).toMatchInlineSnapshot('"Packet diagram"'); expect(db.getDiagramTitle()).toMatchInlineSnapshot('"Packet diagram"');
expect(getAccTitle()).toMatchInlineSnapshot('"Packet accTitle"'); expect(db.getAccTitle()).toMatchInlineSnapshot('"Packet accTitle"');
expect(getAccDescription()).toMatchInlineSnapshot('"Packet accDescription"'); expect(db.getAccDescription()).toMatchInlineSnapshot('"Packet accDescription"');
expect(getPacket()).toMatchInlineSnapshot(` expect(db.getPacket()).toMatchInlineSnapshot(`
[ [
[ [
{ {
@@ -52,7 +54,7 @@ describe('packet diagrams', () => {
11: "single" 11: "single"
`; `;
await expect(parser.parse(str)).resolves.not.toThrow(); await expect(parser.parse(str)).resolves.not.toThrow();
expect(getPacket()).toMatchInlineSnapshot(` expect(db.getPacket()).toMatchInlineSnapshot(`
[ [
[ [
{ {
@@ -78,7 +80,7 @@ describe('packet diagrams', () => {
+16: "word" +16: "word"
`; `;
await expect(parser.parse(str)).resolves.not.toThrow(); await expect(parser.parse(str)).resolves.not.toThrow();
expect(getPacket()).toMatchInlineSnapshot(` expect(db.getPacket()).toMatchInlineSnapshot(`
[ [
[ [
{ {
@@ -104,7 +106,7 @@ describe('packet diagrams', () => {
+16: "word" +16: "word"
`; `;
await expect(parser.parse(str)).resolves.not.toThrow(); await expect(parser.parse(str)).resolves.not.toThrow();
expect(getPacket()).toMatchInlineSnapshot(` expect(db.getPacket()).toMatchInlineSnapshot(`
[ [
[ [
{ {
@@ -130,7 +132,7 @@ describe('packet diagrams', () => {
11-90: "multiple" 11-90: "multiple"
`; `;
await expect(parser.parse(str)).resolves.not.toThrow(); await expect(parser.parse(str)).resolves.not.toThrow();
expect(getPacket()).toMatchInlineSnapshot(` expect(db.getPacket()).toMatchInlineSnapshot(`
[ [
[ [
{ {
@@ -172,7 +174,7 @@ describe('packet diagrams', () => {
17-63: "multiple" 17-63: "multiple"
`; `;
await expect(parser.parse(str)).resolves.not.toThrow(); await expect(parser.parse(str)).resolves.not.toThrow();
expect(getPacket()).toMatchInlineSnapshot(` expect(db.getPacket()).toMatchInlineSnapshot(`
[ [
[ [
{ {

View File

@@ -3,12 +3,12 @@ import { parse } from '@mermaid-js/parser';
import type { ParserDefinition } from '../../diagram-api/types.js'; import type { ParserDefinition } from '../../diagram-api/types.js';
import { log } from '../../logger.js'; import { log } from '../../logger.js';
import { populateCommonDb } from '../common/populateCommonDb.js'; import { populateCommonDb } from '../common/populateCommonDb.js';
import { db } from './db.js'; import { PacketDB } from './db.js';
import type { PacketBlock, PacketWord } from './types.js'; import type { PacketBlock, PacketWord } from './types.js';
const maxPacketSize = 10_000; const maxPacketSize = 10_000;
const populate = (ast: Packet) => { const populate = (ast: Packet, db: PacketDB) => {
populateCommonDb(ast, db); populateCommonDb(ast, db);
let lastBit = -1; let lastBit = -1;
let word: PacketWord = []; let word: PacketWord = [];
@@ -91,9 +91,17 @@ const getNextFittingBlock = (
}; };
export const parser: ParserDefinition = { export const parser: ParserDefinition = {
// @ts-expect-error - PacketDB is not assignable to DiagramDB
parser: { yy: undefined },
parse: async (input: string): Promise<void> => { parse: async (input: string): Promise<void> => {
const ast: Packet = await parse('packet', input); const ast: Packet = await parse('packet', input);
const db = parser.parser?.yy;
if (!(db instanceof PacketDB)) {
throw new Error(
'parser.parser?.yy was not a PacketDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.'
);
}
log.debug(ast); log.debug(ast);
populate(ast); populate(ast, db);
}, },
}; };