@floegence/floe-webapp-core 0.84.0 → 0.86.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/components/file-browser/DragPreview.js +1 -1
- package/dist/components/graph/layout.js +65 -61
- package/dist/components/graph/packing.d.ts +4 -0
- package/dist/components/graph/packing.js +74 -0
- package/dist/components/graph/positions.d.ts +5 -3
- package/dist/components/graph/positions.js +143 -103
- package/dist/components/graph/types.d.ts +5 -1
- package/dist/components/notes/NotesOverlay.js +1 -1
- package/dist/components/workbench/WorkbenchFilterBar.js +1 -1
- package/dist/components/workbench/WorkbenchLockButton.js +1 -1
- package/dist/components/workbench/WorkbenchOverlay.js +1 -1
- package/dist/node_modules/.pnpm/{solid-motionone@1.0.4_solid-js@1.9.15 → solid-motionone@1.0.4_solid-js@1.9.17}/node_modules/solid-motionone/dist/index.js +3 -3
- package/package.json +3 -3
- /package/dist/node_modules/.pnpm/{@solid-primitives_props@3.2.4_solid-js@1.9.15 → @solid-primitives_props@3.2.4_solid-js@1.9.17}/node_modules/@solid-primitives/props/dist/combineProps.js +0 -0
- /package/dist/node_modules/.pnpm/{@solid-primitives_refs@1.1.4_solid-js@1.9.15 → @solid-primitives_refs@1.1.4_solid-js@1.9.17}/node_modules/@solid-primitives/refs/dist/index.js +0 -0
- /package/dist/node_modules/.pnpm/{@solid-primitives_transition-group@1.1.2_solid-js@1.9.15 → @solid-primitives_transition-group@1.1.2_solid-js@1.9.17}/node_modules/@solid-primitives/transition-group/dist/index.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createComponent as o, Portal as N, insert as l, effect as u, className as $, memo as B, template as a, setAttribute as A } from "solid-js/web";
|
|
2
2
|
import { createSignal as F, createEffect as V, createMemo as d, Show as m, For as j } from "solid-js";
|
|
3
|
-
import { Presence as U, Motion as X } from "../../node_modules/.pnpm/solid-motionone@1.0.4_solid-js@1.9.
|
|
3
|
+
import { Presence as U, Motion as X } from "../../node_modules/.pnpm/solid-motionone@1.0.4_solid-js@1.9.17/node_modules/solid-motionone/dist/index.js";
|
|
4
4
|
import { cn as f } from "../../utils/cn.js";
|
|
5
5
|
import { useFileBrowserDrag as G } from "../../context/FileBrowserDragContext.js";
|
|
6
6
|
import { FileItemIcon as W } from "./FileIcons.js";
|
|
@@ -1,91 +1,94 @@
|
|
|
1
1
|
import { applyGraphPositions as v } from "./positions.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import { computePackedGraphLayout as b } from "./packing.js";
|
|
3
|
+
function N(n) {
|
|
4
|
+
const o = /* @__PURE__ */ new Set(), c = (e) => {
|
|
5
|
+
if (!e || o.has(e)) throw new Error(`Duplicate or empty graph ID: ${e}`);
|
|
6
|
+
o.add(e);
|
|
7
|
+
}, a = new Map(n.nodes.map((e) => [e.id, e]));
|
|
8
|
+
for (const e of n.nodes) {
|
|
9
|
+
if (c(e.id), ![e.width, e.height].every((i) => Number.isFinite(i) && i > 0))
|
|
9
10
|
throw new Error(`Invalid dimensions for graph node: ${e.id}`);
|
|
10
|
-
for (const
|
|
11
|
-
const
|
|
11
|
+
for (const i of e.ports ?? []) c(i.id);
|
|
12
|
+
const s = /* @__PURE__ */ new Set([e.id]);
|
|
12
13
|
let d = e.parentId;
|
|
13
14
|
for (; d !== void 0; ) {
|
|
14
|
-
const
|
|
15
|
-
if (!
|
|
15
|
+
const i = a.get(d);
|
|
16
|
+
if (!i || i.kind !== "group")
|
|
16
17
|
throw new Error(`Invalid parent for graph node: ${e.id}`);
|
|
17
|
-
if (
|
|
18
|
-
|
|
18
|
+
if (s.has(d)) throw new Error(`Cyclic graph containment: ${e.id}`);
|
|
19
|
+
s.add(d), d = i.parentId;
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
|
-
for (const e of
|
|
22
|
-
|
|
23
|
-
for (const [
|
|
22
|
+
for (const e of n.edges) {
|
|
23
|
+
c(e.id);
|
|
24
|
+
for (const [s, d] of [
|
|
24
25
|
[e.source, e.sourcePort],
|
|
25
26
|
[e.target, e.targetPort]
|
|
26
27
|
]) {
|
|
27
|
-
const
|
|
28
|
-
if (!
|
|
28
|
+
const i = a.get(s);
|
|
29
|
+
if (!i || d !== void 0 && !i.ports?.some((h) => h.id === d))
|
|
29
30
|
throw new Error(`Invalid endpoint for graph edge: ${e.id}`);
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
|
-
async function
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
async function P(n, o, c) {
|
|
35
|
+
if (N(n), o.aspectRatio !== void 0 && (!Number.isFinite(o.aspectRatio) || o.aspectRatio <= 0))
|
|
36
|
+
throw new Error("Graph layout aspect ratio must be finite and positive");
|
|
37
|
+
const a = o.groupPadding ?? { top: 64, right: 28, bottom: 28, left: 28 };
|
|
38
|
+
if (![...Object.values(a), o.spacing ?? 64].every((t) => Number.isFinite(t) && t >= 0))
|
|
37
39
|
throw new Error("Graph layout spacing must be finite and nonnegative");
|
|
40
|
+
if (o.aspectRatio !== void 0) return b(n, o, c);
|
|
38
41
|
const e = /* @__PURE__ */ new Map();
|
|
39
|
-
for (const t of
|
|
42
|
+
for (const t of n.nodes)
|
|
40
43
|
e.set(t.id, {
|
|
41
44
|
id: t.id,
|
|
42
45
|
width: t.width,
|
|
43
46
|
height: t.height,
|
|
44
47
|
...t.kind === "group" ? { children: [] } : {},
|
|
45
|
-
ports: t.ports?.map((
|
|
46
|
-
id:
|
|
48
|
+
ports: t.ports?.map((r) => ({
|
|
49
|
+
id: r.id,
|
|
47
50
|
width: 1,
|
|
48
51
|
height: 1,
|
|
49
|
-
layoutOptions: { "elk.port.side":
|
|
52
|
+
layoutOptions: { "elk.port.side": r.side }
|
|
50
53
|
})),
|
|
51
54
|
layoutOptions: {
|
|
52
55
|
"elk.portConstraints": "FIXED_ORDER",
|
|
53
|
-
"elk.padding": `[top=${
|
|
56
|
+
"elk.padding": `[top=${a.top},left=${a.left},bottom=${a.bottom},right=${a.right}]`
|
|
54
57
|
}
|
|
55
58
|
});
|
|
56
|
-
const
|
|
57
|
-
for (const t of
|
|
58
|
-
(t.parentId ? e.get(t.parentId).children :
|
|
59
|
+
const s = [];
|
|
60
|
+
for (const t of n.nodes)
|
|
61
|
+
(t.parentId ? e.get(t.parentId).children : s).push(e.get(t.id));
|
|
59
62
|
const d = /* @__PURE__ */ new Set([
|
|
60
|
-
...
|
|
61
|
-
...
|
|
63
|
+
...n.nodes.flatMap((t) => [t.id, ...(t.ports ?? []).map((r) => r.id)]),
|
|
64
|
+
...n.edges.map((t) => t.id)
|
|
62
65
|
]);
|
|
63
|
-
let
|
|
64
|
-
for (; d.has(
|
|
65
|
-
const
|
|
66
|
-
id:
|
|
67
|
-
children:
|
|
68
|
-
edges:
|
|
66
|
+
let i = "$graph";
|
|
67
|
+
for (; d.has(i); ) i += "$";
|
|
68
|
+
const h = await c.layout({
|
|
69
|
+
id: i,
|
|
70
|
+
children: s,
|
|
71
|
+
edges: n.edges.map((t) => ({
|
|
69
72
|
id: t.id,
|
|
70
73
|
sources: [t.sourcePort ?? t.source],
|
|
71
74
|
targets: [t.targetPort ?? t.target]
|
|
72
75
|
})),
|
|
73
76
|
layoutOptions: {
|
|
74
77
|
"elk.algorithm": "layered",
|
|
75
|
-
"elk.direction":
|
|
78
|
+
"elk.direction": o.direction ?? "RIGHT",
|
|
76
79
|
"elk.edgeRouting": "ORTHOGONAL",
|
|
77
80
|
"elk.hierarchyHandling": "INCLUDE_CHILDREN",
|
|
78
|
-
"elk.spacing.nodeNode": String(
|
|
79
|
-
"elk.layered.spacing.nodeNodeBetweenLayers": String(
|
|
81
|
+
"elk.spacing.nodeNode": String(o.spacing ?? 64),
|
|
82
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": String(o.spacing ?? 64),
|
|
80
83
|
"elk.layered.considerModelOrder.strategy": "NODES_AND_EDGES",
|
|
81
84
|
"elk.randomSeed": "1"
|
|
82
85
|
}
|
|
83
|
-
}), f = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map(),
|
|
84
|
-
for (const
|
|
85
|
-
const
|
|
86
|
+
}), f = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map(), E = (t) => {
|
|
87
|
+
for (const r of t.edges ?? []) {
|
|
88
|
+
const p = r.container ?? t.id, l = f.get(p) ?? { x: 0, y: 0 };
|
|
86
89
|
x.set(
|
|
87
|
-
|
|
88
|
-
(
|
|
90
|
+
r.id,
|
|
91
|
+
(r.sections ?? []).map(
|
|
89
92
|
(g) => [g.startPoint, ...g.bendPoints ?? [], g.endPoint].map((w) => ({
|
|
90
93
|
x: w.x + l.x,
|
|
91
94
|
y: w.y + l.y
|
|
@@ -93,33 +96,34 @@ async function O(i, n, p) {
|
|
|
93
96
|
)
|
|
94
97
|
);
|
|
95
98
|
}
|
|
96
|
-
for (const
|
|
97
|
-
},
|
|
98
|
-
const l =
|
|
99
|
+
for (const r of t.children ?? []) E(r);
|
|
100
|
+
}, I = (t, r, p) => {
|
|
101
|
+
const l = r + (t.x ?? 0), g = p + (t.y ?? 0);
|
|
99
102
|
f.set(t.id, { x: l, y: g, width: t.width ?? 0, height: t.height ?? 0 });
|
|
100
|
-
for (const w of t.children ?? [])
|
|
103
|
+
for (const w of t.children ?? []) I(w, l, g);
|
|
101
104
|
};
|
|
102
|
-
for (const t of
|
|
103
|
-
|
|
104
|
-
const y = !
|
|
105
|
-
const
|
|
106
|
-
return { ...t, ...
|
|
105
|
+
for (const t of h.children ?? []) I(t, 0, 0);
|
|
106
|
+
E(h);
|
|
107
|
+
const y = !o.positions?.length && o.anchor && f.get(o.anchor.nodeId), m = y ? o.anchor.position.x - y.x : 0, u = y ? o.anchor.position.y - y.y : 0, k = n.nodes.map((t) => {
|
|
108
|
+
const r = f.get(t.id);
|
|
109
|
+
return { ...t, ...r, x: r.x + m, y: r.y + u };
|
|
107
110
|
});
|
|
108
111
|
return v(
|
|
109
112
|
{
|
|
110
113
|
nodes: k,
|
|
111
|
-
edges:
|
|
114
|
+
edges: n.edges.map((t) => ({
|
|
112
115
|
...t,
|
|
113
116
|
sections: (x.get(t.id) ?? []).map(
|
|
114
|
-
(
|
|
117
|
+
(r) => r.map((p) => ({ x: p.x + m, y: p.y + u }))
|
|
115
118
|
)
|
|
116
119
|
})),
|
|
117
|
-
bounds: { x: m, y: u, width:
|
|
120
|
+
bounds: { x: m, y: u, width: h.width ?? 0, height: h.height ?? 0 }
|
|
118
121
|
},
|
|
119
|
-
|
|
122
|
+
o,
|
|
123
|
+
n.nodes
|
|
120
124
|
);
|
|
121
125
|
}
|
|
122
126
|
export {
|
|
123
|
-
|
|
124
|
-
|
|
127
|
+
P as computeGraphLayout,
|
|
128
|
+
N as validateGraphInput
|
|
125
129
|
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ELK } from 'elkjs/lib/elk-api';
|
|
2
|
+
import type { GraphInput, GraphLayout, GraphLayoutOptions } from './types';
|
|
3
|
+
/** Lay out each containment level as peers, then route the complete compound graph. */
|
|
4
|
+
export declare function computePackedGraphLayout(input: GraphInput, options: GraphLayoutOptions, engine: Pick<ELK, 'layout'>): Promise<GraphLayout>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { applyGraphPositions as b, routeGraphGeometry as G } from "./positions.js";
|
|
2
|
+
async function O(d, n, k) {
|
|
3
|
+
const a = new Map(d.nodes.map((e) => [e.id, { ...e, x: 0, y: 0 }])), r = /* @__PURE__ */ new Map();
|
|
4
|
+
for (const e of a.values()) {
|
|
5
|
+
const i = r.get(e.parentId) ?? [];
|
|
6
|
+
i.push(e), r.set(e.parentId, i);
|
|
7
|
+
}
|
|
8
|
+
const x = /* @__PURE__ */ new Set([
|
|
9
|
+
...d.nodes.flatMap((e) => [e.id, ...(e.ports ?? []).map((i) => i.id)]),
|
|
10
|
+
...d.edges.map((e) => e.id)
|
|
11
|
+
]);
|
|
12
|
+
let l = "$packed";
|
|
13
|
+
for (; x.has(l); ) l += "$";
|
|
14
|
+
const g = n.groupPadding ?? { top: 64, right: 28, bottom: 28, left: 28 }, p = (e, i, o) => {
|
|
15
|
+
e.x += i, e.y += o;
|
|
16
|
+
for (const c of r.get(e.id) ?? []) p(c, i, o);
|
|
17
|
+
}, y = (e, i) => {
|
|
18
|
+
let o = a.get(e);
|
|
19
|
+
for (; o && o.parentId !== i; )
|
|
20
|
+
o = o.parentId ? a.get(o.parentId) : void 0;
|
|
21
|
+
return o;
|
|
22
|
+
}, m = async (e) => {
|
|
23
|
+
const i = r.get(e) ?? [];
|
|
24
|
+
for (const t of i) {
|
|
25
|
+
if (!r.has(t.id)) continue;
|
|
26
|
+
const s = await m(t.id);
|
|
27
|
+
t.width = Math.max(t.width, s.width), t.height = Math.max(t.height, s.height);
|
|
28
|
+
}
|
|
29
|
+
if (!i.length) return { width: 0, height: 0 };
|
|
30
|
+
const o = /* @__PURE__ */ new Map();
|
|
31
|
+
for (const t of d.edges) {
|
|
32
|
+
const s = y(t.source, e), h = y(t.target, e);
|
|
33
|
+
if (!s || !h || s.id === h.id) continue;
|
|
34
|
+
const w = JSON.stringify([s.id, h.id]);
|
|
35
|
+
o.has(w) || o.set(w, { id: t.id, sources: [s.id], targets: [h.id] });
|
|
36
|
+
}
|
|
37
|
+
const c = await k.layout({
|
|
38
|
+
id: e ?? l,
|
|
39
|
+
children: i.map((t) => ({ id: t.id, width: t.width, height: t.height })),
|
|
40
|
+
edges: [...o.values()],
|
|
41
|
+
layoutOptions: {
|
|
42
|
+
"elk.algorithm": o.size ? "layered" : "rectpacking",
|
|
43
|
+
"elk.direction": n.direction ?? "RIGHT",
|
|
44
|
+
"elk.edgeRouting": "ORTHOGONAL",
|
|
45
|
+
"elk.separateConnectedComponents": "true",
|
|
46
|
+
"elk.aspectRatio": String(n.aspectRatio),
|
|
47
|
+
"elk.spacing.componentComponent": String(n.spacing ?? 64),
|
|
48
|
+
"elk.spacing.nodeNode": String(n.spacing ?? 64),
|
|
49
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": String(n.spacing ?? 64),
|
|
50
|
+
"elk.layered.considerModelOrder.strategy": "NODES_AND_EDGES",
|
|
51
|
+
"elk.padding": e ? `[top=${g.top},left=${g.left},bottom=${g.bottom},right=${g.right}]` : "[top=12,left=12,bottom=12,right=12]",
|
|
52
|
+
"elk.randomSeed": "1"
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
for (const t of c.children ?? []) {
|
|
56
|
+
const s = a.get(t.id);
|
|
57
|
+
p(s, (t.x ?? 0) - s.x, (t.y ?? 0) - s.y);
|
|
58
|
+
}
|
|
59
|
+
return { width: c.width ?? 0, height: c.height ?? 0 };
|
|
60
|
+
}, S = await m(), f = !n.positions?.length && n.anchor && a.get(n.anchor.nodeId);
|
|
61
|
+
if (f) {
|
|
62
|
+
const e = n.anchor.position.x - f.x, i = n.anchor.position.y - f.y;
|
|
63
|
+
for (const o of r.get(void 0) ?? []) p(o, e, i);
|
|
64
|
+
}
|
|
65
|
+
const u = {
|
|
66
|
+
nodes: [...a.values()],
|
|
67
|
+
edges: d.edges.map((e) => ({ ...e, sections: [] })),
|
|
68
|
+
bounds: { x: 0, y: 0, ...S }
|
|
69
|
+
};
|
|
70
|
+
return n.positions?.length ? b(u, n, d.nodes) : G(u);
|
|
71
|
+
}
|
|
72
|
+
export {
|
|
73
|
+
O as computePackedGraphLayout
|
|
74
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
import type { GraphLayout, GraphLayoutOptions } from './types';
|
|
2
|
-
/** Apply
|
|
3
|
-
export declare function applyGraphPositions(layout: GraphLayout, options: GraphLayoutOptions): GraphLayout;
|
|
1
|
+
import type { GraphLayout, GraphLayoutOptions, GraphNode } from './types';
|
|
2
|
+
/** Apply explicit fixed or preferred positions, then route the resulting geometry once. */
|
|
3
|
+
export declare function applyGraphPositions(layout: GraphLayout, options: GraphLayoutOptions, input: readonly GraphNode[]): GraphLayout;
|
|
4
|
+
/** Shared routing and bounds for explicit positions and packed compound geometry. */
|
|
5
|
+
export declare function routeGraphGeometry(layout: GraphLayout): GraphLayout;
|
|
@@ -1,134 +1,174 @@
|
|
|
1
|
-
const
|
|
2
|
-
left:
|
|
3
|
-
top:
|
|
4
|
-
right:
|
|
5
|
-
bottom:
|
|
6
|
-
}),
|
|
7
|
-
(
|
|
1
|
+
const T = (r, a = 0) => ({
|
|
2
|
+
left: r.x - a,
|
|
3
|
+
top: r.y - a,
|
|
4
|
+
right: r.x + r.width + a,
|
|
5
|
+
bottom: r.y + r.height + a
|
|
6
|
+
}), S = (r, a) => r.x > a.left && r.x < a.right && r.y > a.top && r.y < a.bottom, O = (r, a, w) => !w.some(
|
|
7
|
+
(c) => r.x === a.x ? r.x > c.left && r.x < c.right && Math.max(r.y, a.y) > c.top && Math.min(r.y, a.y) < c.bottom : r.y > c.top && r.y < c.bottom && Math.max(r.x, a.x) > c.left && Math.min(r.x, a.x) < c.right
|
|
8
8
|
);
|
|
9
|
-
function
|
|
10
|
-
if (
|
|
9
|
+
function P(r, a, w) {
|
|
10
|
+
if (w.some((e) => S(r, e) || S(a, e)))
|
|
11
11
|
throw new Error("Pinned graph positions obstruct an edge endpoint");
|
|
12
|
-
const
|
|
13
|
-
.../* @__PURE__ */ new Set([
|
|
14
|
-
].sort((
|
|
15
|
-
.../* @__PURE__ */ new Set([
|
|
16
|
-
].sort((
|
|
17
|
-
let
|
|
18
|
-
for (
|
|
19
|
-
const
|
|
20
|
-
if (
|
|
21
|
-
|
|
12
|
+
const c = [
|
|
13
|
+
.../* @__PURE__ */ new Set([r.x, a.x, ...w.flatMap((e) => [e.left, e.right])])
|
|
14
|
+
].sort((e, i) => e - i), m = [
|
|
15
|
+
.../* @__PURE__ */ new Set([r.y, a.y, ...w.flatMap((e) => [e.top, e.bottom])])
|
|
16
|
+
].sort((e, i) => e - i), l = (e) => ({ x: c[e % c.length], y: m[Math.floor(e / c.length)] }), g = m.indexOf(r.y) * c.length + c.indexOf(r.x), n = m.indexOf(a.y) * c.length + c.indexOf(a.x), M = /* @__PURE__ */ new Map([[g, 0]]), d = /* @__PURE__ */ new Map(), t = [], u = (e) => {
|
|
17
|
+
let i = t.length;
|
|
18
|
+
for (t.push(e); i > 0; ) {
|
|
19
|
+
const x = i - 1 >> 1;
|
|
20
|
+
if (t[x].score <= e.score) break;
|
|
21
|
+
t[i] = t[x], i = x;
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
},
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
let
|
|
28
|
-
for (;
|
|
29
|
-
let
|
|
30
|
-
if (
|
|
31
|
-
|
|
23
|
+
t[i] = e;
|
|
24
|
+
}, I = () => {
|
|
25
|
+
const e = t[0], i = t.pop();
|
|
26
|
+
if (t.length) {
|
|
27
|
+
let x = 0;
|
|
28
|
+
for (; x * 2 + 1 < t.length; ) {
|
|
29
|
+
let h = x * 2 + 1;
|
|
30
|
+
if (h + 1 < t.length && t[h + 1].score < t[h].score && h++, t[h].score >= i.score) break;
|
|
31
|
+
t[x] = t[h], x = h;
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
t[x] = i;
|
|
34
34
|
}
|
|
35
|
-
return
|
|
35
|
+
return e;
|
|
36
36
|
};
|
|
37
|
-
|
|
38
|
-
let
|
|
39
|
-
for (;
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
42
|
-
if (
|
|
43
|
-
const
|
|
44
|
-
let
|
|
45
|
-
for (;
|
|
46
|
-
|
|
47
|
-
return
|
|
48
|
-
const
|
|
49
|
-
return !
|
|
37
|
+
u({ id: g, score: 0, cost: 0 });
|
|
38
|
+
let v = 0;
|
|
39
|
+
for (; t.length && v++ < 5e4; ) {
|
|
40
|
+
const e = I();
|
|
41
|
+
if (e.cost !== M.get(e.id)) continue;
|
|
42
|
+
if (e.id === n) {
|
|
43
|
+
const y = [l(n)];
|
|
44
|
+
let o = n;
|
|
45
|
+
for (; o !== g; )
|
|
46
|
+
o = d.get(o), y.push(l(o));
|
|
47
|
+
return y.reverse(), y.filter((p, f) => {
|
|
48
|
+
const E = y[f - 1], b = y[f + 1];
|
|
49
|
+
return !E || !b || !(E.x === p.x && p.x === b.x || E.y === p.y && p.y === b.y);
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
const i = l(e.id), x = e.id % c.length, h = Math.floor(e.id / c.length), s = [
|
|
53
|
+
x ? e.id - 1 : -1,
|
|
54
|
+
x + 1 < c.length ? e.id + 1 : -1,
|
|
55
|
+
h ? e.id - c.length : -1,
|
|
56
|
+
h + 1 < m.length ? e.id + c.length : -1
|
|
57
57
|
];
|
|
58
|
-
for (const
|
|
59
|
-
if (
|
|
60
|
-
const
|
|
61
|
-
|
|
58
|
+
for (const y of s) {
|
|
59
|
+
if (y < 0) continue;
|
|
60
|
+
const o = l(y), p = e.cost + Math.abs(i.x - o.x) + Math.abs(i.y - o.y);
|
|
61
|
+
p >= (M.get(y) ?? 1 / 0) || !O(i, o, w) || (M.set(y, p), d.set(y, e.id), u({ id: y, cost: p, score: p + Math.abs(o.x - a.x) + Math.abs(o.y - a.y) }));
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
throw new Error("Pinned graph positions cannot be routed within the layout budget");
|
|
65
65
|
}
|
|
66
|
-
function
|
|
67
|
-
if (!
|
|
68
|
-
const
|
|
69
|
-
for (const t of
|
|
70
|
-
if (!
|
|
66
|
+
function k(r, a, w) {
|
|
67
|
+
if (!a.positions?.length) return r;
|
|
68
|
+
const c = new Map(r.nodes.map((t) => [t.id, { ...t }])), m = /* @__PURE__ */ new Map();
|
|
69
|
+
for (const t of a.positions) {
|
|
70
|
+
if (!c.has(t.nodeId) || m.has(t.nodeId) || !Number.isFinite(t.x) || !Number.isFinite(t.y))
|
|
71
71
|
throw new Error(`Invalid graph position: ${t.nodeId}`);
|
|
72
|
-
|
|
72
|
+
m.set(t.nodeId, t);
|
|
73
73
|
}
|
|
74
|
-
const
|
|
75
|
-
for (const t of
|
|
74
|
+
const l = /* @__PURE__ */ new Map();
|
|
75
|
+
for (const t of c.values())
|
|
76
76
|
if (t.parentId) {
|
|
77
|
-
const
|
|
78
|
-
|
|
77
|
+
const u = l.get(t.parentId) ?? [];
|
|
78
|
+
u.push(t), l.set(t.parentId, u);
|
|
79
79
|
}
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
t.x =
|
|
83
|
-
const
|
|
84
|
-
for (const
|
|
85
|
-
if (!
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
80
|
+
const g = a.groupPadding ?? { top: 64, left: 28, right: 28, bottom: 28 }, n = a.positionMode === "preferred", M = new Map(w.map((t) => [t.id, t])), d = (t, u, I) => {
|
|
81
|
+
const v = { x: t.x, y: t.y }, e = m.get(t.id);
|
|
82
|
+
t.x = e?.x ?? t.x + u, t.y = e?.y ?? t.y + I;
|
|
83
|
+
const i = l.get(t.id) ?? [];
|
|
84
|
+
for (const o of i) d(o, t.x - v.x, t.y - v.y);
|
|
85
|
+
if (!i.length || n) return;
|
|
86
|
+
const x = Math.min(...i.map((o) => o.x)) - g.left, h = Math.min(...i.map((o) => o.y)) - g.top;
|
|
87
|
+
if (e && (x < t.x || h < t.y))
|
|
88
88
|
throw new Error(`Pinned child lies outside group content: ${t.id}`);
|
|
89
|
-
const
|
|
89
|
+
const s = Math.max(
|
|
90
90
|
t.x + t.width,
|
|
91
|
-
...
|
|
92
|
-
),
|
|
91
|
+
...i.map((o) => o.x + o.width + g.right)
|
|
92
|
+
), y = Math.max(
|
|
93
93
|
t.y + t.height,
|
|
94
|
-
...
|
|
94
|
+
...i.map((o) => o.y + o.height + g.bottom)
|
|
95
95
|
);
|
|
96
|
-
|
|
96
|
+
e || (t.x = Math.min(t.x, x), t.y = Math.min(t.y, h)), t.width = s - t.x, t.height = y - t.y;
|
|
97
97
|
};
|
|
98
|
-
for (const t of
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
98
|
+
for (const t of c.values()) t.parentId || d(t, 0, 0);
|
|
99
|
+
if (n) {
|
|
100
|
+
const t = Math.max(16, a.spacing ?? 64), u = (i, x, h) => {
|
|
101
|
+
i.x += x, i.y += h;
|
|
102
|
+
for (const s of l.get(i.id) ?? []) u(s, x, h);
|
|
103
|
+
}, I = (i) => {
|
|
104
|
+
const x = [];
|
|
105
|
+
for (const h of [...i].sort(
|
|
106
|
+
(s, y) => s.y - y.y || s.x - y.x || s.id.localeCompare(y.id)
|
|
107
|
+
)) {
|
|
108
|
+
const s = { x: h.x, y: h.y };
|
|
109
|
+
for (const p of [...x].sort((f, E) => f.x - E.x))
|
|
110
|
+
h.y < p.y + p.height + t && h.y + h.height + t > p.y && s.x < p.x + p.width + t && s.x + h.width + t > p.x && (s.x = p.x + p.width + t);
|
|
111
|
+
const y = { x: h.x, y: h.y };
|
|
112
|
+
for (const p of [...x].sort((f, E) => f.y - E.y))
|
|
113
|
+
h.x < p.x + p.width + t && h.x + h.width + t > p.x && y.y < p.y + p.height + t && y.y + h.height + t > p.y && (y.y = p.y + p.height + t);
|
|
114
|
+
const o = s.x - h.x < y.y - h.y ? s : y;
|
|
115
|
+
u(h, o.x - h.x, o.y - h.y), x.push(h);
|
|
116
|
+
}
|
|
117
|
+
}, v = (i) => {
|
|
118
|
+
const x = l.get(i.id) ?? [];
|
|
119
|
+
if (!x.length) return;
|
|
120
|
+
for (const f of x) v(f);
|
|
121
|
+
I(x);
|
|
122
|
+
const h = Math.max(12, g.left), s = Math.max(12, g.top), y = Math.max(12, g.right), o = Math.max(12, g.bottom), p = m.get(i.id);
|
|
123
|
+
i.x = Math.min(p?.x ?? 1 / 0, Math.min(...x.map((f) => f.x)) - h), i.y = Math.min(p?.y ?? 1 / 0, Math.min(...x.map((f) => f.y)) - s), i.width = Math.max(
|
|
124
|
+
M.get(i.id).width,
|
|
125
|
+
Math.max(...x.map((f) => f.x + f.width)) + y - i.x
|
|
126
|
+
), i.height = Math.max(
|
|
127
|
+
M.get(i.id).height,
|
|
128
|
+
Math.max(...x.map((f) => f.y + f.height)) + o - i.y
|
|
129
|
+
);
|
|
130
|
+
}, e = [...c.values()].filter((i) => !i.parentId);
|
|
131
|
+
for (const i of e) v(i);
|
|
132
|
+
I(e);
|
|
133
|
+
}
|
|
134
|
+
return N({ ...r, nodes: [...c.values()] });
|
|
135
|
+
}
|
|
136
|
+
function N(r) {
|
|
137
|
+
if (!r.nodes.length) return r;
|
|
138
|
+
const a = new Map(r.nodes.map((n) => [n.id, n])), w = r.edges.map((n) => {
|
|
139
|
+
const M = a.get(n.source), d = a.get(n.target), t = (s, y, o) => s.ports?.find((p) => p.id === y)?.side ?? o, u = M.x + M.width / 2 <= d.x + d.width / 2, I = (s, y) => {
|
|
140
|
+
const o = { x: s.x + s.width / 2, y: s.y + s.height / 2 };
|
|
141
|
+
return y === "NORTH" ? [
|
|
142
|
+
{ x: o.x, y: s.y },
|
|
143
|
+
{ x: o.x, y: s.y - 8 }
|
|
144
|
+
] : y === "SOUTH" ? [
|
|
145
|
+
{ x: o.x, y: s.y + s.height },
|
|
146
|
+
{ x: o.x, y: s.y + s.height + 8 }
|
|
147
|
+
] : y === "WEST" ? [
|
|
148
|
+
{ x: s.x, y: o.y },
|
|
149
|
+
{ x: s.x - 8, y: o.y }
|
|
111
150
|
] : [
|
|
112
|
-
{ x:
|
|
113
|
-
{ x:
|
|
151
|
+
{ x: s.x + s.width, y: o.y },
|
|
152
|
+
{ x: s.x + s.width + 8, y: o.y }
|
|
114
153
|
];
|
|
115
|
-
}, [
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
),
|
|
119
|
-
return { ...
|
|
120
|
-
}),
|
|
154
|
+
}, [v, e] = I(M, t(M, n.sourcePort, u ? "EAST" : "WEST")), [i, x] = I(
|
|
155
|
+
d,
|
|
156
|
+
t(d, n.targetPort, M === d ? "NORTH" : u ? "WEST" : "EAST")
|
|
157
|
+
), h = [...a.values()].filter((s) => s.kind !== "group").map((s) => T(s, 4));
|
|
158
|
+
return { ...n, sections: [[v, ...P(e, x, h), i]] };
|
|
159
|
+
}), c = [...a.values()], m = w.flatMap((n) => n.sections.flat()), l = Math.min(...c.map((n) => n.x), ...m.map((n) => n.x)), g = Math.min(...c.map((n) => n.y), ...m.map((n) => n.y));
|
|
121
160
|
return {
|
|
122
|
-
nodes:
|
|
123
|
-
edges:
|
|
161
|
+
nodes: c,
|
|
162
|
+
edges: w,
|
|
124
163
|
bounds: {
|
|
125
|
-
x:
|
|
126
|
-
y:
|
|
127
|
-
width: Math.max(...
|
|
128
|
-
height: Math.max(...
|
|
164
|
+
x: l,
|
|
165
|
+
y: g,
|
|
166
|
+
width: Math.max(...c.map((n) => n.x + n.width), ...m.map((n) => n.x)) - l,
|
|
167
|
+
height: Math.max(...c.map((n) => n.y + n.height), ...m.map((n) => n.y)) - g
|
|
129
168
|
}
|
|
130
169
|
};
|
|
131
170
|
}
|
|
132
171
|
export {
|
|
133
|
-
|
|
172
|
+
k as applyGraphPositions,
|
|
173
|
+
N as routeGraphGeometry
|
|
134
174
|
};
|
|
@@ -46,10 +46,14 @@ export interface GraphLayout {
|
|
|
46
46
|
bounds: GraphBounds;
|
|
47
47
|
}
|
|
48
48
|
export interface GraphLayoutOptions {
|
|
49
|
-
/**
|
|
49
|
+
/** Desired width/height when packing disconnected objects, including group members. */
|
|
50
|
+
aspectRatio?: number;
|
|
51
|
+
/** Absolute world positions. Descendants move with their group. Invalid positions always fail. */
|
|
50
52
|
positions?: readonly (GraphPoint & {
|
|
51
53
|
nodeId: string;
|
|
52
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';
|
|
53
57
|
direction?: 'RIGHT' | 'DOWN' | 'LEFT' | 'UP';
|
|
54
58
|
spacing?: number;
|
|
55
59
|
groupPadding?: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createComponent as n, insert as l, addEventListener as v, effect as C, setAttribute as F, Portal as d, memo as P, template as c, delegateEvents as L } from "solid-js/web";
|
|
2
2
|
import { createMemo as R, createEffect as f, onCleanup as _, Show as s } from "solid-js";
|
|
3
|
-
import { Motion as w } from "../../node_modules/.pnpm/solid-motionone@1.0.4_solid-js@1.9.
|
|
3
|
+
import { Motion as w } from "../../node_modules/.pnpm/solid-motionone@1.0.4_solid-js@1.9.17/node_modules/solid-motionone/dist/index.js";
|
|
4
4
|
import { easing as B, duration as k } from "../../utils/animations.js";
|
|
5
5
|
import { useOverlayMask as K } from "../../hooks/useOverlayMask.js";
|
|
6
6
|
import { X as Z } from "../icons/index.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { insert as m, createComponent as d, effect as K, setAttribute as I, memo as B, className as He, template as $, Dynamic as Ke, Portal as We, setStyleProperty as Ne, use as Ve, delegateEvents as Ge } from "solid-js/web";
|
|
2
2
|
import { createSignal as de, onCleanup as p, createEffect as ee, createMemo as A, Show as R, For as te, Index as Ue } from "solid-js";
|
|
3
|
-
import { Motion as W } from "../../node_modules/.pnpm/solid-motionone@1.0.4_solid-js@1.9.
|
|
3
|
+
import { Motion as W } from "../../node_modules/.pnpm/solid-motionone@1.0.4_solid-js@1.9.17/node_modules/solid-motionone/dist/index.js";
|
|
4
4
|
import { easing as N, duration as V } from "../../utils/animations.js";
|
|
5
5
|
import { Plus as qe } from "../icons/index.js";
|
|
6
6
|
import { startHotInteraction as ze } from "../../utils/hotInteraction.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { insert as n, createComponent as c, memo as s, effect as d, setAttribute as u, template as k, delegateEvents as v } from "solid-js/web";
|
|
2
|
-
import { Motion as m } from "../../node_modules/.pnpm/solid-motionone@1.0.4_solid-js@1.9.
|
|
2
|
+
import { Motion as m } from "../../node_modules/.pnpm/solid-motionone@1.0.4_solid-js@1.9.17/node_modules/solid-motionone/dist/index.js";
|
|
3
3
|
import { easing as f, duration as h } from "../../utils/animations.js";
|
|
4
4
|
import { Lock as g, Unlock as _ } from "../icons/index.js";
|
|
5
5
|
var L = /* @__PURE__ */ k("<button type=button class=workbench-lock-button data-floe-surface=floating data-floe-canvas-interactive=true><span class=workbench-lock-button__icon>"), w = /* @__PURE__ */ k("<span class=workbench-lock-button__kbd>");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createComponent as r, insert as l, template as s, delegateEvents as y } from "solid-js/web";
|
|
2
2
|
import { Show as f } from "solid-js";
|
|
3
|
-
import { Motion as i } from "../../node_modules/.pnpm/solid-motionone@1.0.4_solid-js@1.9.
|
|
3
|
+
import { Motion as i } from "../../node_modules/.pnpm/solid-motionone@1.0.4_solid-js@1.9.17/node_modules/solid-motionone/dist/index.js";
|
|
4
4
|
import { easing as h, duration as c } from "../../utils/animations.js";
|
|
5
5
|
import { useOverlayMask as b } from "../../hooks/useOverlayMask.js";
|
|
6
6
|
import { X as v } from "../icons/index.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createComponent as m, mergeProps as v, Dynamic as x } from "solid-js/web";
|
|
2
2
|
import { createSignal as p, createContext as d, splitProps as P, useContext as l, createEffect as u, onCleanup as S, batch as c } from "solid-js";
|
|
3
|
-
import { resolveFirst as E } from "../../../../@solid-primitives_refs@1.1.4_solid-js@1.9.
|
|
4
|
-
import { createSwitchTransition as y } from "../../../../@solid-primitives_transition-group@1.1.2_solid-js@1.9.
|
|
5
|
-
import { combineStyle as C } from "../../../../@solid-primitives_props@3.2.4_solid-js@1.9.
|
|
3
|
+
import { resolveFirst as E } from "../../../../@solid-primitives_refs@1.1.4_solid-js@1.9.17/node_modules/@solid-primitives/refs/dist/index.js";
|
|
4
|
+
import { createSwitchTransition as y } from "../../../../@solid-primitives_transition-group@1.1.2_solid-js@1.9.17/node_modules/@solid-primitives/transition-group/dist/index.js";
|
|
5
|
+
import { combineStyle as C } from "../../../../@solid-primitives_props@3.2.4_solid-js@1.9.17/node_modules/@solid-primitives/props/dist/combineProps.js";
|
|
6
6
|
import { createMotionState as h, mountedStates as M } from "../../../../@motionone_dom@10.18.0/node_modules/@motionone/dom/dist/state/index.es.js";
|
|
7
7
|
import { createStyles as T } from "../../../../@motionone_dom@10.18.0/node_modules/@motionone/dom/dist/animate/utils/style-object.es.js";
|
|
8
8
|
var g = d(), D = (t) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@floegence/floe-webapp-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.86.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
"clean": "rm -rf dist *.tsbuildinfo"
|
|
157
157
|
},
|
|
158
158
|
"peerDependencies": {
|
|
159
|
-
"solid-js": "^1.
|
|
159
|
+
"solid-js": "^1.9.17"
|
|
160
160
|
},
|
|
161
161
|
"dependencies": {
|
|
162
162
|
"clsx": "^2.1.1",
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
},
|
|
174
174
|
"devDependencies": {
|
|
175
175
|
"@tailwindcss/vite": "^4.3.3",
|
|
176
|
-
"solid-js": "^1.9.
|
|
176
|
+
"solid-js": "^1.9.17",
|
|
177
177
|
"tailwindcss": "^4.3.3",
|
|
178
178
|
"typescript": "^5.9.3",
|
|
179
179
|
"vite": "^7.3.6",
|
|
File without changes
|
|
File without changes
|