@cnvx/nodal 0.0.5 → 0.1.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.
package/dist/Diagram.svelte
CHANGED
|
@@ -1,29 +1,19 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
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 });
|
|
10
|
-
|
|
11
2
|
import { onMount, setContext, type Snippet } from "svelte";
|
|
12
3
|
import { SvelteMap } from "svelte/reactivity";
|
|
13
4
|
import {
|
|
14
|
-
debugSide,
|
|
15
5
|
eq,
|
|
16
6
|
getBezierPath,
|
|
17
7
|
getSmoothStepPath,
|
|
18
8
|
normaliseAngle,
|
|
19
9
|
Side,
|
|
20
10
|
sideForAngle,
|
|
21
|
-
unitVectorFromAngle,
|
|
22
11
|
vector2,
|
|
23
12
|
type Vector2,
|
|
24
13
|
Anchor,
|
|
14
|
+
browser,
|
|
15
|
+
dev,
|
|
25
16
|
} from "./diagram-lib.js";
|
|
26
|
-
import { draw } from "svelte/transition";
|
|
27
17
|
|
|
28
18
|
export interface DiagramNodeDef {
|
|
29
19
|
id: string;
|
|
@@ -160,7 +150,7 @@
|
|
|
160
150
|
}
|
|
161
151
|
|
|
162
152
|
function calculateDimensions(_nodes: typeof nodes) {
|
|
163
|
-
console.time("dim");
|
|
153
|
+
// console.time("dim");
|
|
164
154
|
let newMin = vector2(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
|
|
165
155
|
let newMax = vector2(Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);
|
|
166
156
|
|
|
@@ -183,7 +173,7 @@
|
|
|
183
173
|
);
|
|
184
174
|
}
|
|
185
175
|
|
|
186
|
-
console.timeEnd("dim");
|
|
176
|
+
// console.timeEnd("dim");
|
|
187
177
|
return { min: newMin, max: newMax };
|
|
188
178
|
}
|
|
189
179
|
|
|
@@ -13,42 +13,93 @@
|
|
|
13
13
|
} from "svelte";
|
|
14
14
|
import type { HTMLAttributes } from "svelte/elements";
|
|
15
15
|
import PrerenderDiagram from "./PrerenderDiagram.svelte";
|
|
16
|
+
import { browser } from "./diagram-lib.js";
|
|
16
17
|
|
|
17
18
|
let {
|
|
18
19
|
children,
|
|
20
|
+
eagerLoad = false,
|
|
21
|
+
rootMargin = "100px", // start a bit before it enters the viewport
|
|
19
22
|
...rest
|
|
20
23
|
}: {
|
|
21
24
|
children: Snippet;
|
|
25
|
+
eagerLoad?: boolean;
|
|
26
|
+
rootMargin?: string;
|
|
22
27
|
} & HTMLAttributes<HTMLDivElement> = $props();
|
|
23
28
|
|
|
24
29
|
const nodes = new SvelteMap<string, DiagramNodeDef>();
|
|
25
|
-
|
|
26
30
|
const layers = new SvelteMap<number, Record<string, DiagramNodeDef>>();
|
|
27
31
|
setContext("layerNodeMap", () => layers);
|
|
28
|
-
|
|
29
32
|
const edges = new SvelteMap<string, DiagramEdgeDef>();
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
let containerEl: HTMLDivElement | undefined;
|
|
32
35
|
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
+
// If we're SSR (not browser), or eagerLoad is false, render immediately.
|
|
37
|
+
// Otherwise wait until after load + idle + intersection.
|
|
38
|
+
let shouldRender = $derived(!eagerLoad);
|
|
36
39
|
|
|
37
40
|
const initialTime = performance.now();
|
|
41
|
+
|
|
42
|
+
onMount(() => {
|
|
43
|
+
if (!eagerLoad || !containerEl) return;
|
|
44
|
+
|
|
45
|
+
let io: IntersectionObserver | null = null;
|
|
46
|
+
|
|
47
|
+
const idle = (fn: () => void) => {
|
|
48
|
+
const ric = (window as any).requestIdleCallback as
|
|
49
|
+
| ((cb: () => void) => number)
|
|
50
|
+
| undefined;
|
|
51
|
+
if (ric) ric(fn);
|
|
52
|
+
else setTimeout(fn, 0);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const startObserving = () => {
|
|
56
|
+
// In case the element is already visible at this moment
|
|
57
|
+
io = new IntersectionObserver(
|
|
58
|
+
(entries) => {
|
|
59
|
+
if (entries.some((e) => e.isIntersecting)) {
|
|
60
|
+
shouldRender = true;
|
|
61
|
+
io?.disconnect();
|
|
62
|
+
io = null;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{ root: null, rootMargin, threshold: 0 },
|
|
66
|
+
);
|
|
67
|
+
io.observe(containerEl!);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
if (document.readyState === "complete") {
|
|
71
|
+
idle(startObserving);
|
|
72
|
+
} else {
|
|
73
|
+
// Wait until the whole document (including images) has loaded
|
|
74
|
+
window.addEventListener("load", () => idle(startObserving), {
|
|
75
|
+
once: true,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return () => {
|
|
80
|
+
io?.disconnect();
|
|
81
|
+
io = null;
|
|
82
|
+
};
|
|
83
|
+
});
|
|
38
84
|
</script>
|
|
39
85
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
<!--
|
|
45
|
-
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
</
|
|
50
|
-
|
|
86
|
+
{#if shouldRender}
|
|
87
|
+
<!-- first pass: register all the nodes and edges -->
|
|
88
|
+
<PrerenderDiagram {nodes} {edges} {children} />
|
|
89
|
+
|
|
90
|
+
<!-- second pass: render with computed positions -->
|
|
91
|
+
<div {...rest}>
|
|
92
|
+
<Diagram {nodes} {edges}>
|
|
93
|
+
{@render children()}
|
|
94
|
+
</Diagram>
|
|
95
|
+
</div>
|
|
96
|
+
{:else}
|
|
97
|
+
<!-- Lightweight placeholder / container used for intersection observation. -->
|
|
98
|
+
<div bind:this={containerEl} {...rest}></div>
|
|
99
|
+
{/if}
|
|
100
|
+
|
|
51
101
|
<!--
|
|
52
102
|
<svelte:boundary>
|
|
53
103
|
{@const _ = console.log('Finished rendering diagram in', performance.now() - initialTime, 'ms')}
|
|
54
|
-
</svelte:boundary>
|
|
104
|
+
</svelte:boundary>
|
|
105
|
+
-->
|
|
@@ -2,6 +2,8 @@ import { type Snippet } from "svelte";
|
|
|
2
2
|
import type { HTMLAttributes } from "svelte/elements";
|
|
3
3
|
type $$ComponentProps = {
|
|
4
4
|
children: Snippet;
|
|
5
|
+
eagerLoad?: boolean;
|
|
6
|
+
rootMargin?: string;
|
|
5
7
|
} & HTMLAttributes<HTMLDivElement>;
|
|
6
8
|
declare const DiagramController: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
9
|
type DiagramController = ReturnType<typeof DiagramController>;
|
package/dist/DiagramNode.svelte
CHANGED
|
@@ -187,6 +187,5 @@ top:${top}px;left:${left}px;${nodeDef.clientOnly && !mounted ? "opacity:0" : ""}
|
|
|
187
187
|
bind:clientHeight
|
|
188
188
|
></div>
|
|
189
189
|
{/if}
|
|
190
|
-
<!-- <div class="absolute top-0 left-0 w-full h-full bg-red-500"> {nodeDef.clientOnly} {mounted}</div> -->
|
|
191
190
|
{@render children?.()}
|
|
192
191
|
</div>
|
package/dist/diagram-lib.d.ts
CHANGED
package/dist/diagram-lib.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export const browser = !!globalThis?.window;
|
|
2
|
+
export const dev = globalThis?.process?.env?.NODE_ENV &&
|
|
3
|
+
!globalThis?.process.env.NODE_ENV.toLowerCase().startsWith("prod");
|
|
1
4
|
export const vector2 = (x, y) => ({ x, y });
|
|
2
5
|
export const eq = (a, b) => a.x === b.x && a.y === b.y;
|
|
3
6
|
export const Anchor = {
|