@cnvx/nodal 0.0.4 → 0.0.5
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/README.md +6 -0
- package/dist/Diagram.svelte +22 -14
- package/dist/Diagram.svelte.d.ts +6 -6
- package/dist/DiagramController.svelte +40 -28
- package/dist/DiagramController.svelte.d.ts +2 -2
- package/dist/DiagramNode.svelte +46 -85
- package/dist/DiagramNode.svelte.d.ts +5 -8
- package/dist/PrerenderDiagram.svelte +15 -10
- package/dist/PrerenderDiagram.svelte.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +81 -81
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@ A Svelte 5 library for creating interactive node diagrams with customizable conn
|
|
|
7
7
|
- Static rendering by default
|
|
8
8
|
- SVG Rendering
|
|
9
9
|
- Fully typed
|
|
10
|
+
- Lightweight and performant
|
|
10
11
|
|
|
11
12
|
## Quick Start
|
|
12
13
|
|
|
@@ -220,3 +221,8 @@ const nodes: DiagramNodeType[] = [
|
|
|
220
221
|
## License
|
|
221
222
|
|
|
222
223
|
MIT License - see LICENSE file for details.
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
# TODOs:
|
|
227
|
+
- Refactor away from Diagram.svelte:247 into a more efficient rendering system
|
|
228
|
+
- Add a testing suite that uses the browser DOM and takes screenshots to verify correct rendering against expected outputs
|
package/dist/Diagram.svelte
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
-
const browser = !!globalThis?.window
|
|
3
|
-
const dev =
|
|
2
|
+
const browser = !!globalThis?.window;
|
|
3
|
+
const dev =
|
|
4
|
+
(globalThis as any)?.process?.env?.NODE_ENV &&
|
|
5
|
+
!(globalThis as any)?.process.env.NODE_ENV.toLowerCase().startsWith(
|
|
6
|
+
"prod",
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
console.debug({ browser, dev });
|
|
4
10
|
|
|
5
11
|
import { onMount, setContext, type Snippet } from "svelte";
|
|
6
12
|
import { SvelteMap } from "svelte/reactivity";
|
|
@@ -19,7 +25,7 @@
|
|
|
19
25
|
} from "./diagram-lib.js";
|
|
20
26
|
import { draw } from "svelte/transition";
|
|
21
27
|
|
|
22
|
-
export interface
|
|
28
|
+
export interface DiagramNodeDef {
|
|
23
29
|
id: string;
|
|
24
30
|
x: number;
|
|
25
31
|
y: number;
|
|
@@ -44,7 +50,7 @@
|
|
|
44
50
|
|
|
45
51
|
export type DiagramEdgeParams = {
|
|
46
52
|
// target: string;
|
|
47
|
-
snippet?: Snippet<[edge:
|
|
53
|
+
snippet?: Snippet<[edge: DiagramEdgeDef, path: string, extra: any]>;
|
|
48
54
|
snippetExtraArg?: any;
|
|
49
55
|
|
|
50
56
|
sourceAnchor?: Vector2;
|
|
@@ -55,14 +61,14 @@
|
|
|
55
61
|
zIndex?: number;
|
|
56
62
|
} & PathGenParams;
|
|
57
63
|
|
|
58
|
-
export type
|
|
64
|
+
export type DiagramEdgeDef = {
|
|
59
65
|
source: string;
|
|
60
66
|
target: string;
|
|
61
67
|
} & DiagramEdgeParams;
|
|
62
68
|
|
|
63
69
|
export type DiagramProps = {
|
|
64
|
-
nodes: SvelteMap<string,
|
|
65
|
-
edges: SvelteMap<string,
|
|
70
|
+
nodes: SvelteMap<string, DiagramNodeDef>;
|
|
71
|
+
edges: SvelteMap<string, DiagramEdgeDef>;
|
|
66
72
|
children: Snippet;
|
|
67
73
|
};
|
|
68
74
|
|
|
@@ -70,7 +76,7 @@
|
|
|
70
76
|
// export const getNodeOrigin = (node: DiagramNode) => node.origin ?? vector2(0.5, 0.5);
|
|
71
77
|
// export const getNodeOrigin = (node: DiagramNode) => vector2(0.0, 0.0);
|
|
72
78
|
|
|
73
|
-
const getNodeSize = (node:
|
|
79
|
+
const getNodeSize = (node: DiagramNodeDef) => ({
|
|
74
80
|
x: node.width ?? 0,
|
|
75
81
|
y: node.height ?? 0,
|
|
76
82
|
});
|
|
@@ -83,7 +89,7 @@
|
|
|
83
89
|
y1: number,
|
|
84
90
|
x2: number,
|
|
85
91
|
y2: number,
|
|
86
|
-
edge:
|
|
92
|
+
edge: DiagramEdgeDef,
|
|
87
93
|
): string {
|
|
88
94
|
const {
|
|
89
95
|
sourceAnchor: source = Anchor.CENTER_CENTER,
|
|
@@ -195,11 +201,12 @@
|
|
|
195
201
|
setContext("nodeMap", () => nodes);
|
|
196
202
|
setContext("edgeMap", () => edges);
|
|
197
203
|
setContext("dimensions", () => dimensions);
|
|
204
|
+
setContext("prerendering", false);
|
|
198
205
|
|
|
199
206
|
let width = $derived(Math.max(dimensions.max.x - dimensions.min.x, 1));
|
|
200
207
|
let height = $derived(Math.max(dimensions.max.y - dimensions.min.y, 1));
|
|
201
208
|
|
|
202
|
-
function generateEdgePath(edge:
|
|
209
|
+
function generateEdgePath(edge: DiagramEdgeDef) {
|
|
203
210
|
const sourceNode = nodes.get(edge.source)!;
|
|
204
211
|
const targetNode = nodes.get(edge.target)!;
|
|
205
212
|
|
|
@@ -221,7 +228,7 @@
|
|
|
221
228
|
);
|
|
222
229
|
}
|
|
223
230
|
|
|
224
|
-
function getNodeAnchor(node:
|
|
231
|
+
function getNodeAnchor(node: DiagramNodeDef, anchor: Vector2) {
|
|
225
232
|
const size = getNodeSize(node);
|
|
226
233
|
|
|
227
234
|
// if (!browser && !eq(anchor, Anchor.CENTER_CENTER) && eq(size, vector2(0, 0))) {
|
|
@@ -236,15 +243,16 @@
|
|
|
236
243
|
return { left, top };
|
|
237
244
|
}
|
|
238
245
|
|
|
246
|
+
// TODO: desperate need for refactoring
|
|
239
247
|
let edgesByZIndexPlane = $derived(
|
|
240
|
-
edges.values().reduce((acc, edge) => {
|
|
248
|
+
Array.from(edges.values()).reduce((acc, edge) => {
|
|
241
249
|
const zIndex = edge.zIndex ?? 0;
|
|
242
250
|
if (!acc.has(zIndex)) {
|
|
243
251
|
acc.set(zIndex, []);
|
|
244
252
|
}
|
|
245
253
|
acc.get(zIndex)!.push(edge);
|
|
246
254
|
return acc;
|
|
247
|
-
}, new Map<number,
|
|
255
|
+
}, new Map<number, DiagramEdgeDef[]>()),
|
|
248
256
|
);
|
|
249
257
|
|
|
250
258
|
// let depthMap = new SvelteMap<number, [DiagramEdge[], DiagramNode[]]>();
|
|
@@ -262,7 +270,7 @@
|
|
|
262
270
|
});
|
|
263
271
|
</script>
|
|
264
272
|
|
|
265
|
-
{#snippet defaultEdge(edge:
|
|
273
|
+
{#snippet defaultEdge(edge: DiagramEdgeDef, edgePath: string)}
|
|
266
274
|
<path
|
|
267
275
|
d={edgePath}
|
|
268
276
|
fill="none"
|
package/dist/Diagram.svelte.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Snippet } from "svelte";
|
|
2
2
|
import { SvelteMap } from "svelte/reactivity";
|
|
3
3
|
import { type Vector2 } from "./diagram-lib.js";
|
|
4
|
-
export interface
|
|
4
|
+
export interface DiagramNodeDef {
|
|
5
5
|
id: string;
|
|
6
6
|
x: number;
|
|
7
7
|
y: number;
|
|
@@ -19,7 +19,7 @@ type PathGenParams = {
|
|
|
19
19
|
center?: Vector2;
|
|
20
20
|
};
|
|
21
21
|
export type DiagramEdgeParams = {
|
|
22
|
-
snippet?: Snippet<[edge:
|
|
22
|
+
snippet?: Snippet<[edge: DiagramEdgeDef, path: string, extra: any]>;
|
|
23
23
|
snippetExtraArg?: any;
|
|
24
24
|
sourceAnchor?: Vector2;
|
|
25
25
|
targetAnchor?: Vector2;
|
|
@@ -27,17 +27,17 @@ export type DiagramEdgeParams = {
|
|
|
27
27
|
style?: string;
|
|
28
28
|
zIndex?: number;
|
|
29
29
|
} & PathGenParams;
|
|
30
|
-
export type
|
|
30
|
+
export type DiagramEdgeDef = {
|
|
31
31
|
source: string;
|
|
32
32
|
target: string;
|
|
33
33
|
} & DiagramEdgeParams;
|
|
34
34
|
export type DiagramProps = {
|
|
35
|
-
nodes: SvelteMap<string,
|
|
36
|
-
edges: SvelteMap<string,
|
|
35
|
+
nodes: SvelteMap<string, DiagramNodeDef>;
|
|
36
|
+
edges: SvelteMap<string, DiagramEdgeDef>;
|
|
37
37
|
children: Snippet;
|
|
38
38
|
};
|
|
39
39
|
declare const Diagram: import("svelte").Component<DiagramProps, {
|
|
40
|
-
generateCurvePath: (x1: number, y1: number, x2: number, y2: number, edge:
|
|
40
|
+
generateCurvePath: (x1: number, y1: number, x2: number, y2: number, edge: DiagramEdgeDef) => string;
|
|
41
41
|
}, "">;
|
|
42
42
|
type Diagram = ReturnType<typeof Diagram>;
|
|
43
43
|
export default Diagram;
|
|
@@ -1,28 +1,40 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
2
|
+
import { SvelteMap } from "svelte/reactivity";
|
|
3
|
+
import Diagram, {
|
|
4
|
+
type DiagramNodeDef,
|
|
5
|
+
type DiagramEdgeDef,
|
|
6
|
+
} from "./Diagram.svelte";
|
|
7
|
+
import {
|
|
8
|
+
createRawSnippet,
|
|
9
|
+
flushSync,
|
|
10
|
+
onMount,
|
|
11
|
+
setContext,
|
|
12
|
+
type Snippet,
|
|
13
|
+
} from "svelte";
|
|
14
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
15
|
+
import PrerenderDiagram from "./PrerenderDiagram.svelte";
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
children,
|
|
19
|
+
...rest
|
|
20
|
+
}: {
|
|
21
|
+
children: Snippet;
|
|
22
|
+
} & HTMLAttributes<HTMLDivElement> = $props();
|
|
23
|
+
|
|
24
|
+
const nodes = new SvelteMap<string, DiagramNodeDef>();
|
|
25
|
+
|
|
26
|
+
const layers = new SvelteMap<number, Record<string, DiagramNodeDef>>();
|
|
27
|
+
setContext("layerNodeMap", () => layers);
|
|
28
|
+
|
|
29
|
+
const edges = new SvelteMap<string, DiagramEdgeDef>();
|
|
30
|
+
|
|
31
|
+
// let initialDiagramContainer: HTMLElement;
|
|
32
|
+
|
|
33
|
+
// onMount(() => {
|
|
34
|
+
// initialDiagramContainer.remove();
|
|
35
|
+
// });
|
|
36
|
+
|
|
37
|
+
const initialTime = performance.now();
|
|
26
38
|
</script>
|
|
27
39
|
|
|
28
40
|
<!-- first time to register all the nodes and edges -->
|
|
@@ -32,11 +44,11 @@
|
|
|
32
44
|
<!-- this is necessary because we need to calculate the relative positions of the nodes and edges -->
|
|
33
45
|
<!-- TODO: Investigate how to do this properly with hydrate and mount and render https://svelte.dev/docs/svelte/imperative-component-api#hydrate -->
|
|
34
46
|
<div {...rest}>
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
<Diagram {nodes} {edges}>
|
|
48
|
+
{@render children()}
|
|
49
|
+
</Diagram>
|
|
38
50
|
</div>
|
|
39
|
-
<!--
|
|
51
|
+
<!--
|
|
40
52
|
<svelte:boundary>
|
|
41
53
|
{@const _ = console.log('Finished rendering diagram in', performance.now() - initialTime, 'ms')}
|
|
42
54
|
</svelte:boundary> -->
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Snippet } from
|
|
2
|
-
import type { HTMLAttributes } from
|
|
1
|
+
import { type Snippet } from "svelte";
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
3
|
type $$ComponentProps = {
|
|
4
4
|
children: Snippet;
|
|
5
5
|
} & HTMLAttributes<HTMLDivElement>;
|
package/dist/DiagramNode.svelte
CHANGED
|
@@ -1,47 +1,35 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
getContext,
|
|
4
|
-
onMount,
|
|
5
|
-
tick,
|
|
6
|
-
type ComponentProps,
|
|
7
|
-
type Snippet,
|
|
8
|
-
} from "svelte";
|
|
2
|
+
import { getContext, onMount, tick, type Snippet } from "svelte";
|
|
9
3
|
import type {
|
|
10
|
-
|
|
4
|
+
DiagramNodeDef,
|
|
11
5
|
DiagramEdgeParams,
|
|
12
|
-
|
|
6
|
+
DiagramEdgeDef,
|
|
13
7
|
} from "./Diagram.svelte";
|
|
14
8
|
import type { SvelteMap } from "svelte/reactivity";
|
|
15
9
|
import type { HTMLAttributes } from "svelte/elements";
|
|
16
|
-
import { vector2, type Vector2 } from "./diagram-lib";
|
|
10
|
+
import { vector2, type Vector2 } from "./diagram-lib.js";
|
|
17
11
|
|
|
18
|
-
// type IndividualConnectActionParam = string | Omit<DiagramEdge, 'source'>;
|
|
19
12
|
type IndividualConnectActionParam =
|
|
20
13
|
| string
|
|
21
|
-
| (DiagramEdgeParams & { target: string })
|
|
22
|
-
type IndividualConnectSourceActionParam =
|
|
23
|
-
| string
|
|
14
|
+
| (DiagramEdgeParams & { target: string })
|
|
24
15
|
| (DiagramEdgeParams & { source: string });
|
|
16
|
+
|
|
25
17
|
type DiagramNodeConnectParam =
|
|
26
18
|
| IndividualConnectActionParam
|
|
27
19
|
| IndividualConnectActionParam[];
|
|
28
|
-
type DiagramNodeConnectSourceParam =
|
|
29
|
-
| IndividualConnectSourceActionParam
|
|
30
|
-
| IndividualConnectSourceActionParam[];
|
|
31
20
|
|
|
32
21
|
export type DiagramNodeProps = {
|
|
33
22
|
children?: Snippet;
|
|
34
23
|
connect?: DiagramNodeConnectParam;
|
|
35
|
-
connectSource?: DiagramNodeConnectSourceParam;
|
|
36
24
|
autosize?: boolean;
|
|
37
25
|
origin?: Vector2;
|
|
38
|
-
} & Omit<
|
|
26
|
+
} & Omit<DiagramNodeDef, "snippet"> &
|
|
39
27
|
HTMLAttributes<HTMLDivElement>;
|
|
40
28
|
|
|
41
29
|
let {
|
|
42
30
|
children,
|
|
43
31
|
connect,
|
|
44
|
-
connectSource: connectFrom,
|
|
32
|
+
// connectSource: connectFrom,
|
|
45
33
|
id,
|
|
46
34
|
x,
|
|
47
35
|
y,
|
|
@@ -56,11 +44,12 @@
|
|
|
56
44
|
}: DiagramNodeProps = $props();
|
|
57
45
|
|
|
58
46
|
const nodeMap = (
|
|
59
|
-
getContext("nodeMap") as () => SvelteMap<string,
|
|
47
|
+
getContext("nodeMap") as () => SvelteMap<string, DiagramNodeDef>
|
|
60
48
|
)();
|
|
61
49
|
const edgeMap = (
|
|
62
|
-
getContext("edgeMap") as () => SvelteMap<string,
|
|
50
|
+
getContext("edgeMap") as () => SvelteMap<string, DiagramEdgeDef>
|
|
63
51
|
)();
|
|
52
|
+
|
|
64
53
|
let dimensions = (
|
|
65
54
|
getContext("dimensions") as () =>
|
|
66
55
|
| { min: Vector2; max: Vector2 }
|
|
@@ -76,8 +65,7 @@
|
|
|
76
65
|
y: y - (origin?.y ?? 0.5) * (height ?? 0),
|
|
77
66
|
});
|
|
78
67
|
|
|
79
|
-
|
|
80
|
-
const nodeDef: DiagramNode = $derived({
|
|
68
|
+
const nodeDef: DiagramNodeDef = $derived({
|
|
81
69
|
id,
|
|
82
70
|
x: absolutePosition.x,
|
|
83
71
|
y: absolutePosition.y,
|
|
@@ -86,17 +74,8 @@
|
|
|
86
74
|
clientOnly: clientOnly || autosize,
|
|
87
75
|
snippet: children,
|
|
88
76
|
});
|
|
89
|
-
const prerender = $state.snapshot(getContext("prerendering"));
|
|
90
|
-
|
|
91
|
-
// console.log('set', nodeDef.id, nodeDef);
|
|
92
|
-
|
|
93
|
-
// const source = elementNodeMap.get(element);
|
|
94
|
-
// if (!source) {
|
|
95
|
-
// return console.warn(`Could not find source element for`, element);
|
|
96
|
-
// }
|
|
97
77
|
|
|
98
78
|
let mounted = $state(false);
|
|
99
|
-
|
|
100
79
|
const previousEdgeIds = new Set();
|
|
101
80
|
|
|
102
81
|
// TODO: this should be done only if clientWidth is needed
|
|
@@ -108,63 +87,59 @@
|
|
|
108
87
|
// nodeDef.y -= (origin?.y ?? 0) * $state.snapshot(nodeDef.height ?? 0);
|
|
109
88
|
// }
|
|
110
89
|
|
|
111
|
-
|
|
112
|
-
|
|
90
|
+
onMount(async () => {
|
|
91
|
+
if (autosize) {
|
|
113
92
|
width = clientWidth;
|
|
114
93
|
height = clientHeight;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
94
|
+
}
|
|
117
95
|
|
|
118
|
-
onMount(async () => {
|
|
119
96
|
if (nodeDef.clientOnly) {
|
|
120
97
|
await tick();
|
|
121
98
|
mounted = true;
|
|
122
99
|
}
|
|
123
100
|
});
|
|
124
101
|
|
|
125
|
-
function updateEdgeFrom(
|
|
126
|
-
param: IndividualConnectSourceActionParam,
|
|
127
|
-
index: number = 0,
|
|
128
|
-
) {
|
|
129
|
-
const getEdgeId = (source: string, i: number) =>
|
|
130
|
-
`${source}:${nodeDef.id}:(${i})`;
|
|
131
|
-
// const edgeId = getEdgeId();
|
|
132
|
-
if (typeof param == "string") {
|
|
133
|
-
const source = param;
|
|
134
|
-
|
|
135
|
-
const edgeId = getEdgeId(source, index);
|
|
136
|
-
previousEdgeIds.add(edgeId);
|
|
137
|
-
|
|
138
|
-
edgeMap.set(edgeId, { target: nodeDef.id, source });
|
|
139
|
-
} else {
|
|
140
|
-
const edgeId = getEdgeId(param.source, index);
|
|
141
|
-
previousEdgeIds.add(edgeId);
|
|
142
|
-
|
|
143
|
-
(param as DiagramEdge).target = nodeDef.id;
|
|
144
|
-
edgeMap.set(edgeId, param as DiagramEdge);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
102
|
function updateEdge(
|
|
149
103
|
param: IndividualConnectActionParam,
|
|
150
104
|
index: number = 0,
|
|
151
105
|
) {
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
106
|
+
const selfId = nodeDef.id;
|
|
107
|
+
const getEdgeId = ({
|
|
108
|
+
source,
|
|
109
|
+
target,
|
|
110
|
+
index,
|
|
111
|
+
}: {
|
|
112
|
+
source: string;
|
|
113
|
+
target: string;
|
|
114
|
+
index: number;
|
|
115
|
+
}) => `${source}:${target}:(${index})`;
|
|
116
|
+
|
|
155
117
|
if (typeof param == "string") {
|
|
156
118
|
const target = param;
|
|
157
119
|
|
|
158
|
-
const edgeId = getEdgeId(target, index);
|
|
120
|
+
const edgeId = getEdgeId({ source: selfId, target, index });
|
|
159
121
|
previousEdgeIds.add(edgeId);
|
|
160
122
|
|
|
161
123
|
edgeMap.set(edgeId, { source: nodeDef.id, target });
|
|
162
|
-
} else {
|
|
163
|
-
const edgeId = getEdgeId(param.target, index);
|
|
124
|
+
} else if ("target" in param) {
|
|
125
|
+
// const edgeId = getEdgeId(param.target, index);
|
|
126
|
+
const edgeId = getEdgeId({
|
|
127
|
+
source: selfId,
|
|
128
|
+
target: param.target,
|
|
129
|
+
index,
|
|
130
|
+
});
|
|
164
131
|
previousEdgeIds.add(edgeId);
|
|
165
|
-
|
|
166
|
-
(param as
|
|
167
|
-
|
|
132
|
+
(param as DiagramEdgeDef).source = nodeDef.id;
|
|
133
|
+
edgeMap.set(edgeId, param as DiagramEdgeDef);
|
|
134
|
+
} else if ("source" in param) {
|
|
135
|
+
const edgeId = getEdgeId({
|
|
136
|
+
source: param.source,
|
|
137
|
+
target: selfId,
|
|
138
|
+
index,
|
|
139
|
+
});
|
|
140
|
+
previousEdgeIds.add(edgeId);
|
|
141
|
+
(param as DiagramEdgeDef).target = selfId;
|
|
142
|
+
edgeMap.set(edgeId, param as DiagramEdgeDef);
|
|
168
143
|
}
|
|
169
144
|
}
|
|
170
145
|
|
|
@@ -176,28 +151,14 @@
|
|
|
176
151
|
}
|
|
177
152
|
}
|
|
178
153
|
|
|
179
|
-
if (connectFrom) {
|
|
180
|
-
if (!Array.isArray(connectFrom)) {
|
|
181
|
-
updateEdgeFrom(connectFrom);
|
|
182
|
-
} else {
|
|
183
|
-
connectFrom.forEach(updateEdgeFrom);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
154
|
let left = $derived(nodeDef.x - (dimensions?.min.x ?? 0));
|
|
188
155
|
let top = $derived(nodeDef.y - (dimensions?.min.y ?? 0));
|
|
189
156
|
|
|
157
|
+
nodeMap.set(nodeDef.id, nodeDef);
|
|
190
158
|
$effect(() => {
|
|
191
159
|
nodeMap.set(nodeDef.id, nodeDef);
|
|
192
160
|
});
|
|
193
161
|
|
|
194
|
-
// nodeMap.set(nodeDef.id, nodeDef);
|
|
195
|
-
$effect(() => {
|
|
196
|
-
// nodeDef.x -= (origin?.x ?? 0.5) * (nodeDef?.width ?? clientWidth ?? 0);
|
|
197
|
-
// nodeDef.y -= (origin?.y ?? 0.5) * (nodeDef?.height ?? clientHeight ?? 0);
|
|
198
|
-
nodeMap.set(nodeDef.id, nodeDef);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
162
|
// $inspect(
|
|
202
163
|
// 'mounted render diagramNode',
|
|
203
164
|
// nodeDef.id,
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
import { type Snippet } from "svelte";
|
|
2
|
-
import type {
|
|
2
|
+
import type { DiagramNodeDef, DiagramEdgeParams } from "./Diagram.svelte";
|
|
3
3
|
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
-
import { type Vector2 } from "./diagram-lib";
|
|
4
|
+
import { type Vector2 } from "./diagram-lib.js";
|
|
5
5
|
type IndividualConnectActionParam = string | (DiagramEdgeParams & {
|
|
6
6
|
target: string;
|
|
7
|
-
})
|
|
8
|
-
type IndividualConnectSourceActionParam = string | (DiagramEdgeParams & {
|
|
7
|
+
}) | (DiagramEdgeParams & {
|
|
9
8
|
source: string;
|
|
10
9
|
});
|
|
11
10
|
type DiagramNodeConnectParam = IndividualConnectActionParam | IndividualConnectActionParam[];
|
|
12
|
-
type DiagramNodeConnectSourceParam = IndividualConnectSourceActionParam | IndividualConnectSourceActionParam[];
|
|
13
11
|
export type DiagramNodeProps = {
|
|
14
12
|
children?: Snippet;
|
|
15
13
|
connect?: DiagramNodeConnectParam;
|
|
16
|
-
connectSource?: DiagramNodeConnectSourceParam;
|
|
17
14
|
autosize?: boolean;
|
|
18
15
|
origin?: Vector2;
|
|
19
|
-
} & Omit<
|
|
20
|
-
declare const DiagramNode:
|
|
16
|
+
} & Omit<DiagramNodeDef, "snippet"> & HTMLAttributes<HTMLDivElement>;
|
|
17
|
+
declare const DiagramNode: import("svelte").Component<DiagramNodeProps, {}, "">;
|
|
21
18
|
type DiagramNode = ReturnType<typeof DiagramNode>;
|
|
22
19
|
export default DiagramNode;
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { setContext } from "svelte";
|
|
3
|
+
import type { DiagramProps } from "./Diagram.svelte";
|
|
4
|
+
import { vector2 } from "./diagram-lib.js";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
let { nodes, edges, children }: DiagramProps = $props();
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
setContext("nodeMap", () => nodes);
|
|
9
|
+
setContext("edgeMap", () => edges);
|
|
10
|
+
setContext("dimensions", () => ({
|
|
11
|
+
min: vector2(0, 0),
|
|
12
|
+
max: vector2(0, 0),
|
|
13
|
+
}));
|
|
14
|
+
setContext("prerendering", true);
|
|
12
15
|
</script>
|
|
13
16
|
|
|
14
17
|
<template>
|
|
15
|
-
|
|
18
|
+
{@render children()}
|
|
16
19
|
</template>
|
|
17
20
|
|
|
18
|
-
<svelte:boundary>
|
|
21
|
+
<svelte:boundary>
|
|
22
|
+
{@const _ = setContext("prerendering", false)}
|
|
23
|
+
</svelte:boundary>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DiagramProps } from
|
|
1
|
+
import type { DiagramProps } from "./Diagram.svelte";
|
|
2
2
|
declare const PrerenderDiagram: import("svelte").Component<DiagramProps, {}, "">;
|
|
3
3
|
type PrerenderDiagram = ReturnType<typeof PrerenderDiagram>;
|
|
4
4
|
export default PrerenderDiagram;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export { default as DiagramController } from './DiagramController.svelte';
|
|
|
3
3
|
export { default as DiagramNode } from './DiagramNode.svelte';
|
|
4
4
|
export { default as PrerenderDiagram } from './PrerenderDiagram.svelte';
|
|
5
5
|
export * from './diagram-lib.js';
|
|
6
|
-
export type {
|
|
6
|
+
export type { DiagramEdgeDef as DiagramEdge, DiagramEdgeParams, DiagramProps } from './Diagram.svelte';
|
|
7
7
|
export type { DiagramNodeProps } from './DiagramNode.svelte';
|
package/package.json
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
2
|
+
"name": "@cnvx/nodal",
|
|
3
|
+
"private": false,
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"version": "0.0.5",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite dev",
|
|
8
|
+
"dev-lib": "svelte-package -w",
|
|
9
|
+
"build": "vite build && npm run prepack",
|
|
10
|
+
"preview": "vite preview",
|
|
11
|
+
"prepare": "svelte-kit sync || echo ''",
|
|
12
|
+
"prepack": "svelte-kit sync && svelte-package && publint",
|
|
13
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
14
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
15
|
+
"test:capture": "bun run test/capture.ts",
|
|
16
|
+
"format": "prettier --write .",
|
|
17
|
+
"lint": "prettier --check . && eslint ."
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"!dist/**/*.test.*",
|
|
22
|
+
"!dist/**/*.spec.*"
|
|
23
|
+
],
|
|
24
|
+
"sideEffects": [
|
|
25
|
+
"**/*.css"
|
|
26
|
+
],
|
|
27
|
+
"svelte": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"type": "module",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"svelte": "./dist/index.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"svelte": "^5.0.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@eslint/compat": "^1.2.5",
|
|
41
|
+
"@eslint/js": "^9.18.0",
|
|
42
|
+
"@sveltejs/adapter-auto": "^6.0.0",
|
|
43
|
+
"@sveltejs/adapter-static": "^3.0.8",
|
|
44
|
+
"@sveltejs/kit": "^2.22.0",
|
|
45
|
+
"@sveltejs/package": "^2.0.0",
|
|
46
|
+
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
|
47
|
+
"@tailwindcss/vite": "^4.1.11",
|
|
48
|
+
"@types/bun": "^1.2.19",
|
|
49
|
+
"@types/pixelmatch": "^5.2.6",
|
|
50
|
+
"@types/pngjs": "^6.0.5",
|
|
51
|
+
"eslint": "^9.18.0",
|
|
52
|
+
"eslint-config-prettier": "^10.0.1",
|
|
53
|
+
"eslint-plugin-svelte": "^3.0.0",
|
|
54
|
+
"globals": "^16.0.0",
|
|
55
|
+
"mdsvex": "^0.12.6",
|
|
56
|
+
"pixelmatch": "^7.1.0",
|
|
57
|
+
"playwright": "^1.53.0",
|
|
58
|
+
"prettier": "^3.4.2",
|
|
59
|
+
"prettier-plugin-svelte": "^3.3.3",
|
|
60
|
+
"publint": "^0.3.2",
|
|
61
|
+
"svelte": "^5.0.0",
|
|
62
|
+
"svelte-check": "^4.0.0",
|
|
63
|
+
"typescript": "^5.0.0",
|
|
64
|
+
"typescript-eslint": "^8.20.0",
|
|
65
|
+
"vite": "^7.0.4"
|
|
66
|
+
},
|
|
67
|
+
"keywords": [
|
|
68
|
+
"svelte",
|
|
69
|
+
"diagram",
|
|
70
|
+
"nodes",
|
|
71
|
+
"graph",
|
|
72
|
+
"visualization",
|
|
73
|
+
"flow-chart",
|
|
74
|
+
"connections",
|
|
75
|
+
"bezier",
|
|
76
|
+
"smoothstep"
|
|
77
|
+
],
|
|
78
|
+
"repository": {
|
|
79
|
+
"type": "git",
|
|
80
|
+
"url": "git+https://github.com/Convex-Works/nodal.git"
|
|
81
|
+
},
|
|
82
|
+
"dependencies": {}
|
|
83
83
|
}
|