@transitrix/diagrams 1.8.19 → 1.8.20

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.
@@ -21,6 +21,22 @@ export interface ValidateGridOptions {
21
21
  /** Extra template-level rules to run once the base grid is well-formed. */
22
22
  rules?: GridRule[];
23
23
  }
24
+ /**
25
+ * Element-level TYPE registry — IDS_AND_REFERENCES.md §3.1, plus
26
+ * `VERIFICATION` (§3.7): block diagrams cross-reference the full
27
+ * hazard → risk-control → requirement → verification chain, and
28
+ * `VERIFICATION` is the terminal link in that chain.
29
+ *
30
+ * `FACTOR` and `ACTIVITY` are kept alongside their canonical replacements
31
+ * `DRIVER` and `ACTION` — both still-valid grandfathered/deprecated aliases
32
+ * per §3.1 and §6, not yet forced to migrate.
33
+ *
34
+ * `UNIT`/`EMPLOYEE` (replaced by `ACTOR`, removed from canon 2026-05-29) and
35
+ * `ISSUE` (retired 2026-06-07, no replacement TYPE — see methodology
36
+ * `docs/decisions/2026-06-07-retire-model-issue-type.md`) are deliberately
37
+ * not carried forward. `STAGE` was never a canonical TYPE.
38
+ */
39
+ export declare const REGISTERED_ELEMENT_TYPES: Set<string>;
24
40
  export declare function validateNestedBlocks(input: unknown): ValidationResult;
25
41
  /** Matrix subset (§4a): validate a `grid:` root document — BL-021..BL-025. */
26
42
  export declare function validateGrid(input: unknown, options?: ValidateGridOptions): ValidationResult;
@@ -18,23 +18,55 @@ const CANONICAL_ID_RE = /^[A-Z][A-Z0-9_]*(-[A-Z0-9][A-Z0-9_]*)+-\d+$/;
18
18
  * dot, so we recognise it separately.
19
19
  */
20
20
  const CAPABILITY_ID_RE = /^CAPABILITY-[VH]\d+(\.\d+){0,2}$/;
21
- /** Element-level TYPE registry — IDS_AND_REFERENCES.md §3.1. */
22
- const REGISTERED_ELEMENT_TYPES = new Set([
21
+ /**
22
+ * Element-level TYPE registry — IDS_AND_REFERENCES.md §3.1, plus
23
+ * `VERIFICATION` (§3.7): block diagrams cross-reference the full
24
+ * hazard → risk-control → requirement → verification chain, and
25
+ * `VERIFICATION` is the terminal link in that chain.
26
+ *
27
+ * `FACTOR` and `ACTIVITY` are kept alongside their canonical replacements
28
+ * `DRIVER` and `ACTION` — both still-valid grandfathered/deprecated aliases
29
+ * per §3.1 and §6, not yet forced to migrate.
30
+ *
31
+ * `UNIT`/`EMPLOYEE` (replaced by `ACTOR`, removed from canon 2026-05-29) and
32
+ * `ISSUE` (retired 2026-06-07, no replacement TYPE — see methodology
33
+ * `docs/decisions/2026-06-07-retire-model-issue-type.md`) are deliberately
34
+ * not carried forward. `STAGE` was never a canonical TYPE.
35
+ */
36
+ export const REGISTERED_ELEMENT_TYPES = new Set([
37
+ 'DRIVER',
23
38
  'FACTOR',
24
39
  'GOAL',
25
40
  'CHANGE',
41
+ 'ACTION',
26
42
  'ACTIVITY',
27
43
  'CAPABILITY',
28
44
  'PROCESS',
45
+ 'STEP',
29
46
  'PRODUCT',
30
47
  'APPLICATION',
31
48
  'INTEGRATION',
32
49
  'ROLE',
33
- 'UNIT',
34
- 'EMPLOYEE',
50
+ 'ACTOR',
51
+ 'LOCATION',
52
+ 'BUSINESS_SERVICE',
35
53
  'SCENARIO',
36
- 'ISSUE',
37
- 'STAGE',
54
+ 'EQUIPMENT',
55
+ 'NODE',
56
+ 'TECHNOLOGY_SERVICE',
57
+ 'BUSINESS_OBJECT',
58
+ 'RULE',
59
+ 'REGISTRY',
60
+ 'CONSTRAINT',
61
+ 'REQUIREMENT',
62
+ 'STAKEHOLDER',
63
+ 'ASSESSMENT',
64
+ 'HAZARD',
65
+ 'RISK_CONTROL',
66
+ 'TARGET_STATE',
67
+ 'REL',
68
+ 'MILESTONE',
69
+ 'VERIFICATION',
38
70
  ]);
39
71
  /**
40
72
  * Recommended maximum nesting depth (1-indexed). The spec warns at depth 6+;
@@ -12,13 +12,16 @@ export declare const ACTIVITIES_NETWORK_CSS = "\n .act-node { fill: var(--ts-la
12
12
  export declare const ACTIVITIES_NETWORK_DEFS = "<defs>\n <marker id=\"arrow\" markerWidth=\"8\" markerHeight=\"8\" refX=\"8\" refY=\"3\" orient=\"auto\">\n <path d=\"M0,0 L0,6 L8,3 z\" class=\"arrow-fill\"/>\n </marker>\n <marker id=\"arrow-crit\" markerWidth=\"8\" markerHeight=\"8\" refX=\"8\" refY=\"3\" orient=\"auto\">\n <path d=\"M0,0 L0,6 L8,3 z\" class=\"arrow-fill-critical\"/>\n </marker>\n</defs>";
13
13
  /**
14
14
  * Extra top padding (px) a network-view canvas must add so skip-edge bows
15
- * (see `blockingNodes`/`bowY` above) never draw above the SVG's y=0 and get
16
- * clipped. `oyBase` is the canvas's Y offset *before* this padding — the
17
- * historical `-bounds.y + N_PAD + titleH` both hosts compute — since a bow
18
- * near the topmost row can reach above the diagram's own node bounds.
19
- * Callers add the returned value to both `oyBase` and the canvas height.
15
+ * (see `blockingNodes`/`bowY` above) never rise above the diagram's own node
16
+ * bounds (`layout.bounds.y`). Node rows shift down by the returned amount to
17
+ * make room for the bow within the diagram area; the title block — drawn
18
+ * separately, above that area, at a fixed position independent of this pad —
19
+ * is left undisturbed, so the bow can never climb into the reserved title
20
+ * zone (the earlier version floored against the canvas's literal y=0, which
21
+ * let a tall bow draw straight through the title text sitting between 0 and
22
+ * the diagram's un-padded top).
20
23
  */
21
- export declare function computeNetworkTopPad(layout: ActivitiesLayout, oyBase: number): number;
24
+ export declare function computeNetworkTopPad(layout: ActivitiesLayout): number;
22
25
  /**
23
26
  * Canonical Network (PSND) body — the node rects and edge paths that go inside
24
27
  * the `<svg>`, shared verbatim by the VS Code preview and the host-neutral
@@ -85,13 +85,16 @@ function bowY(blockers) {
85
85
  }
86
86
  /**
87
87
  * Extra top padding (px) a network-view canvas must add so skip-edge bows
88
- * (see `blockingNodes`/`bowY` above) never draw above the SVG's y=0 and get
89
- * clipped. `oyBase` is the canvas's Y offset *before* this padding — the
90
- * historical `-bounds.y + N_PAD + titleH` both hosts compute — since a bow
91
- * near the topmost row can reach above the diagram's own node bounds.
92
- * Callers add the returned value to both `oyBase` and the canvas height.
88
+ * (see `blockingNodes`/`bowY` above) never rise above the diagram's own node
89
+ * bounds (`layout.bounds.y`). Node rows shift down by the returned amount to
90
+ * make room for the bow within the diagram area; the title block — drawn
91
+ * separately, above that area, at a fixed position independent of this pad —
92
+ * is left undisturbed, so the bow can never climb into the reserved title
93
+ * zone (the earlier version floored against the canvas's literal y=0, which
94
+ * let a tall bow draw straight through the title text sitting between 0 and
95
+ * the diagram's un-padded top).
93
96
  */
94
- export function computeNetworkTopPad(layout, oyBase) {
97
+ export function computeNetworkTopPad(layout) {
95
98
  const nodeMap = new Map(layout.nodes.map((n) => [n.id, n]));
96
99
  let pad = 0;
97
100
  for (const e of layout.edges) {
@@ -102,7 +105,7 @@ export function computeNetworkTopPad(layout, oyBase) {
102
105
  const blockers = blockingNodes(layout.nodes, s, t);
103
106
  if (blockers.length === 0)
104
107
  continue;
105
- const shortfall = -(oyBase + bowY(blockers));
108
+ const shortfall = layout.bounds.y - bowY(blockers);
106
109
  if (shortfall > pad)
107
110
  pad = shortfall;
108
111
  }
@@ -209,7 +212,7 @@ export function renderActivitiesSvg(doc, options = {}) {
209
212
  const cpm = computeCpm(renderDoc.activities ?? []);
210
213
  const titleH = title ? 24 : 0;
211
214
  const oyBase = -layout.bounds.y + N_PAD + titleH;
212
- const topPad = computeNetworkTopPad(layout, oyBase);
215
+ const topPad = computeNetworkTopPad(layout);
213
216
  const w = layout.bounds.width + N_PAD * 2;
214
217
  const h = layout.bounds.height + N_PAD * 2 + titleH + topPad;
215
218
  const ox = -layout.bounds.x + N_PAD;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transitrix/diagrams",
3
- "version": "1.8.19",
3
+ "version": "1.8.20",
4
4
  "type": "module",
5
5
  "description": "Shared rendering, validation, and pure mutations for Transitrix custom diagram formats.",
6
6
  "license": "MIT",
@@ -45,23 +45,55 @@ const CANONICAL_ID_RE = /^[A-Z][A-Z0-9_]*(-[A-Z0-9][A-Z0-9_]*)+-\d+$/;
45
45
  */
46
46
  const CAPABILITY_ID_RE = /^CAPABILITY-[VH]\d+(\.\d+){0,2}$/;
47
47
 
48
- /** Element-level TYPE registry — IDS_AND_REFERENCES.md §3.1. */
49
- const REGISTERED_ELEMENT_TYPES = new Set<string>([
48
+ /**
49
+ * Element-level TYPE registry — IDS_AND_REFERENCES.md §3.1, plus
50
+ * `VERIFICATION` (§3.7): block diagrams cross-reference the full
51
+ * hazard → risk-control → requirement → verification chain, and
52
+ * `VERIFICATION` is the terminal link in that chain.
53
+ *
54
+ * `FACTOR` and `ACTIVITY` are kept alongside their canonical replacements
55
+ * `DRIVER` and `ACTION` — both still-valid grandfathered/deprecated aliases
56
+ * per §3.1 and §6, not yet forced to migrate.
57
+ *
58
+ * `UNIT`/`EMPLOYEE` (replaced by `ACTOR`, removed from canon 2026-05-29) and
59
+ * `ISSUE` (retired 2026-06-07, no replacement TYPE — see methodology
60
+ * `docs/decisions/2026-06-07-retire-model-issue-type.md`) are deliberately
61
+ * not carried forward. `STAGE` was never a canonical TYPE.
62
+ */
63
+ export const REGISTERED_ELEMENT_TYPES = new Set<string>([
64
+ 'DRIVER',
50
65
  'FACTOR',
51
66
  'GOAL',
52
67
  'CHANGE',
68
+ 'ACTION',
53
69
  'ACTIVITY',
54
70
  'CAPABILITY',
55
71
  'PROCESS',
72
+ 'STEP',
56
73
  'PRODUCT',
57
74
  'APPLICATION',
58
75
  'INTEGRATION',
59
76
  'ROLE',
60
- 'UNIT',
61
- 'EMPLOYEE',
77
+ 'ACTOR',
78
+ 'LOCATION',
79
+ 'BUSINESS_SERVICE',
62
80
  'SCENARIO',
63
- 'ISSUE',
64
- 'STAGE',
81
+ 'EQUIPMENT',
82
+ 'NODE',
83
+ 'TECHNOLOGY_SERVICE',
84
+ 'BUSINESS_OBJECT',
85
+ 'RULE',
86
+ 'REGISTRY',
87
+ 'CONSTRAINT',
88
+ 'REQUIREMENT',
89
+ 'STAKEHOLDER',
90
+ 'ASSESSMENT',
91
+ 'HAZARD',
92
+ 'RISK_CONTROL',
93
+ 'TARGET_STATE',
94
+ 'REL',
95
+ 'MILESTONE',
96
+ 'VERIFICATION',
65
97
  ]);
66
98
 
67
99
  /**
@@ -100,13 +100,16 @@ function bowY(blockers: ActivityLayoutNode[]): number {
100
100
 
101
101
  /**
102
102
  * Extra top padding (px) a network-view canvas must add so skip-edge bows
103
- * (see `blockingNodes`/`bowY` above) never draw above the SVG's y=0 and get
104
- * clipped. `oyBase` is the canvas's Y offset *before* this padding — the
105
- * historical `-bounds.y + N_PAD + titleH` both hosts compute — since a bow
106
- * near the topmost row can reach above the diagram's own node bounds.
107
- * Callers add the returned value to both `oyBase` and the canvas height.
103
+ * (see `blockingNodes`/`bowY` above) never rise above the diagram's own node
104
+ * bounds (`layout.bounds.y`). Node rows shift down by the returned amount to
105
+ * make room for the bow within the diagram area; the title block — drawn
106
+ * separately, above that area, at a fixed position independent of this pad —
107
+ * is left undisturbed, so the bow can never climb into the reserved title
108
+ * zone (the earlier version floored against the canvas's literal y=0, which
109
+ * let a tall bow draw straight through the title text sitting between 0 and
110
+ * the diagram's un-padded top).
108
111
  */
109
- export function computeNetworkTopPad(layout: ActivitiesLayout, oyBase: number): number {
112
+ export function computeNetworkTopPad(layout: ActivitiesLayout): number {
110
113
  const nodeMap = new Map(layout.nodes.map((n) => [n.id, n]));
111
114
  let pad = 0;
112
115
  for (const e of layout.edges) {
@@ -115,7 +118,7 @@ export function computeNetworkTopPad(layout: ActivitiesLayout, oyBase: number):
115
118
  if (!s || !t) continue;
116
119
  const blockers = blockingNodes(layout.nodes, s, t);
117
120
  if (blockers.length === 0) continue;
118
- const shortfall = -(oyBase + bowY(blockers));
121
+ const shortfall = layout.bounds.y - bowY(blockers);
119
122
  if (shortfall > pad) pad = shortfall;
120
123
  }
121
124
  return pad;
@@ -278,7 +281,7 @@ export function renderActivitiesSvg(doc: ActivityDoc, options: RenderActivitiesO
278
281
  const cpm = computeCpm(renderDoc.activities ?? []);
279
282
  const titleH = title ? 24 : 0;
280
283
  const oyBase = -layout.bounds.y + N_PAD + titleH;
281
- const topPad = computeNetworkTopPad(layout, oyBase);
284
+ const topPad = computeNetworkTopPad(layout);
282
285
  const w = layout.bounds.width + N_PAD * 2;
283
286
  const h = layout.bounds.height + N_PAD * 2 + titleH + topPad;
284
287
  const ox = -layout.bounds.x + N_PAD;