@zombie-mermaid/mermaid-parser 3.2.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zombie-mermaid/mermaid-parser",
3
- "version": "3.2.0",
3
+ "version": "4.0.0",
4
4
  "license": "MIT",
5
5
  "description": "Parsers for class, ER, sequence, and XY chart diagrams — the per-type parse functions both svg-renderer and ascii-renderer import directly.",
6
6
  "repository": {
@@ -35,6 +35,6 @@
35
35
  "LICENSE"
36
36
  ],
37
37
  "dependencies": {
38
- "@zombie-mermaid/core": "3.2.0"
38
+ "@zombie-mermaid/core": "4.0.0"
39
39
  }
40
40
  }
@@ -117,6 +117,40 @@ describe('getSeriesColor', () => {
117
117
  })
118
118
  })
119
119
 
120
+ describe('first-three-series separation (#1244)', () => {
121
+ // CIE76 ΔE between two sRGB hex colors.
122
+ function lab(hex: string): [number, number, number] {
123
+ const lin = (i: number) => {
124
+ const v = parseInt(hex.slice(i, i + 2), 16) / 255
125
+ return v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4
126
+ }
127
+ const [r, g, b] = [lin(1), lin(3), lin(5)] as const
128
+ const x = (0.4124 * r + 0.3576 * g + 0.1805 * b) / 0.95047
129
+ const y = 0.2126 * r + 0.7152 * g + 0.0722 * b
130
+ const z = (0.0193 * r + 0.1192 * g + 0.9505 * b) / 1.08883
131
+ const f = (t: number) =>
132
+ t > 0.008856 ? Math.cbrt(t) : 7.787 * t + 16 / 116
133
+ return [116 * f(y) - 16, 500 * (f(x) - f(y)), 200 * (f(y) - f(z))]
134
+ }
135
+ const deltaE = (a: string, b: string) => {
136
+ const [l1, a1, b1] = lab(a)
137
+ const [l2, a2, b2] = lab(b)
138
+ return Math.hypot(l1 - l2, a1 - a2, b1 - b2)
139
+ }
140
+
141
+ // The pre-fix palette had ΔE 9 between series 0 and 2 (two similar blues).
142
+ for (const bg of ['#ffffff', '#1a1b26']) {
143
+ it(`keeps series 0, 1 and 2 at least 25 ΔE apart on ${bg}`, () => {
144
+ const c0 = getSeriesColor(0, '#3b82f6', bg)
145
+ const c1 = getSeriesColor(1, '#3b82f6', bg)
146
+ const c2 = getSeriesColor(2, '#3b82f6', bg)
147
+ expect(deltaE(c0, c1)).toBeGreaterThanOrEqual(25)
148
+ expect(deltaE(c0, c2)).toBeGreaterThanOrEqual(25)
149
+ expect(deltaE(c1, c2)).toBeGreaterThanOrEqual(25)
150
+ })
151
+ }
152
+ })
153
+
120
154
  /** Minimal hex→HSL helper for assertions (mirrors colors.ts's private hexToHsl). */
121
155
  function hexLightness(hex: string): [number, number, number] {
122
156
  const h = hex.replace('#', '')
@@ -478,19 +478,14 @@ function parseMember(
478
478
  }
479
479
  }
480
480
 
481
- // It's an attribute: [Type] name or name Type
482
- // Common patterns: "String name", "+int age", "name"
483
- const parts = parseGenericTypes(rest).split(/\s+/)
484
- let name: string
485
- let type: string | undefined
486
-
487
- if (parts.length >= 2) {
488
- // "Type name" pattern
489
- type = parts[0]
490
- name = parts.slice(1).join(' ')
491
- } else {
492
- name = parts[0] ?? rest
493
- }
481
+ // It's an attribute. Mermaid renders attribute text verbatim (its
482
+ // ClassMember keeps everything after the visibility marker as one id and
483
+ // only splits methods into name/params/return type), so `String name`,
484
+ // `name Type` and `name: Type` all display as written. Splitting two
485
+ // tokens into Type + name guessed the order and flipped `-data Map` into
486
+ // `- Map: data` (#1265).
487
+ const name = parseGenericTypes(rest)
488
+ const type: string | undefined = undefined
494
489
 
495
490
  const isStatic = name.endsWith('$')
496
491
  const isAbstract = name.endsWith('*')
@@ -110,6 +110,19 @@ export interface PositionedClassDiagram {
110
110
  classes: PositionedClassNode[]
111
111
  relationships: PositionedClassRelationship[]
112
112
  notes: PositionedClassNote[]
113
+ /** Namespace frames, drawn behind their member classes */
114
+ namespaces: PositionedClassNamespace[]
115
+ }
116
+
117
+ /** A `namespace Name { ... }` block's frame, in diagram coordinates */
118
+ export interface PositionedClassNamespace {
119
+ name: string
120
+ /** Ids of the member classes the frame encloses */
121
+ classIds: string[]
122
+ x: number
123
+ y: number
124
+ width: number
125
+ height: number
113
126
  }
114
127
 
115
128
  export interface PositionedClassNote {
@@ -216,6 +216,8 @@ export interface Activation {
216
216
  topY: number
217
217
  bottomY: number
218
218
  width: number
219
+ /** Nesting level on this actor's lifeline: 0 for the outermost bar, 1 for a bar opened while one is already active, and so on */
220
+ depth: number
219
221
  }
220
222
 
221
223
  export interface PositionedBlock {
@@ -4,7 +4,9 @@
4
4
  // Generates monochromatic shades from the theme accent color.
5
5
  // Series 0 = accent (or blue fallback). Series 1+ are darker/lighter
6
6
  // shades of the same hue with subtle hue drift to stay in the same
7
- // color family (like navy ↔ cyan from blue).
7
+ // color family (like navy ↔ cyan from blue). Hue drifts toward navy for
8
+ // darker shades and toward cyan for lighter ones, so neighbouring series
9
+ // do not collapse into two near-identical blues (#1244).
8
10
  //
9
11
  // Used by both the SVG and ASCII renderers.
10
12
  // ============================================================================
@@ -101,7 +103,7 @@ export function isDarkBackground(bgHex: string): boolean {
101
103
  * Get the hex color for a series index.
102
104
  * Index 0 returns the accent color as-is.
103
105
  * Index 1+ alternate between darker and lighter shades of the same hue
104
- * with subtle hue drift (±8-12° per tier) to stay in the same family.
106
+ * with subtle hue drift (-8° per tier for darker, -12° for lighter) to stay in the same family.
105
107
  *
106
108
  * When `bgColor` is provided, shade direction adapts to the background:
107
109
  * - Light bg: odd = darker, even = lighter (default)
@@ -128,8 +130,12 @@ export function getSeriesColor(
128
130
  const dark = safeBg && isDarkBackground(safeBg) ? !oddIndex : oddIndex
129
131
  const l = dark ? Math.max(25, 48 - tier * 13) : Math.min(78, 55 + tier * 11)
130
132
 
131
- // Subtle hue drift: darker shades shift slightly negative, lighter shift positive
132
- const hShift = (dark ? -8 : 12) * tier
133
+ // Subtle hue drift: darker shades shift slightly negative (toward navy),
134
+ // lighter shades shift negative too (toward sky/cyan). The lighter shade
135
+ // used to drift positive (toward indigo), which landed series 2 within a
136
+ // few ΔE of series 0 (#1244); drifting the other way keeps the three first
137
+ // series distinct in hue as well as lightness.
138
+ const hShift = (dark ? -8 : -12) * tier
133
139
  const newH = (((h + hShift) % 360) + 360) % 360
134
140
 
135
141
  return hslToHex(newH, chartS, l)