@weasel-js/diagram 1.13.0 → 1.14.1

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.
Files changed (35) hide show
  1. package/README.md +122 -17
  2. package/dist/{chunk-Y72FK3Y7.js → chunk-5VNPLOIX.js} +94 -6
  3. package/dist/chunk-5VNPLOIX.js.map +1 -0
  4. package/dist/{chunk-ESFIS7BB.js → chunk-62SMY45E.js} +918 -574
  5. package/dist/chunk-62SMY45E.js.map +1 -0
  6. package/dist/{chunk-FAQXYGMX.js → chunk-TBG6DFB2.js} +3 -3
  7. package/dist/{chunk-FAQXYGMX.js.map → chunk-TBG6DFB2.js.map} +1 -1
  8. package/dist/{chunk-L4H444QI.js → chunk-VB6HUKNG.js} +659 -185
  9. package/dist/chunk-VB6HUKNG.js.map +1 -0
  10. package/dist/{chunk-QU4QZUC6.js → chunk-ZWXM5F4I.js} +141 -39
  11. package/dist/chunk-ZWXM5F4I.js.map +1 -0
  12. package/dist/{dataTypes-DW-MljuN.d.ts → dataTypes-BIkhAOc4.d.ts} +13 -2
  13. package/dist/effect-audio.d.ts +2 -1
  14. package/dist/effect-audio.js +6 -5
  15. package/dist/effect-audio.js.map +1 -1
  16. package/dist/effect.d.ts +46 -16
  17. package/dist/effect.js +257 -102
  18. package/dist/effect.js.map +1 -1
  19. package/dist/icons.table.js +262 -0
  20. package/dist/icons.table.js.map +1 -1
  21. package/dist/icons.table.json +262 -0
  22. package/dist/index.d.ts +491 -167
  23. package/dist/index.js +586 -36
  24. package/dist/index.js.map +1 -1
  25. package/dist/labelTrait-BBjRgxbz.d.ts +44 -0
  26. package/dist/layout.d.ts +4 -3
  27. package/dist/{layout.entry-CQoPNfzA.d.ts → layout.entry-Ca6pVvqo.d.ts} +23 -2
  28. package/dist/layout.js +2 -2
  29. package/dist/{stageTypes-DvnR8cKQ.d.ts → stageTypes-UiO25hcn.d.ts} +7 -0
  30. package/dist/{types-vbW21fHm.d.ts → types-B0n2CNTW.d.ts} +108 -81
  31. package/package.json +11 -9
  32. package/dist/chunk-ESFIS7BB.js.map +0 -1
  33. package/dist/chunk-L4H444QI.js.map +0 -1
  34. package/dist/chunk-QU4QZUC6.js.map +0 -1
  35. package/dist/chunk-Y72FK3Y7.js.map +0 -1
@@ -0,0 +1,44 @@
1
+ import { Vec2 } from '@weasel-js/core/math';
2
+
3
+ /**
4
+ * The label trait: where along its edge a label sits. Data only — placing the
5
+ * label on the route is `label`'s job, so layout can read one without
6
+ * reaching the scene.
7
+ */
8
+
9
+ /** Where along an edge a label sits. */
10
+ interface DiagramLabel {
11
+ /** `'start'`, `'mid'` and `'end'` are 0, 0.5 and 1; a number is that
12
+ * fraction of the route's length. `{ near }` is the point on the route
13
+ * nearest `near`, in world coordinates — where `layered` leaves a label
14
+ * room — so a bend added or removed elsewhere leaves the label on the
15
+ * stretch it was on. */
16
+ at: 'start' | 'mid' | 'end' | number | {
17
+ near: Vec2;
18
+ };
19
+ /** World units between the route and the label's near side, to the **left
20
+ * of the direction of travel** — above a left-to-right edge. Default 0,
21
+ * which centers the label on the line. */
22
+ offset?: number;
23
+ /** Where label placement moved it, off a station something covered:
24
+ * `at` a fraction of the route's length, `offset` as above. Read in place
25
+ * of `at` and `offset`, which stay the author's preference. Written only
26
+ * by placement (`installLabelPlacement`). */
27
+ placed?: LabelSpot;
28
+ /** `false` keeps placement from ever moving this label. */
29
+ dodge?: false;
30
+ }
31
+ /** A station placement chose: a fraction of the route's length, and the
32
+ * offset from the line. */
33
+ interface LabelSpot {
34
+ at: number;
35
+ offset: number;
36
+ }
37
+ /** Where an edge label sits when neither the edge nor the scene says. */
38
+ declare const LABEL_PLACEMENT: DiagramLabel;
39
+ /** The label trait on a node's data, or `null`. */
40
+ declare function diagramLabelOf(node: {
41
+ data: unknown;
42
+ }): DiagramLabel | null;
43
+
44
+ export { type DiagramLabel as D, type LabelSpot as L, LABEL_PLACEMENT as a, diagramLabelOf as d };
package/dist/layout.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export { t as BodyFloor, B as BodySpec, m as Bounds, w as DEFAULT_HOP_SIZE, x as DEFAULT_NODE_GAP, y as DEFAULT_RANK_GAP, c as DiagramLabel, f as DiagramNode, E as EdgeHop, H as EdgeLabelRoom, G as Graph, I as GraphEdge, J as GraphGroup, K as GraphNode, Q as HOPS_DOC_KEY, T as HopsDocValue, l as LabelSpot, V as LayoutAxes, q as LayoutDirection, d as LayoutFn, e as LayoutOptions, r as LayoutPlan, p as LayoutPlanner, L as LayoutPorts, n as LayoutResult, M as MeasureRowText, O as Outline, g as Port, P as PortAnchor, W as PortSite, b as PortSpec, a as Row, X as RowBox, Y as RowPort, Z as RowPortBox, R as RowTextStyle, _ as Slot, $ as anchorOffset, a0 as axesFor, a2 as bodyOutline, a4 as boxForContent, a6 as canvasMeasure, a7 as contentBox, ay as extent, ae as graphOrder, ai as layoutBody, aj as layoutRowPorts, ak as measureBody, al as outlinePath, am as packAcross, ao as pinnedSet, ap as planOf, aq as plannerPlan, as as seededOrder, at as settle, au as sizeToBody, aw as translated, ax as untilSettled } from './types-vbW21fHm.js';
2
- export { e as AVOID_DEFAULTS, f as AvoidEdge, g as AvoidEnd, A as AvoidInput, h as AvoidLabel, i as AvoidObstacle, b as AvoidOptions, j as AvoidPort, a as AvoidRouter, c as AvoidRoutes, k as AvoidUpdateOptions, B as BodyNodeSpec, l as BuildBodyOptions, C as COMPASS, D as DEFAULT_PORTS, m as ForceBody, F as ForceOptions, n as ForceRelaxation, L as LabelPlacements, p as LayeredPlan, q as PORT_LABEL_GAP, r as PerimeterPortLabelBox, s as PlaceLabel, t as PlaceLabelsInput, d as PlaceLabelsOptions, u as PlaceRoute, P as PortsOptions, R as RowNodeData, w as backEdges, x as buildBody, y as chain, z as createAvoidRouter, E as edgeHops, G as footprintNode, H as force, I as forceRelaxation, J as forestOf, K as labelCenter, M as layered, N as layeredPlan, O as marginOf, Q as outlinePolyline, S as placeLabels, T as portLabelBox, V as portOf, W as portSitesOf, X as portsOf, Y as portsOnOutline, Z as ranksByLength, _ as ranksOf, $ as rayHit, a0 as routeHolds, a1 as tree } from './layout.entry-CQoPNfzA.js';
3
- import '@weasel-js/core/math';
1
+ export { s as BodyFloor, B as BodySpec, k as Bounds, v as BuiltinOutline, x as DEFAULT_HOP_SIZE, y as DEFAULT_NODE_GAP, z as DEFAULT_RANK_GAP, e as DiagramNode, E as EdgeHop, J as EdgeLabelRoom, G as Graph, K as GraphEdge, N as GraphGroup, Q as GraphNode, U as HOPS_DOC_KEY, V as HopsDocValue, W as LayoutAxes, o as LayoutDirection, c as LayoutFn, d as LayoutOptions, p as LayoutPlan, n as LayoutPlanner, L as LayoutPorts, l as LayoutResult, M as MeasureRowText, O as Outline, X as OutlineDef, f as Port, P as PortAnchor, Y as PortSite, b as PortSpec, a as Row, Z as RowBox, _ as RowPort, $ as RowPortBox, R as RowTextStyle, a0 as Slot, a1 as anchorOffset, a2 as axesFor, a4 as bodyOutline, a6 as boxForContent, a8 as canvasMeasure, a9 as contentBox, aB as extent, af as graphOrder, aj as layoutBody, ak as layoutRowPorts, al as measureBody, am as outlineDetail, an as outlinePath, ao as packAcross, aq as pinnedSet, ar as planOf, as as plannerPlan, au as registerOutline, av as seededOrder, aw as settle, ax as sizeToBody, az as translated, aA as untilSettled } from './types-B0n2CNTW.js';
2
+ export { e as AVOID_DEFAULTS, f as AvoidEdge, g as AvoidEnd, A as AvoidInput, h as AvoidLabel, i as AvoidObstacle, b as AvoidOptions, j as AvoidPort, a as AvoidRouter, c as AvoidRoutes, k as AvoidUpdateOptions, B as BodyNodeSpec, l as BuildBodyOptions, C as COMPASS, D as DEFAULT_PORTS, m as ForceBody, F as ForceOptions, n as ForceRelaxation, L as LabelPlacements, p as LayeredPlan, q as PORT_LABEL_GAP, r as PerimeterPortLabelBox, s as PlaceLabel, t as PlaceLabelsInput, d as PlaceLabelsOptions, u as PlaceRoute, P as PortsOptions, R as RowNodeData, w as backEdges, x as buildBody, y as chain, z as createAvoidRouter, E as edgeHops, G as footprintNode, H as force, I as forceRelaxation, J as forestOf, K as labelCenter, M as layered, N as layeredPlan, O as marginOf, Q as outlineFromD, S as outlinePolyline, T as placeLabels, U as portLabelBox, W as portOf, X as portSitesOf, Y as portsOf, Z as portsOnOutline, _ as radial, $ as ranksByLength, a0 as ranksOf, a1 as rayHit, a2 as routeHolds, a3 as subtreeBlocks, a4 as tree } from './layout.entry-Ca6pVvqo.js';
3
+ export { D as DiagramLabel, L as LabelSpot } from './labelTrait-BBjRgxbz.js';
4
4
  import '@weasel-js/geom';
5
+ import '@weasel-js/core/math';
5
6
  import '@weasel-js/simulation';
@@ -1,6 +1,15 @@
1
- import { m as Bounds, b as PortSpec, g as Port, N as GroupInset, f as DiagramNode, M as MeasureRowText, X as RowBox, Z as RowPortBox, B as BodySpec, K as GraphNode, i as DiagramNodeReader, h as DiagramNodeLike, c as DiagramLabel, E as EdgeHop, l as LabelSpot, e as LayoutOptions, G as Graph, n as LayoutResult, d as LayoutFn, L as LayoutPorts, O as Outline } from './types-vbW21fHm.js';
1
+ import { k as Bounds, X as OutlineDef, b as PortSpec, f as Port, T as GroupInset, e as DiagramNode, M as MeasureRowText, Z as RowBox, $ as RowPortBox, B as BodySpec, Q as GraphNode, h as DiagramNodeReader, g as DiagramNodeLike, E as EdgeHop, d as LayoutOptions, G as Graph, l as LayoutResult, c as LayoutFn, L as LayoutPorts, O as Outline } from './types-B0n2CNTW.js';
2
2
  import { Vec2, PoseDescriptor, Path } from '@weasel-js/core/math';
3
3
  import { SimulationNode, createSimulation } from '@weasel-js/simulation';
4
+ import { D as DiagramLabel, L as LabelSpot } from './labelTrait-BBjRgxbz.js';
5
+
6
+ /** An outline from SVG path data in a unit square — `(0, 0)` the box's
7
+ * top-left, `(1, 1)` its bottom-right — stretched over each node's bounds.
8
+ * `content` is in the same unit square. */
9
+ declare function outlineFromD(d: string, opts?: {
10
+ detail?: string;
11
+ content?: Bounds;
12
+ }): OutlineDef;
4
13
 
5
14
  /**
6
15
  * Perimeter port labels: where the text naming a port is drawn, and how far
@@ -581,11 +590,23 @@ interface Forest {
581
590
  * node ended up whose child" is the question anyone debugging a tree layout
582
591
  * asks first. */
583
592
  declare function forestOf(graph: Graph, crossAxis: 'x' | 'y'): Forest;
593
+ /** Subtrees packed as solid blocks on one axis. `span` is how much room a node's
594
+ * whole subtree takes: its children's blocks side by side, or the node itself
595
+ * when that is wider. `lay` writes the low corner of every node in a subtree
596
+ * whose block starts at `from`, each parent centered over its children. */
597
+ declare function subtreeBlocks(children: ReadonlyMap<string, readonly GraphNode[]>, axis: 'x' | 'y', gap: number): {
598
+ span(node: GraphNode): number;
599
+ lay(node: GraphNode, from: number, into: Map<string, number>): void;
600
+ };
584
601
  /** The hierarchy layout: each parent centered over its children's block, one
585
602
  * rank per depth. A graph that is not a tree lays out as the forest
586
603
  * {@link forestOf} reads from it. */
587
604
  declare const tree: LayoutFn;
588
605
 
606
+ /** The mind-map layout: the first root in the middle, its branches balanced
607
+ * to its right and its left, any further trees stacked below. */
608
+ declare const radial: LayoutFn;
609
+
589
610
  /** The outline as a closed polyline: `[x0, y0, x1, y1, …]`. */
590
611
  declare function outlinePolyline(outline: Outline, bounds: Bounds): number[];
591
612
  /**
@@ -611,4 +632,4 @@ declare function rayHit(poly: readonly number[], center: {
611
632
  */
612
633
  declare function portsOnOutline(ports: readonly Port[], outline: Outline, bounds: Bounds): Port[];
613
634
 
614
- export { rayHit as $, type AvoidInput as A, type BodyNodeSpec as B, COMPASS as C, DEFAULT_PORTS as D, edgeHops as E, type ForceOptions as F, footprintNode as G, force as H, forceRelaxation as I, forestOf as J, labelCenter as K, type LabelPlacements as L, layered as M, layeredPlan as N, marginOf as O, type PortsOptions as P, outlinePolyline as Q, type RowNodeData as R, placeLabels as S, portLabelBox as T, portLabelsOf as U, portOf as V, portSitesOf as W, portsOf as X, portsOnOutline as Y, ranksByLength as Z, ranksOf as _, type AvoidRouter as a, routeHolds as a0, tree as a1, type AvoidOptions as b, type AvoidRoutes as c, type PlaceLabelsOptions as d, AVOID_DEFAULTS as e, type AvoidEdge as f, type AvoidEnd as g, type AvoidLabel as h, type AvoidObstacle as i, type AvoidPort as j, type AvoidUpdateOptions as k, type BuildBodyOptions as l, type ForceBody as m, type ForceRelaxation as n, type Forest as o, type LayeredPlan as p, PORT_LABEL_GAP as q, type PerimeterPortLabelBox as r, type PlaceLabel as s, type PlaceLabelsInput as t, type PlaceRoute as u, type PortLabelPlacement as v, backEdges as w, buildBody as x, chain as y, createAvoidRouter as z };
635
+ export { ranksByLength as $, type AvoidInput as A, type BodyNodeSpec as B, COMPASS as C, DEFAULT_PORTS as D, edgeHops as E, type ForceOptions as F, footprintNode as G, force as H, forceRelaxation as I, forestOf as J, labelCenter as K, type LabelPlacements as L, layered as M, layeredPlan as N, marginOf as O, type PortsOptions as P, outlineFromD as Q, type RowNodeData as R, outlinePolyline as S, placeLabels as T, portLabelBox as U, portLabelsOf as V, portOf as W, portSitesOf as X, portsOf as Y, portsOnOutline as Z, radial as _, type AvoidRouter as a, ranksOf as a0, rayHit as a1, routeHolds as a2, subtreeBlocks as a3, tree as a4, type AvoidOptions as b, type AvoidRoutes as c, type PlaceLabelsOptions as d, AVOID_DEFAULTS as e, type AvoidEdge as f, type AvoidEnd as g, type AvoidLabel as h, type AvoidObstacle as i, type AvoidPort as j, type AvoidUpdateOptions as k, type BuildBodyOptions as l, type ForceBody as m, type ForceRelaxation as n, type Forest as o, type LayeredPlan as p, PORT_LABEL_GAP as q, type PerimeterPortLabelBox as r, type PlaceLabel as s, type PlaceLabelsInput as t, type PlaceRoute as u, type PortLabelPlacement as v, backEdges as w, buildBody as x, chain as y, createAvoidRouter as z };
package/dist/layout.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import './chunk-WDIE35AK.js';
2
- export { AVOID_DEFAULTS, DEFAULT_HOP_SIZE, HOPS_DOC_KEY, createAvoidRouter, edgeHops, placeLabels } from './chunk-Y72FK3Y7.js';
3
- export { COMPASS, DEFAULT_NODE_GAP, DEFAULT_PORTS, DEFAULT_RANK_GAP, PORT_LABEL_GAP, anchorOffset, axesFor, backEdges, bodyOutline, boxForContent, buildBody, canvasMeasure, chain, contentBox, extent, footprintNode, force, forceRelaxation, forestOf, graphOrder, labelCenter, layered, layeredPlan, layoutBody, layoutRowPorts, marginOf, measureBody, outlinePath, outlinePolyline, packAcross, pinnedSet, planOf, plannerPlan, portLabelBox, portOf, portSitesOf, portsOf, portsOnOutline, ranksByLength, ranksOf, rayHit, routeHolds, seededOrder, settle, sizeToBody, translated, tree, untilSettled } from './chunk-L4H444QI.js';
2
+ export { AVOID_DEFAULTS, DEFAULT_HOP_SIZE, HOPS_DOC_KEY, createAvoidRouter, edgeHops, placeLabels, radial } from './chunk-5VNPLOIX.js';
3
+ export { COMPASS, DEFAULT_NODE_GAP, DEFAULT_PORTS, DEFAULT_RANK_GAP, PORT_LABEL_GAP, anchorOffset, axesFor, backEdges, bodyOutline, boxForContent, buildBody, canvasMeasure, chain, contentBox, extent, footprintNode, force, forceRelaxation, forestOf, graphOrder, labelCenter, layered, layeredPlan, layoutBody, layoutRowPorts, marginOf, measureBody, outlineDetail, outlineFromD, outlinePath, outlinePolyline, packAcross, pinnedSet, planOf, plannerPlan, portLabelBox, portOf, portSitesOf, portsOf, portsOnOutline, ranksByLength, ranksOf, rayHit, registerOutline, routeHolds, seededOrder, settle, sizeToBody, subtreeBlocks, translated, tree, untilSettled } from './chunk-VB6HUKNG.js';
4
4
  //# sourceMappingURL=layout.js.map
5
5
  //# sourceMappingURL=layout.js.map
@@ -1,5 +1,6 @@
1
1
  import { Page } from '@weasel-js/core';
2
2
  import { Vec2 } from '@weasel-js/core/math';
3
+ import { D as DiagramLabel } from './labelTrait-BBjRgxbz.js';
3
4
 
4
5
  /** An effects pipeline as plain data. It says what is wired to what and
5
6
  * nothing about how any of it is drawn. */
@@ -44,6 +45,9 @@ interface EffectPort {
44
45
  /** Default the id. */
45
46
  label?: string;
46
47
  type: string;
48
+ /** An input that takes any number of wires, which a runner combines: the
49
+ * audio runner sums them, as Web Audio does. Default one wire. */
50
+ many?: boolean;
47
51
  }
48
52
  /** A connection from one stage's output to another stage's input. */
49
53
  interface EffectWire {
@@ -147,6 +151,9 @@ interface EffectDoc {
147
151
  routes?: Readonly<Record<string, readonly Vec2[]>>;
148
152
  /** The routes a person drew under `rack` and `lanes`, by look, then by wire id. */
149
153
  lookRoutes?: LookRoutes;
154
+ /** Where a person put each wire's label, by wire id. Along the route and
155
+ * off it, so it holds under every look, and over where a look puts it. */
156
+ labels?: Readonly<Record<string, DiagramLabel>>;
150
157
  /** Each group's box under `nodeGraph`, by group id, beside the pipeline as
151
158
  * `places` is. A group with none fits its members. */
152
159
  groupBoxes?: Readonly<Record<string, EffectBox>>;
@@ -1,17 +1,5 @@
1
- import { Path, Vec2, PoseDescriptor } from '@weasel-js/core/math';
2
1
  import * as _weasel_js_geom from '@weasel-js/geom';
3
-
4
- /**
5
- * The shapes a built body can wear, as paths in the node's bounds.
6
- *
7
- * These are the flowchart vocabulary — a decision is a diamond, an I/O step a
8
- * parallelogram, a terminator a stadium, a demultiplexer a trapezoid, a preparation step a hexagon,
9
- * a connector an ellipse — plus `'rect'` for everything else and
10
- * a `Path` escape hatch for a shape the vocabulary does not have. The path is
11
- * built in world coordinates from the bounds it is given, the same way the
12
- * kit's own `clipFromPose` factories are; a custom `Path` is drawn in a unit
13
- * square and stretched over them, as a mark is.
14
- */
2
+ import { Path, Vec2, PoseDescriptor } from '@weasel-js/core/math';
15
3
 
16
4
  /** An axis-aligned box. This is `PoseDescriptor.getBounds`'s return shape
17
5
  * minus its optional `rotation`, deliberately: an outline is built in the
@@ -23,80 +11,98 @@ interface Bounds {
23
11
  width: number;
24
12
  height: number;
25
13
  }
26
- /** A named flowchart shape, or a path a consumer built themselves in a unit
27
- * square — `(0, 0)` the box's top-left, `(1, 1)` its bottom-right — so it
28
- * follows its node wherever layout or a drag puts it. */
29
- type Outline = 'rect' | 'diamond' | 'stadium' | 'ellipse' | 'parallelogram' | 'trapezoid' | 'hexagon' | Path;
14
+ interface Size {
15
+ width: number;
16
+ height: number;
17
+ }
18
+ /** A named outline: how its shape is built in a node's bounds, and where the
19
+ * node's rows may sit inside it. */
20
+ interface OutlineDef {
21
+ /** Filled and stroked; also the node's silhouette for picking and clipping. */
22
+ path(bounds: Bounds): Path;
23
+ /** Stroked only, over the fill: a cylinder's front rim, a note's fold. */
24
+ detail?(bounds: Bounds): Path;
25
+ /** The largest box rows can occupy without leaving the shape. Default the bounds. */
26
+ content?(bounds: Bounds): Bounds;
27
+ /** The inverse of `content`: a box whose content is at least `content`. Default the content size. */
28
+ boxForContent?(content: Size): Size;
29
+ }
30
+
31
+ declare const BUILTINS: {
32
+ component: OutlineDef;
33
+ doubleRect: OutlineDef;
34
+ event: OutlineDef;
35
+ intermediateEvent: OutlineDef;
36
+ exclusiveGateway: OutlineDef;
37
+ parallelGateway: OutlineDef;
38
+ inclusiveGateway: OutlineDef;
39
+ eventGateway: OutlineDef;
40
+ subprocess: OutlineDef;
41
+ server: OutlineDef;
42
+ router: OutlineDef;
43
+ switch: OutlineDef;
44
+ firewall: OutlineDef;
45
+ laptop: OutlineDef;
46
+ desktop: OutlineDef;
47
+ phone: OutlineDef;
48
+ printer: OutlineDef;
49
+ user: OutlineDef;
50
+ globe: OutlineDef;
51
+ cylinder: OutlineDef;
52
+ document: OutlineDef;
53
+ note: OutlineDef;
54
+ folder: OutlineDef;
55
+ cube: OutlineDef;
56
+ roundRect: OutlineDef;
57
+ triangle: OutlineDef;
58
+ octagon: OutlineDef;
59
+ cloud: OutlineDef;
60
+ actor: OutlineDef;
61
+ doubleEllipse: OutlineDef;
62
+ rect: OutlineDef;
63
+ diamond: OutlineDef;
64
+ stadium: OutlineDef;
65
+ ellipse: OutlineDef;
66
+ parallelogram: OutlineDef;
67
+ trapezoid: OutlineDef;
68
+ hexagon: OutlineDef;
69
+ };
70
+ /** A name the kit itself registers. */
71
+ type BuiltinOutline = keyof typeof BUILTINS;
72
+ /** Register `def` under `name`, shadowing any definition already there.
73
+ * Returns the disposer. */
74
+ declare function registerOutline(name: string, def: OutlineDef): () => void;
75
+
76
+ /**
77
+ * The shapes a built body can wear, as paths in the node's bounds.
78
+ *
79
+ * A name resolves through the outline table (`outlines/table.ts`), which
80
+ * holds the built-ins and whatever `registerOutline` adds. A `Path` is the
81
+ * escape hatch for a one-off shape: drawn in a unit square and stretched over
82
+ * the bounds, as a mark is. Paths are built in world coordinates from the
83
+ * bounds, the same way the kit's own `clipFromPose` factories are.
84
+ */
85
+
86
+ /** A registered outline's name, or a path a consumer built themselves in a
87
+ * unit square — `(0, 0)` the box's top-left, `(1, 1)` its bottom-right — so
88
+ * it follows its node wherever layout or a drag puts it. */
89
+ type Outline = BuiltinOutline | (string & {}) | Path;
30
90
  /** The path `outline` describes inside `bounds`. A zero-area box gives a
31
91
  * zero-area rect rather than a degenerate polygon. */
32
92
  declare function outlinePath(outline: Outline, bounds: Bounds): Path;
93
+ /** The strokes `outline` draws over its fill — a cylinder's rim, a note's
94
+ * fold — or null when it has none. */
95
+ declare function outlineDetail(outline: Outline, bounds: Bounds): Path | null;
33
96
  /**
34
97
  * The largest axis-aligned box a shape's content can occupy without leaving
35
98
  * the shape. Rows lay out in here, not in the bounds — a diamond's corners and
36
99
  * a parallelogram's lean are outside its own box, and a label placed against
37
100
  * the bounding box lands there and gets clipped away by the silhouette.
38
- *
39
- * Conservative rather than exact: the inscribed rect of a rhombus is exact,
40
- * and a stadium reports the flat span between its rounded ends, which gives up
41
- * a little height near them.
42
101
  */
43
102
  declare function contentBox(outline: Outline, bounds: Bounds): Bounds;
44
- /**
45
- * The box whose {@link contentBox} is at least `content` — the inverse, for
46
- * sizing a node to what its rows measured.
47
- *
48
- * The stadium case is the only inexact one: its inset depends on the height it
49
- * is solving for, so it assumes the wide orientation and adds one height's
50
- * worth of end caps.
51
- */
52
- declare function boxForContent(outline: Outline, content: {
53
- width: number;
54
- height: number;
55
- }): {
56
- width: number;
57
- height: number;
58
- };
59
-
60
- /**
61
- * The label trait: where along its edge a label sits. Data only — placing the
62
- * label on the route is `label`'s job, so layout can read one without
63
- * reaching the scene.
64
- */
65
-
66
- /** Where along an edge a label sits. */
67
- interface DiagramLabel {
68
- /** `'start'`, `'mid'` and `'end'` are 0, 0.5 and 1; a number is that
69
- * fraction of the route's length. `{ near }` is the point on the route
70
- * nearest `near`, in world coordinates — where `layered` leaves a label
71
- * room — so a bend added or removed elsewhere leaves the label on the
72
- * stretch it was on. */
73
- at: 'start' | 'mid' | 'end' | number | {
74
- near: Vec2;
75
- };
76
- /** World units between the route and the label's near side, to the **left
77
- * of the direction of travel** — above a left-to-right edge. Default 0,
78
- * which centers the label on the line. */
79
- offset?: number;
80
- /** Where label placement moved it, off a station something covered:
81
- * `at` a fraction of the route's length, `offset` as above. Read in place
82
- * of `at` and `offset`, which stay the author's preference. Written only
83
- * by placement (`installLabelPlacement`). */
84
- placed?: LabelSpot;
85
- /** `false` keeps placement from ever moving this label. */
86
- dodge?: false;
87
- }
88
- /** A station placement chose: a fraction of the route's length, and the
89
- * offset from the line. */
90
- interface LabelSpot {
91
- at: number;
92
- offset: number;
93
- }
94
- /** Where an edge label sits when neither the edge nor the scene says. */
95
- declare const LABEL_PLACEMENT: DiagramLabel;
96
- /** The label trait on a node's data, or `null`. */
97
- declare function diagramLabelOf(node: {
98
- data: unknown;
99
- }): DiagramLabel | null;
103
+ /** The box whose {@link contentBox} is at least `content` — the inverse, for
104
+ * sizing a node to what its rows measured. */
105
+ declare function boxForContent(outline: Outline, content: Size): Size;
100
106
 
101
107
  /**
102
108
  * Reading the `DiagramNode` trait off a scene node.
@@ -517,6 +523,8 @@ interface DiagramContainer {
517
523
  /** Its box is fitted to its members each time the diagram is built from data
518
524
  * (`DataContainer` with no `box`), so a move that carries it along is no edit of its own. */
519
525
  fitted?: true;
526
+ /** A container whose members are reordered along this axis (`DataContainer.reorder`). */
527
+ reorder?: 'x' | 'y';
520
528
  }
521
529
  type Box = {
522
530
  x: number;
@@ -617,16 +625,26 @@ interface DiagramNode {
617
625
  ownStyle?: readonly StyleField[];
618
626
  /** The parts of its text face the author set by hand, which a theme leaves as they are. */
619
627
  ownFont?: readonly FontField[];
620
- /** On a built body whose rows are all text: how it stacks them, so it can be laid out again when
621
- * their text changes size. Each row's text node carries its place as `bodyRow`. */
628
+ /** On a built body whose rows are all text or dividers: how it stacks them, so it can be laid out
629
+ * again when their text changes size. Each row's text node carries its place as `bodyRow`. */
622
630
  body?: BodyLayout;
623
631
  }
624
- /** How a built body stacks its text rows: the `BodySpec` fields its layout reads, and how many rows. */
632
+ /** How a built body stacks its rows: the `BodySpec` fields its layout reads, and how many rows. */
625
633
  interface BodyLayout {
626
634
  padding: number;
627
635
  gap: number;
628
636
  verticalAlign: 'top' | 'center' | 'bottom';
629
637
  rows: number;
638
+ /** Each row's height as last laid out, so the rows can be stacked again at a new size without
639
+ * measuring. Absent on a body saved before it was recorded. */
640
+ heights?: readonly number[];
641
+ /** The divider rows, by place. The outline painter draws their rules. */
642
+ dividers?: readonly BodyDivider[];
643
+ }
644
+ /** A divider row of a {@link BodyLayout}: its place among the rows, and its `inset`. */
645
+ interface BodyDivider {
646
+ index: number;
647
+ inset?: number;
630
648
  }
631
649
  /** The group half of a {@link DiagramNode}. */
632
650
  interface DiagramGroup {
@@ -689,6 +707,12 @@ type Row =
689
707
  height: number;
690
708
  width?: number;
691
709
  id?: string;
710
+ }
711
+ /** A rule across the content box, drawn in the body's own stroke by the
712
+ * outline painter. `inset` stops it that far short of each side. */
713
+ | {
714
+ kind: 'divider';
715
+ inset?: number;
692
716
  };
693
717
  /** A port declared on a row rather than on the node's perimeter. */
694
718
  interface RowPort {
@@ -703,6 +727,7 @@ interface RowTextStyle {
703
727
  fontSize?: number;
704
728
  fontFamily?: string;
705
729
  bold?: boolean;
730
+ italic?: boolean;
706
731
  }
707
732
  /** Measures one run of text. Returns its advance width and its line height. */
708
733
  type MeasureRowText = (text: string, style: RowTextStyle) => {
@@ -745,6 +770,8 @@ interface RowPortBox extends Bounds {
745
770
  /** Position within its own side, top to bottom. */
746
771
  index: number;
747
772
  }
773
+ /** The height a divider row takes; its rule runs through the middle. */
774
+ declare const DIVIDER_HEIGHT = 4;
748
775
  /** Adapts the kit's `measureText` for a caller holding a 2D context. Pass the
749
776
  * same context the renderer measures with, or the floor will not match what
750
777
  * is painted. */
@@ -822,4 +849,4 @@ interface EdgeHop {
822
849
  r: number;
823
850
  }
824
851
 
825
- export { anchorOffset as $, type DiagramNodeEntry as A, type BodySpec as B, type ContainerRole as C, type DiagramGroup as D, type EdgeHop as E, type FontField as F, type Graph as G, type EdgeLabelRoom as H, type GraphEdge as I, type GraphGroup as J, type GraphNode as K, type LayoutPorts as L, type MeasureRowText as M, type GroupInset as N, type Outline as O, type PortAnchor as P, HOPS_DOC_KEY as Q, type RowTextStyle as R, type StyleField as S, type HopsDocValue as T, LABEL_PLACEMENT as U, type LayoutAxes as V, type PortSite as W, type RowBox as X, type RowPort as Y, type RowPortBox as Z, type Slot as _, type Row as a, axesFor as a0, bodyBox as a1, bodyOutline as a2, bodyTrait as a3, boxForContent as a4, buildGraph as a5, canvasMeasure as a6, contentBox as a7, createDiagramNodes as a8, dataKeyReader as a9, diagramContainerOf as aa, diagramLabelOf as ab, diagramNodeOf as ac, expandGroupEdges as ad, graphOrder as ae, headerBox as af, insetOf as ag, isPinned as ah, layoutBody as ai, layoutRowPorts as aj, measureBody as ak, outlinePath as al, packAcross as am, packClusters as an, pinnedSet as ao, planOf as ap, plannerPlan as aq, rankGaps as ar, seededOrder as as, settle as at, sizeToBody as au, titleIdOf as av, translated as aw, untilSettled as ax, extent as ay, type PortSpec as b, type DiagramLabel as c, type LayoutFn as d, type LayoutOptions as e, type DiagramNode as f, type Port as g, type DiagramNodeLike as h, type DiagramNodeReader as i, type DiagramContainer as j, type ContainerHeader as k, type LabelSpot as l, type Bounds as m, type LayoutResult as n, type GraphSource as o, type LayoutPlanner as p, type LayoutDirection as q, type LayoutPlan as r, type GraphNodeLike as s, type BodyFloor as t, type BuildGraphOptions as u, DEFAULT_GROUP_INSET as v, DEFAULT_HOP_SIZE as w, DEFAULT_NODE_GAP as x, DEFAULT_RANK_GAP as y, DIAGRAM_TRAIT_KEY as z };
852
+ export { type RowPortBox as $, DIAGRAM_TRAIT_KEY as A, type BodySpec as B, type ContainerRole as C, type DiagramGroup as D, type EdgeHop as E, type FontField as F, type Graph as G, DIVIDER_HEIGHT as H, type DiagramNodeEntry as I, type EdgeLabelRoom as J, type GraphEdge as K, type LayoutPorts as L, type MeasureRowText as M, type GraphGroup as N, type Outline as O, type PortAnchor as P, type GraphNode as Q, type RowTextStyle as R, type StyleField as S, type GroupInset as T, HOPS_DOC_KEY as U, type HopsDocValue as V, type LayoutAxes as W, type OutlineDef as X, type PortSite as Y, type RowBox as Z, type RowPort as _, type Row as a, type Slot as a0, anchorOffset as a1, axesFor as a2, bodyBox as a3, bodyOutline as a4, bodyTrait as a5, boxForContent as a6, buildGraph as a7, canvasMeasure as a8, contentBox as a9, untilSettled as aA, extent as aB, createDiagramNodes as aa, dataKeyReader as ab, diagramContainerOf as ac, diagramNodeOf as ad, expandGroupEdges as ae, graphOrder as af, headerBox as ag, insetOf as ah, isPinned as ai, layoutBody as aj, layoutRowPorts as ak, measureBody as al, outlineDetail as am, outlinePath as an, packAcross as ao, packClusters as ap, pinnedSet as aq, planOf as ar, plannerPlan as as, rankGaps as at, registerOutline as au, seededOrder as av, settle as aw, sizeToBody as ax, titleIdOf as ay, translated as az, type PortSpec as b, type LayoutFn as c, type LayoutOptions as d, type DiagramNode as e, type Port as f, type DiagramNodeLike as g, type DiagramNodeReader as h, type DiagramContainer as i, type ContainerHeader as j, type Bounds as k, type LayoutResult as l, type GraphSource as m, type LayoutPlanner as n, type LayoutDirection as o, type LayoutPlan as p, type GraphNodeLike as q, type BodyDivider as r, type BodyFloor as s, type BodyLayout as t, type BuildGraphOptions as u, type BuiltinOutline as v, DEFAULT_GROUP_INSET as w, DEFAULT_HOP_SIZE as x, DEFAULT_NODE_GAP as y, DEFAULT_RANK_GAP as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weasel-js/diagram",
3
- "version": "1.13.0",
3
+ "version": "1.14.1",
4
4
  "description": "Node-link diagramming for weasel: any scene node becomes a diagram participant, with ports on its perimeter and an optional body builder for flowchart-shaped boxes.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -33,13 +33,13 @@
33
33
  },
34
34
  "peerDependencies": {
35
35
  "react": ">=18",
36
- "@weasel-js/animator": "1.13.0",
37
- "@weasel-js/audio": "1.13.0",
38
- "@weasel-js/core": "1.13.0",
39
- "@weasel-js/font": "1.13.0",
40
- "@weasel-js/geom": "1.13.0",
41
- "@weasel-js/react": "1.13.0",
42
- "@weasel-js/simulation": "1.13.0"
36
+ "@weasel-js/animator": "1.14.1",
37
+ "@weasel-js/audio": "1.14.1",
38
+ "@weasel-js/core": "1.14.1",
39
+ "@weasel-js/font": "1.14.1",
40
+ "@weasel-js/geom": "1.14.1",
41
+ "@weasel-js/react": "1.14.1",
42
+ "@weasel-js/simulation": "1.14.1"
43
43
  },
44
44
  "peerDependenciesMeta": {
45
45
  "@weasel-js/audio": {
@@ -50,7 +50,9 @@
50
50
  "table": "./dist/icons.table.json"
51
51
  },
52
52
  "dependencies": {
53
- "@weasel-js/icons": "1.13.0"
53
+ "@weasel-js/clock": "1.14.1",
54
+ "@weasel-js/headless": "1.14.1",
55
+ "@weasel-js/icons": "1.14.1"
54
56
  },
55
57
  "author": "orochi235",
56
58
  "homepage": "https://orochi235.github.io/weasel/",