@floegence/floe-webapp-core 0.86.7 → 0.86.8

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.
@@ -1,165 +1,202 @@
1
1
  import { AvoidLib as H } from "../../node_modules/.pnpm/libavoid-js@0.5.0-beta.5/node_modules/libavoid-js/dist/index.js";
2
- import _ from "../../node_modules/.pnpm/libavoid-js@0.5.0-beta.5/node_modules/libavoid-js/dist/libavoid.wasm.js";
3
- let U;
4
- const F = { NORTH: 1, SOUTH: 2, WEST: 4, EAST: 8 }, v = ["NORTH", "EAST", "SOUTH", "WEST"], m = (s) => s.delete();
5
- async function L(s) {
6
- if (!s.nodes.length) return s;
7
- if (!s.edges.length) return W(s);
8
- await (U ??= H.load(_).catch((g) => {
9
- throw U = void 0, g;
2
+ import W from "../../node_modules/.pnpm/libavoid-js@0.5.0-beta.5/node_modules/libavoid-js/dist/libavoid.wasm.js";
3
+ let N;
4
+ const B = { NORTH: 1, SOUTH: 2, WEST: 4, EAST: 8 }, v = ["NORTH", "EAST", "SOUTH", "WEST"], m = (t) => t.delete();
5
+ async function F(t) {
6
+ if (!t.nodes.length) return t;
7
+ if (!t.edges.length) return C(t);
8
+ await (N ??= H.load(W).catch((h) => {
9
+ throw N = void 0, h;
10
10
  }));
11
- const n = H.getInstance(), x = new Map(s.nodes.map((g) => [g.id, g])), S = (g) => {
11
+ const e = H.getInstance(), s = new Map(t.nodes.map((h) => [h.id, h])), d = (h) => {
12
12
  const y = [];
13
- for (let a = x.get(g).parentId; a; a = x.get(a).parentId)
14
- y.push(a);
13
+ for (let r = s.get(h).parentId; r; r = s.get(r).parentId)
14
+ y.push(r);
15
15
  return y;
16
16
  }, i = /* @__PURE__ */ new Map();
17
- for (const g of s.edges) {
18
- const y = /* @__PURE__ */ new Set([...S(g.source), ...S(g.target)]), a = JSON.stringify([...y].sort()), O = i.get(a) ?? { open: y, edges: [] };
19
- O.edges.push(g), i.set(a, O);
17
+ for (const h of t.edges) {
18
+ const y = /* @__PURE__ */ new Set([...d(h.source), ...d(h.target)]), r = JSON.stringify([...y].sort()), S = i.get(r) ?? { open: y, edges: [] };
19
+ S.edges.push(h), i.set(r, S);
20
20
  }
21
- const k = /* @__PURE__ */ new Map();
22
- for (const { open: g, edges: y } of i.values()) {
23
- const a = new n.Router(2);
21
+ const f = /* @__PURE__ */ new Map();
22
+ for (const { open: h, edges: y } of i.values()) {
23
+ const r = new e.Router(2);
24
24
  try {
25
- a.setRoutingParameter(n.RoutingParameter.shapeBufferDistance, 4), a.setRoutingParameter(n.RoutingParameter.idealNudgingDistance, 8), a.setRoutingParameter(n.RoutingParameter.crossingPenalty, 80), a.setRoutingParameter(n.RoutingParameter.fixedSharedPathPenalty, 120), a.setRoutingParameter(n.RoutingParameter.portDirectionPenalty, 0), a.setRoutingOption(n.RoutingOption.nudgeOrthogonalSegmentsConnectedToShapes, !1), a.setRoutingOption(n.RoutingOption.nudgeSharedPathsWithCommonEndPoint, !0);
26
- const O = new Map(
27
- s.nodes.filter((t) => !g.has(t.id) && S(t.id).every((r) => g.has(r))).map((t) => {
28
- const r = new n.Point(t.x, t.y), c = new n.Point(t.x + t.width, t.y + t.height), h = new n.Rectangle(r, c), o = new n.ShapeRef(a, h);
29
- return m(r), m(c), m(h), [t.id, o];
25
+ r.setRoutingParameter(e.RoutingParameter.shapeBufferDistance, 4), r.setRoutingParameter(e.RoutingParameter.idealNudgingDistance, 8), r.setRoutingParameter(e.RoutingParameter.crossingPenalty, 80), r.setRoutingParameter(e.RoutingParameter.fixedSharedPathPenalty, 120), r.setRoutingParameter(e.RoutingParameter.portDirectionPenalty, 0), r.setRoutingOption(e.RoutingOption.nudgeOrthogonalSegmentsConnectedToShapes, !1), r.setRoutingOption(e.RoutingOption.nudgeSharedPathsWithCommonEndPoint, !0);
26
+ const S = new Map(
27
+ t.nodes.filter((n) => !h.has(n.id) && d(n.id).every((a) => h.has(a))).map((n) => {
28
+ const a = new e.Point(n.x, n.y), p = new e.Point(n.x + n.width, n.y + n.height), o = new e.Rectangle(a, p), c = new e.ShapeRef(r, o);
29
+ return m(a), m(p), m(o), [n.id, c];
30
30
  })
31
- );
32
- for (const t of s.nodes) {
33
- const r = O.get(t.id);
34
- if (!r) continue;
35
- const c = y.flatMap(
36
- (e) => e.source === t.id ? [x.get(e.target)] : e.target === t.id ? [x.get(e.source)] : []
37
- );
38
- if (!c.length) continue;
39
- const h = (e, f, p, M) => {
40
- const T = Math.max(e, p), R = Math.min(e + f, p + M), A = Math.min(8, f / 4);
41
- return T < R ? (T + R) / 2 : Math.max(e + A, Math.min(e + f - A, p + M / 2));
42
- }, o = (e, f) => {
43
- const p = Math.min(8, e / 4);
44
- return [
45
- .../* @__PURE__ */ new Set([
46
- e / 2,
47
- p,
48
- e - p,
49
- ...f.flatMap(
50
- (M) => Array.from(
51
- { length: c.length + 1 },
52
- (T, R) => Math.max(p, Math.min(e - p, M + (R - c.length / 2) * 8))
53
- )
54
- )
55
- ])
56
- ];
57
- }, u = o(
58
- t.width,
59
- c.map((e) => h(t.x, t.width, e.x, e.width) - t.x)
60
- ), w = o(
61
- t.height,
62
- c.map((e) => h(t.y, t.height, e.y, e.height) - t.y)
63
- ), l = (t.ports ?? []).map((e) => E(t, e.side)), P = y.some((e) => e.source === t.id && e.target === t.id), C = [
64
- ...l,
65
- ...P ? [
66
- { x: t.x + t.width, y: t.y + t.height / 3 },
67
- { x: t.x + t.width, y: t.y + t.height * 2 / 3 }
68
- ] : []
69
- ], b = (e, f, p, M, T) => {
70
- const R = new n.ShapeConnectionPin(
71
- r,
72
- e,
73
- f / t.width,
74
- p / t.height,
31
+ ), P = /* @__PURE__ */ new Map(), R = /* @__PURE__ */ new Map();
32
+ y.forEach((n) => {
33
+ const a = s.get(n.source), p = s.get(n.target), o = D(a, p), c = n.sourcePort ? a.ports.find((u) => u.id === n.sourcePort).side : n.targetPort ? O(p.ports.find((u) => u.id === n.targetPort).side) : o.source, g = n.targetPort ? p.ports.find((u) => u.id === n.targetPort).side : n.sourcePort ? O(a.ports.find((u) => u.id === n.sourcePort).side) : o.target, w = [n.source, n.target].sort().join("\0"), x = R.get(w) ?? 0;
34
+ R.set(w, x + 1), P.set(n.id, {
35
+ sourceSide: c,
36
+ targetSide: g,
37
+ offset: x % 2 === 0 ? -6 : 6
38
+ });
39
+ });
40
+ for (const n of t.nodes) {
41
+ const a = S.get(n.id);
42
+ if (!a) continue;
43
+ const p = (o, c, g, w, x) => {
44
+ const u = new e.ShapeConnectionPin(
45
+ a,
46
+ o,
47
+ c / n.width,
48
+ g / n.height,
75
49
  !0,
76
50
  0,
77
- M
51
+ w
78
52
  );
79
- R.setExclusive(T), R.setConnectionCost(
80
- t.width / 2 + t.height / 2 - Math.abs(f - t.width / 2) - Math.abs(p - t.height / 2)
53
+ u.setExclusive(x), u.setConnectionCost(
54
+ n.width / 2 + n.height / 2 - Math.abs(c - n.width / 2) - Math.abs(g - n.height / 2)
81
55
  );
82
- }, d = (e, f, p) => {
83
- C.some((M) => M.x === t.x + e && M.y === t.y + f) || b(1, e, f, p, !0);
84
56
  };
85
- for (const e of u)
86
- d(e, 0, 1), d(e, t.height, 2);
87
- for (const e of w)
88
- d(0, e, 4), d(t.width, e, 8);
89
- for (const e of new Set(t.ports?.map((f) => f.side))) {
90
- const { x: f, y: p } = E(t, e);
91
- b(v.indexOf(e) + 2, f - t.x, p - t.y, F[e], !1);
57
+ for (const o of new Set(n.ports?.map((c) => c.side))) {
58
+ const { x: c, y: g } = A(n, o);
59
+ p(v.indexOf(o) + 2, c - n.x, g - n.y, B[o], !1);
92
60
  }
93
- P && (b(6, t.width, t.height / 3, 8, !1), b(7, t.width, t.height * 2 / 3, 8, !1));
94
61
  }
95
- const N = (t, r, c, h) => {
96
- const o = x.get(t), u = O.get(t);
97
- if (u)
98
- return new n.ConnEnd(
99
- u,
100
- r ? v.indexOf(o.ports.find((d) => d.id === r).side) + 2 : t === c ? h ? 7 : 6 : 1
62
+ const l = (n, a, p) => {
63
+ const o = s.get(n), c = S.get(n);
64
+ if (c && a)
65
+ return new e.ConnEnd(
66
+ c,
67
+ v.indexOf(o.ports.find((u) => u.id === a).side) + 2
101
68
  );
102
- const w = x.get(c), l = v.map((d) => E(o, d));
103
- l.sort((d, e) => B(d, w) - B(e, w));
104
- const P = r ? E(o, o.ports.find((d) => d.id === r).side) : l[0], C = new n.Point(P.x, P.y), b = new n.ConnEnd(C);
105
- return m(C), b;
106
- }, G = y.map((t) => {
107
- const r = N(t.source, t.sourcePort, t.target, !1), c = N(t.target, t.targetPort, t.source, !0), h = new n.ConnRef(a, r, c);
108
- if (m(r), m(c), t.source === t.target) {
109
- const o = x.get(t.source), u = new n.CheckpointVector();
110
- for (const w of [o.y + o.height / 3, o.y + o.height * 2 / 3]) {
111
- const l = new n.Point(o.x + o.width + 24, w), P = new n.Checkpoint(l);
112
- u.push_back(P), m(l), m(P);
69
+ const g = a ? A(o, o.ports.find((u) => u.id === a).side) : p, w = new e.Point(g.x, g.y), x = new e.ConnEnd(w);
70
+ return m(w), x;
71
+ }, M = y.map((n) => {
72
+ const a = s.get(n.source), p = s.get(n.target), o = P.get(n.id), c = l(
73
+ n.source,
74
+ n.sourcePort,
75
+ n.source === n.target ? { x: a.x + a.width, y: a.y + a.height / 3 } : k(a, o.sourceSide, p, o.offset)
76
+ ), g = l(
77
+ n.target,
78
+ n.targetPort,
79
+ n.source === n.target ? {
80
+ x: p.x + p.width,
81
+ y: p.y + p.height * 2 / 3
82
+ } : k(p, o.targetSide, a, o.offset)
83
+ ), w = new e.ConnRef(r, c, g);
84
+ if (m(c), m(g), n.source === n.target) {
85
+ const x = s.get(n.source), u = new e.CheckpointVector();
86
+ for (const U of [x.y + x.height / 3, x.y + x.height * 2 / 3]) {
87
+ const E = new e.Point(x.x + x.width + 24, U), b = new e.Checkpoint(E);
88
+ u.push_back(b), m(E), m(b);
113
89
  }
114
- h.setRoutingCheckpoints(u), m(u);
90
+ w.setRoutingCheckpoints(u), m(u);
115
91
  }
116
- return { edge: t, connection: h };
92
+ return { edge: n, connection: w };
117
93
  });
118
- a.processTransaction();
119
- for (const { edge: t, connection: r } of G) {
120
- const c = r.displayRoute(), h = Array.from({ length: c.size() }, (o, u) => {
121
- const w = c.at(u), l = { x: w.x, y: w.y };
122
- return m(w), l;
94
+ r.processTransaction();
95
+ for (const { edge: n, connection: a } of M) {
96
+ const p = a.displayRoute(), o = Array.from({ length: p.size() }, (c, g) => {
97
+ const w = p.at(g), x = { x: w.x, y: w.y };
98
+ return m(w), x;
123
99
  });
124
- if (m(c), !r.hasValidRoute() || h.length < 2 || h.some((o) => !Number.isFinite(o.x) || !Number.isFinite(o.y)) || h.some((o, u) => u > 0 && o.x !== h[u - 1].x && o.y !== h[u - 1].y))
125
- throw new Error(`Graph edge cannot be routed: ${t.id}`);
126
- k.set(t.id, h);
100
+ if (m(p), !a.hasValidRoute() || o.length < 2 || o.some((c) => !Number.isFinite(c.x) || !Number.isFinite(c.y)) || o.some((c, g) => g > 0 && c.x !== o[g - 1].x && c.y !== o[g - 1].y))
101
+ throw new Error(`Graph edge cannot be routed: ${n.id}`);
102
+ f.set(n.id, o);
127
103
  }
128
104
  } finally {
129
- a.delete();
105
+ r.delete();
130
106
  }
131
107
  }
132
- const D = s.edges.map((g) => ({ ...g, sections: [k.get(g.id)] }));
133
- return W({ nodes: s.nodes, edges: D, bounds: s.bounds });
108
+ const T = t.edges.map((h) => ({ ...h, sections: [f.get(h.id)] }));
109
+ return C({
110
+ nodes: t.nodes,
111
+ edges: T,
112
+ bounds: t.bounds
113
+ });
134
114
  }
135
- function W(s) {
136
- const n = [
137
- ...s.nodes.flatMap((i) => [
115
+ function C(t) {
116
+ const e = [
117
+ ...t.nodes.flatMap((i) => [
138
118
  { x: i.x, y: i.y },
139
119
  { x: i.x + i.width, y: i.y + i.height }
140
120
  ]),
141
- ...s.edges.flatMap((i) => i.sections.flat())
142
- ], x = Math.min(...n.map((i) => i.x)), S = Math.min(...n.map((i) => i.y));
121
+ ...t.edges.flatMap((i) => i.sections.flat())
122
+ ], s = Math.min(...e.map((i) => i.x)), d = Math.min(...e.map((i) => i.y));
143
123
  return {
144
- nodes: s.nodes,
145
- edges: s.edges,
124
+ nodes: t.nodes,
125
+ edges: t.edges,
146
126
  bounds: {
147
- x,
148
- y: S,
149
- width: Math.max(...n.map((i) => i.x)) - x,
150
- height: Math.max(...n.map((i) => i.y)) - S
127
+ x: s,
128
+ y: d,
129
+ width: Math.max(...e.map((i) => i.x)) - s,
130
+ height: Math.max(...e.map((i) => i.y)) - d
151
131
  }
152
132
  };
153
133
  }
154
- function E(s, n) {
134
+ function A(t, e) {
155
135
  return {
156
- x: n === "WEST" ? s.x : n === "EAST" ? s.x + s.width : s.x + s.width / 2,
157
- y: n === "NORTH" ? s.y : n === "SOUTH" ? s.y + s.height : s.y + s.height / 2
136
+ x: e === "WEST" ? t.x : e === "EAST" ? t.x + t.width : t.x + t.width / 2,
137
+ y: e === "NORTH" ? t.y : e === "SOUTH" ? t.y + t.height : t.y + t.height / 2
158
138
  };
159
139
  }
160
- function B(s, n) {
161
- return Math.max(n.x - s.x, 0, s.x - n.x - n.width) + Math.max(n.y - s.y, 0, s.y - n.y - n.height);
140
+ function O(t) {
141
+ return {
142
+ NORTH: "SOUTH",
143
+ EAST: "WEST",
144
+ SOUTH: "NORTH",
145
+ WEST: "EAST"
146
+ }[t];
147
+ }
148
+ function D(t, e) {
149
+ const s = e.x + e.width / 2 - (t.x + t.width / 2), d = e.y + e.height / 2 - (t.y + t.height / 2), i = Math.max(t.x - (e.x + e.width), e.x - (t.x + t.width), 0), f = Math.max(
150
+ t.y - (e.y + e.height),
151
+ e.y - (t.y + t.height),
152
+ 0
153
+ ), h = (f === 0 && i > 0 ? !0 : i === 0 && f > 0 ? !1 : i === 0 && f === 0 ? Math.abs(s) >= Math.abs(d) : i <= f) ? s >= 0 ? "EAST" : "WEST" : d >= 0 ? "SOUTH" : "NORTH";
154
+ return { source: h, target: O(h) };
155
+ }
156
+ function k(t, e, s, d = 0) {
157
+ const i = (r) => Math.min(8, r / 4), f = (r, S, P) => Math.max(S + i(P), Math.min(S + P - i(P), r)), T = (r, S, P, R) => {
158
+ const l = Math.max(r, P), M = Math.min(r + S, P + R);
159
+ return l < M ? (l + M) / 2 + d : void 0;
160
+ }, h = s.x + s.width / 2, y = s.y + s.height / 2;
161
+ switch (e) {
162
+ case "NORTH":
163
+ return {
164
+ x: f(
165
+ T(t.x, t.width, s.x, s.width) ?? h + d,
166
+ t.x,
167
+ t.width
168
+ ),
169
+ y: t.y
170
+ };
171
+ case "EAST":
172
+ return {
173
+ x: t.x + t.width,
174
+ y: f(
175
+ T(t.y, t.height, s.y, s.height) ?? y + d,
176
+ t.y,
177
+ t.height
178
+ )
179
+ };
180
+ case "SOUTH":
181
+ return {
182
+ x: f(
183
+ T(t.x, t.width, s.x, s.width) ?? h + d,
184
+ t.x,
185
+ t.width
186
+ ),
187
+ y: t.y + t.height
188
+ };
189
+ case "WEST":
190
+ return {
191
+ x: t.x,
192
+ y: f(
193
+ T(t.y, t.height, s.y, s.height) ?? y + d,
194
+ t.y,
195
+ t.height
196
+ )
197
+ };
198
+ }
162
199
  }
163
200
  export {
164
- L as routeGraphGeometry
201
+ F as routeGraphGeometry
165
202
  };
@@ -52,8 +52,10 @@ export interface GraphLayoutOptions {
52
52
  positions?: readonly (GraphPoint & {
53
53
  nodeId: string;
54
54
  })[];
55
- /** Fixed (default) rejects impossible geometry. Preferred retains clear positions and separates colliding siblings, resizing groups around their content before routing. */
56
- positionMode?: 'fixed' | 'preferred';
55
+ /** Root-level ranks. Unassigned roots are placed deterministically near their closest ranked neighbors. */
56
+ layers?: readonly (readonly string[])[];
57
+ /** Fixed (default) rejects impossible geometry. Preferred retains positions; compact uses them only as stable ordering hints. */
58
+ positionMode?: 'fixed' | 'preferred' | 'compact';
57
59
  direction?: 'RIGHT' | 'DOWN' | 'LEFT' | 'UP';
58
60
  spacing?: number;
59
61
  groupPadding?: {