@diagrammo/dgmo 0.35.0 → 0.37.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/dist/index.cjs CHANGED
@@ -16665,6 +16665,7 @@ function parseInfra(content) {
16665
16665
  let currentGroup = null;
16666
16666
  let currentTagGroup = null;
16667
16667
  let baseIndent = 0;
16668
+ let firstLineConsumed = false;
16668
16669
  function finishCurrentNode() {
16669
16670
  if (!currentNode) return;
16670
16671
  const key = currentNode.id;
@@ -16672,7 +16673,8 @@ function parseInfra(content) {
16672
16673
  if (existing) {
16673
16674
  const incomingDisplay = displayName(currentNode.label);
16674
16675
  const existingDisplay = displayName(existing.label);
16675
- if (incomingDisplay !== existingDisplay) {
16676
+ const isAliasRef = nameAliasMap.get(currentNode.label) === key;
16677
+ if (incomingDisplay !== existingDisplay && !isAliasRef) {
16676
16678
  result.diagnostics.push(
16677
16679
  makeDgmoError(
16678
16680
  currentNode.lineNumber,
@@ -16738,19 +16740,22 @@ function parseInfra(content) {
16738
16740
  if (indent === 0 && currentNode && !trimmed.startsWith("-")) {
16739
16741
  finishCurrentNode();
16740
16742
  }
16741
- const firstLineResult = parseFirstLine(trimmed);
16742
- if (firstLineResult) {
16743
- if (firstLineResult.chartType !== "infra") {
16744
- setError(
16745
- lineNumber,
16746
- `Expected chart type 'infra', got '${firstLineResult.chartType}'`
16747
- );
16748
- }
16749
- if (firstLineResult.title) {
16750
- result.title = firstLineResult.title;
16751
- result.titleLineNumber = lineNumber;
16743
+ if (!firstLineConsumed) {
16744
+ firstLineConsumed = true;
16745
+ const firstLineResult = parseFirstLine(trimmed);
16746
+ if (firstLineResult) {
16747
+ if (firstLineResult.chartType !== "infra") {
16748
+ setError(
16749
+ lineNumber,
16750
+ `Expected chart type 'infra', got '${firstLineResult.chartType}'`
16751
+ );
16752
+ }
16753
+ if (firstLineResult.title) {
16754
+ result.title = firstLineResult.title;
16755
+ result.titleLineNumber = lineNumber;
16756
+ }
16757
+ continue;
16752
16758
  }
16753
- continue;
16754
16759
  }
16755
16760
  if (/^direction-tb$/i.test(trimmed)) {
16756
16761
  result.direction = "TB";
@@ -16816,18 +16821,20 @@ function parseInfra(content) {
16816
16821
  if (compMatch) {
16817
16822
  finishCurrentNode();
16818
16823
  finishCurrentTagGroup();
16819
- const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
16824
+ const { qname, uname, alias: asAlias, meta } = compMatch.groups;
16825
+ const rawName = (qname ?? uname ?? "").trim();
16820
16826
  const peeled = peelInfraDecorations(rawName, lineNumber);
16821
16827
  const name = peeled.label;
16822
- const rest = compMatch[3] || "";
16828
+ const alias = asAlias ?? peeled.alias;
16829
+ const rest = meta ?? "";
16823
16830
  const { tags } = extractPipeMetadata(rest);
16824
16831
  warnUnknownMetaKeys(
16825
16832
  tags,
16826
16833
  withTagAliases(INFRA_REGISTRY, tagAliasSet),
16827
16834
  (msg) => warn(lineNumber, msg)
16828
16835
  );
16829
- const id = nodeId2(name);
16830
- if (peeled.alias) nameAliasMap.set(peeled.alias, id);
16836
+ const id = nameAliasMap.get(name) ?? nodeId2(name);
16837
+ if (alias) nameAliasMap.set(alias, id);
16831
16838
  const isEdge = EDGE_NODE_NAMES.has(id.toLowerCase());
16832
16839
  currentNode = {
16833
16840
  id,
@@ -16911,18 +16918,20 @@ function parseInfra(content) {
16911
16918
  const compMatch = trimmed.match(COMPONENT_RE);
16912
16919
  if (compMatch) {
16913
16920
  finishCurrentTagGroup();
16914
- const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
16921
+ const { qname, uname, alias: asAlias, meta } = compMatch.groups;
16922
+ const rawName = (qname ?? uname ?? "").trim();
16915
16923
  const peeled = peelInfraDecorations(rawName, lineNumber);
16916
16924
  const name = peeled.label;
16917
- const rest = compMatch[3] || "";
16925
+ const alias = asAlias ?? peeled.alias;
16926
+ const rest = meta ?? "";
16918
16927
  const { tags: nodeTags } = extractPipeMetadata(rest);
16919
16928
  warnUnknownMetaKeys(
16920
16929
  nodeTags,
16921
16930
  withTagAliases(INFRA_REGISTRY, tagAliasSet),
16922
16931
  (msg) => warn(lineNumber, msg)
16923
16932
  );
16924
- const id = nodeId2(name);
16925
- if (peeled.alias) nameAliasMap.set(peeled.alias, id);
16933
+ const id = nameAliasMap.get(name) ?? nodeId2(name);
16934
+ if (alias) nameAliasMap.set(alias, id);
16926
16935
  const tags = currentGroup.metadata ? { ...currentGroup.metadata, ...nodeTags } : nodeTags;
16927
16936
  currentNode = {
16928
16937
  id,
@@ -17113,6 +17122,11 @@ function parseInfra(content) {
17113
17122
  }
17114
17123
  continue;
17115
17124
  }
17125
+ if (currentNode && tagAliasSet.has(normalizeName(key))) {
17126
+ const mut = nodeMutableTags.get(currentNode.id);
17127
+ if (mut) mut[tagAttrKey(key)] = rawVal;
17128
+ continue;
17129
+ }
17116
17130
  if (!INFRA_BEHAVIOR_KEYS.has(key) && !EDGE_ONLY_KEYS.has(key)) {
17117
17131
  const allKeys = [...INFRA_BEHAVIOR_KEYS, ...EDGE_ONLY_KEYS];
17118
17132
  const hint = suggest(key, allKeys);
@@ -17178,18 +17192,20 @@ function parseInfra(content) {
17178
17192
  finishCurrentNode();
17179
17193
  const compMatch = trimmed.match(COMPONENT_RE);
17180
17194
  if (compMatch) {
17181
- const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
17195
+ const { qname, uname, alias: asAlias, meta } = compMatch.groups;
17196
+ const rawName = (qname ?? uname ?? "").trim();
17182
17197
  const peeled = peelInfraDecorations(rawName, lineNumber);
17183
17198
  const name = peeled.label;
17184
- const rest = compMatch[3] || "";
17199
+ const alias = asAlias ?? peeled.alias;
17200
+ const rest = meta ?? "";
17185
17201
  const { tags: nodeTags } = extractPipeMetadata(rest);
17186
17202
  warnUnknownMetaKeys(
17187
17203
  nodeTags,
17188
17204
  withTagAliases(INFRA_REGISTRY, tagAliasSet),
17189
17205
  (msg) => warn(lineNumber, msg)
17190
17206
  );
17191
- const id = nodeId2(name);
17192
- if (peeled.alias) nameAliasMap.set(peeled.alias, id);
17207
+ const id = nameAliasMap.get(name) ?? nodeId2(name);
17208
+ if (alias) nameAliasMap.set(alias, id);
17193
17209
  const tags = currentGroup.metadata ? { ...currentGroup.metadata, ...nodeTags } : nodeTags;
17194
17210
  currentNode = {
17195
17211
  id,
@@ -17211,18 +17227,20 @@ function parseInfra(content) {
17211
17227
  finishCurrentNode();
17212
17228
  finishCurrentTagGroup();
17213
17229
  currentGroup = null;
17214
- const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
17230
+ const { qname, uname, alias: asAlias, meta } = compMatch.groups;
17231
+ const rawName = (qname ?? uname ?? "").trim();
17215
17232
  const peeled = peelInfraDecorations(rawName, lineNumber);
17216
17233
  const name = peeled.label;
17217
- const rest = compMatch[3] || "";
17234
+ const alias = asAlias ?? peeled.alias;
17235
+ const rest = meta ?? "";
17218
17236
  const { tags } = extractPipeMetadata(rest);
17219
17237
  warnUnknownMetaKeys(
17220
17238
  tags,
17221
17239
  withTagAliases(INFRA_REGISTRY, tagAliasSet),
17222
17240
  (msg) => warn(lineNumber, msg)
17223
17241
  );
17224
- const id = nodeId2(name);
17225
- if (peeled.alias) nameAliasMap.set(peeled.alias, id);
17242
+ const id = nameAliasMap.get(name) ?? nodeId2(name);
17243
+ if (alias) nameAliasMap.set(alias, id);
17226
17244
  currentNode = {
17227
17245
  id,
17228
17246
  label: name,
@@ -17422,7 +17440,7 @@ var init_parser15 = __esm({
17422
17440
  DEPRECATED_FANOUT_RE = /\bx(\d+)\s*$/;
17423
17441
  GROUP_RE = /^\[([^\]]+)\]\s*(?:as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*)?((?:\|.*)|(?:[a-zA-Z_]\w*\s*:.*))?$/;
17424
17442
  TAG_VALUE_RE = /^(\w[\w\s]+?)\s*$/;
17425
- COMPONENT_RE = /^(?:"([^"]+)"|([a-zA-Z_][\w -]*?))\s*((?:\|.*)|(?:[a-zA-Z_]\w*\s*:.*))?$/;
17443
+ COMPONENT_RE = /^(?:"(?<qname>[^"]+)"|(?<uname>[a-zA-Z_][\w -]*?))(?:\s+as\s+(?<alias>[A-Za-z][A-Za-z0-9_]{0,11}))?\s*(?<meta>(?:\|.*)|(?:[a-zA-Z_]\w*\s*:.*))?$/;
17426
17444
  PIPE_META_RE = /[|,]\s*(\w+)\s*:\s*([^|,]+)/g;
17427
17445
  SAMELINE_META_RE = /(?:^|[\s,])(\w+)\s*:\s*([^,]+?)(?=\s*,|\s*$)/g;
17428
17446
  PROPERTY_RE = /^([\w-]+):\s*(.+)$/;
@@ -18906,8 +18924,8 @@ function parseMap(content, palette) {
18906
18924
  continue;
18907
18925
  }
18908
18926
  if (open.route && indent > open.route.indent) {
18909
- const leg = parseLeg(trimmed, lineNumber, open.route.route.style);
18910
- open.route.route.legs.push(leg);
18927
+ const leg = parseLeg(trimmed, lineNumber);
18928
+ if (leg) open.route.route.legs.push(leg);
18911
18929
  continue;
18912
18930
  }
18913
18931
  if (open.poi && indent > open.poi.indent) {
@@ -18936,6 +18954,14 @@ function parseMap(content, palette) {
18936
18954
  Object.assign(open.poi.poi.meta, split.meta);
18937
18955
  continue;
18938
18956
  }
18957
+ if (split.name) {
18958
+ const src = open.poi.poi.alias ?? poiName(open.poi.poi.pos) ?? "the poi";
18959
+ pushError(
18960
+ lineNumber,
18961
+ `Malformed hub edge: "${trimmed}" \u2014 an indented line under a poi is an edge from "${src}" and needs an arrow glyph (\`-> dest\`, \`~> dest\`, or labeled \`-label-> dest\`). For a standalone place, declare it at the top level. (\xA724B.5)`
18962
+ );
18963
+ continue;
18964
+ }
18939
18965
  }
18940
18966
  closeBlocks();
18941
18967
  const firstWord = trimmed.split(/\s+/)[0];
@@ -19184,31 +19210,44 @@ function parseMap(content, palette) {
19184
19210
  const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
19185
19211
  const originLabel = meta["label"];
19186
19212
  const originValue = meta["value"];
19187
- const style = meta["style"] === "arc" ? "arc" : "straight";
19213
+ if (meta["style"] !== void 0) {
19214
+ pushError(
19215
+ line11,
19216
+ "route header no longer takes `style:` \u2014 set leg shape with the arrow glyph instead (`~\u2026~>` for an arc leg, `-\u2026->` for a straight one). (\xA724B.6)"
19217
+ );
19218
+ }
19188
19219
  const route = {
19189
19220
  origin: pos,
19190
19221
  ...split.alias !== void 0 && { originAlias: split.alias },
19191
19222
  ...originLabel !== void 0 && { originLabel },
19192
19223
  ...originValue !== void 0 && { originValue },
19193
19224
  originTags: tags,
19194
- style,
19195
19225
  legs: [],
19196
19226
  lineNumber: line11
19197
19227
  };
19198
19228
  routes.push(route);
19199
19229
  open.route = { route, indent };
19200
19230
  }
19201
- function parseLeg(trimmed, line11, headerStyle) {
19202
- let arrowStyle = "straight";
19203
- let label;
19204
- let rest = trimmed;
19231
+ function parseLeg(trimmed, line11) {
19205
19232
  const m = trimmed.match(LEG_ARROW_RE);
19206
- if (m) {
19207
- const arr = classifyArrow(m[1], line11);
19208
- arrowStyle = arr.style;
19209
- label = arr.label;
19210
- rest = m[2];
19233
+ if (!m) {
19234
+ pushError(
19235
+ line11,
19236
+ `Malformed route leg: "${trimmed}" \u2014 a leg needs an arrow glyph (\`-> dest\`, \`~> dest\`, or labeled \`-label-> dest\` / \`~label~> dest\`). (\xA724B.6)`
19237
+ );
19238
+ return null;
19211
19239
  }
19240
+ const arr = classifyArrow(m[1], line11);
19241
+ if (!arr.directed) {
19242
+ pushError(
19243
+ line11,
19244
+ `A route leg is directional \u2014 "${trimmed}" uses an undirected glyph; use \`-> \` (straight) or \`~> \` (arc). (\xA724B.6)`
19245
+ );
19246
+ return null;
19247
+ }
19248
+ const arrowStyle = arr.style;
19249
+ const label = arr.label;
19250
+ const rest = m[2];
19212
19251
  const split = splitNameAndMeta(
19213
19252
  rest,
19214
19253
  registry(),
@@ -19224,10 +19263,9 @@ function parseMap(content, palette) {
19224
19263
  const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
19225
19264
  const value = meta["value"];
19226
19265
  const destLabel = meta["label"];
19227
- const style = arrowStyle === "arc" || headerStyle === "arc" ? "arc" : "straight";
19228
19266
  return {
19229
19267
  ...label !== void 0 && { label },
19230
- style,
19268
+ style: arrowStyle,
19231
19269
  ...value !== void 0 && { value },
19232
19270
  dest: pos,
19233
19271
  ...split.alias !== void 0 && { destAlias: split.alias },
@@ -53718,13 +53756,15 @@ function layoutMap(resolvedIn, data, size, opts) {
53718
53756
  labelY: lp.y
53719
53757
  };
53720
53758
  const routeLabelStyle = leg.label !== void 0 ? labelOnFill(fillAt(bow.labelX, bow.labelY)) : void 0;
53759
+ const routeVal = Number(leg.value);
53721
53760
  legs.push({
53722
53761
  d: legPath(a, b, bow.curved, bow.offset),
53723
- width: routeWidthFor(Number(leg.value)),
53762
+ width: routeWidthFor(routeVal),
53724
53763
  color: lineColor(leg.tags) ?? mix(palette.text, palette.bg, 72),
53725
53764
  arrow: true,
53726
53765
  fromId: leg.fromId,
53727
53766
  toId: leg.toId,
53767
+ ...Number.isFinite(routeVal) && routeVal > 0 && { value: routeVal },
53728
53768
  ...Object.keys(leg.tags).length > 0 && { tags: leg.tags },
53729
53769
  lineNumber: leg.lineNumber,
53730
53770
  ...leg.label !== void 0 && {
@@ -53771,6 +53811,7 @@ function layoutMap(resolvedIn, data, size, opts) {
53771
53811
  labelY: lp.y
53772
53812
  };
53773
53813
  const edgeLabelStyle = e.label !== void 0 ? labelOnFill(fillAt(bow.labelX, bow.labelY)) : void 0;
53814
+ const edgeVal = Number(e.meta["value"]);
53774
53815
  legs.push({
53775
53816
  d: legPath(a, b, bow.curved, bow.offset),
53776
53817
  width: widthFor(e),
@@ -53778,6 +53819,7 @@ function layoutMap(resolvedIn, data, size, opts) {
53778
53819
  arrow: e.directed,
53779
53820
  fromId: e.fromId,
53780
53821
  toId: e.toId,
53822
+ ...Number.isFinite(edgeVal) && edgeVal > 0 && { value: edgeVal },
53781
53823
  ...Object.keys(e.tags).length > 0 && { tags: e.tags },
53782
53824
  lineNumber: e.lineNumber,
53783
53825
  ...e.label !== void 0 && {
@@ -53935,18 +53977,49 @@ function layoutMap(resolvedIn, data, size, opts) {
53935
53977
  const SHORT_HOP_MAX = Math.max(46, Math.min(width, height) * 0.11);
53936
53978
  const STEP = 4;
53937
53979
  const HOP_GAP = 9;
53980
+ const CLEAR_STEP = 6;
53981
+ const CLEAR_MAX = SHORT_HOP_MAX * 3;
53982
+ const CLEAR_TOL = CLEAR_STEP;
53983
+ const clearanceAt = (px, py, ox, oy) => {
53984
+ const baseAng = Math.atan2(oy, ox);
53985
+ let minClear = CLEAR_MAX;
53986
+ for (let k = -2; k <= 2; k++) {
53987
+ const a = baseAng + k * Math.PI / 4;
53988
+ const rx = Math.cos(a);
53989
+ const ry = Math.sin(a);
53990
+ let d = CLEAR_STEP;
53991
+ for (; d <= CLEAR_MAX; d += CLEAR_STEP) {
53992
+ const qx = px + rx * d;
53993
+ const qy = py + ry * d;
53994
+ if (qx < FIT_PAD || qy < topPad || qx > width - FIT_PAD || qy > height - FIT_PAD)
53995
+ break;
53996
+ if (fillAt(qx, qy) !== water) break;
53997
+ }
53998
+ if (d < minClear) minClear = d;
53999
+ }
54000
+ return minClear;
54001
+ };
53938
54002
  const tryShortHopCallout = (cx, cy, fill2, name, value, font = FONT2, gap = HOP_GAP, maxLen = SHORT_HOP_MAX) => {
53939
54003
  const chipW = stackW(name, value, font);
53940
54004
  const chipH = stackH(value !== void 0, font);
54005
+ const D = Math.SQRT1_2;
53941
54006
  const dirs = [
53942
54007
  [0, -1],
53943
- // north (over Canada)
54008
+ // north
53944
54009
  [0, 1],
53945
- // south (over Mexico / Gulf)
54010
+ // south
53946
54011
  [1, 0],
53947
- // east (Atlantic)
53948
- [-1, 0]
53949
- // west (Pacific)
54012
+ // east
54013
+ [-1, 0],
54014
+ // west
54015
+ [D, -D],
54016
+ // NE
54017
+ [D, D],
54018
+ // SE
54019
+ [-D, -D],
54020
+ // NW
54021
+ [-D, D]
54022
+ // SW
53950
54023
  ];
53951
54024
  let best = null;
53952
54025
  for (const [dx, dy] of dirs) {
@@ -53996,13 +54069,16 @@ function layoutMap(resolvedIn, data, size, opts) {
53996
54069
  (p) => segmentRectOverlap(cx, cy, innerX, innerY, p)
53997
54070
  ))
53998
54071
  continue;
53999
- if (best === null || len < best.len)
54072
+ const clear = clearanceAt(ccx, ccy, dx, dy);
54073
+ const better = best === null || clear > best.clear + CLEAR_TOL || clear >= best.clear - CLEAR_TOL && len < best.len;
54074
+ if (better)
54000
54075
  best = {
54001
54076
  x: ccx,
54002
54077
  y: ccy,
54003
54078
  rect,
54004
54079
  leader: [cx, cy, innerX, innerY],
54005
- len
54080
+ len,
54081
+ clear
54006
54082
  };
54007
54083
  }
54008
54084
  return best ? { x: best.x, y: best.y, rect: best.rect, leader: best.leader } : null;
@@ -54663,6 +54739,9 @@ function layoutMap(resolvedIn, data, size, opts) {
54663
54739
  const nx = -dy / len;
54664
54740
  const ny = dx / len;
54665
54741
  const perp = labelH + 2;
54742
+ const stroke2 = lg.width ?? W_MIN;
54743
+ const clearW = stroke2 / 2 + labelH / 2 + 3;
54744
+ const offList = stroke2 >= 4 ? [clearW, -clearW, clearW + perp, -(clearW + perp), 0] : [0, perp, -perp, 2 * perp, -2 * perp];
54666
54745
  const pm = /^M(-?[\d.]+),(-?[\d.]+)(?:L(-?[\d.]+),(-?[\d.]+)|Q(-?[\d.]+),(-?[\d.]+) (-?[\d.]+),(-?[\d.]+))$/.exec(
54667
54746
  lg.d
54668
54747
  );
@@ -54682,7 +54761,7 @@ function layoutMap(resolvedIn, data, size, opts) {
54682
54761
  return [a.cx + dx * t, a.cy + dy * t];
54683
54762
  };
54684
54763
  const candidates = [];
54685
- for (const off of [0, perp, -perp, 2 * perp, -2 * perp])
54764
+ for (const off of offList)
54686
54765
  for (const t of T_LIST) {
54687
54766
  const [bx, by] = pointAt(t);
54688
54767
  candidates.push([bx + nx * off, by + ny * off - 4]);
@@ -55434,6 +55513,12 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
55434
55513
  }
55435
55514
  }
55436
55515
  wireSync(p, leg.lineNumber);
55516
+ if (leg.value !== void 0) {
55517
+ p.attr("data-value", leg.value);
55518
+ p.append("title").text(
55519
+ leg.label !== void 0 ? `${leg.label}: ${leg.value}` : `${leg.value}`
55520
+ );
55521
+ }
55437
55522
  if (arrowTri) {
55438
55523
  gLegs.append("path").attr("d", arrowTri).attr("fill", leg.color).attr("stroke", leg.color).attr("stroke-width", 1).attr("stroke-linejoin", "round").attr("data-from-id", leg.fromId).attr("data-to-id", leg.toId);
55439
55524
  }
@@ -59064,9 +59149,9 @@ var init_renderer20 = __esm({
59064
59149
  }
59065
59150
  });
59066
59151
 
59067
- // ../../diagrammo/dgmo/node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
59152
+ // node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
59068
59153
  var require_lz_string = __commonJS({
59069
- "../../diagrammo/dgmo/node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports2, module2) {
59154
+ "node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports2, module2) {
59070
59155
  "use strict";
59071
59156
  var LZString = (function() {
59072
59157
  var f = String.fromCharCode;