@xenolithengine/graph-render-pixi 0.7.0-beta.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -0
  3. package/dist/bezier.d.ts +30 -0
  4. package/dist/bezier.d.ts.map +1 -0
  5. package/dist/bezier.js +70 -0
  6. package/dist/bezier.js.map +1 -0
  7. package/dist/comment-renderer.d.ts +35 -0
  8. package/dist/comment-renderer.d.ts.map +1 -0
  9. package/dist/comment-renderer.js +194 -0
  10. package/dist/comment-renderer.js.map +1 -0
  11. package/dist/edge-paths.d.ts +24 -0
  12. package/dist/edge-paths.d.ts.map +1 -0
  13. package/dist/edge-paths.js +123 -0
  14. package/dist/edge-paths.js.map +1 -0
  15. package/dist/edge-renderer.d.ts +29 -0
  16. package/dist/edge-renderer.d.ts.map +1 -0
  17. package/dist/edge-renderer.js +99 -0
  18. package/dist/edge-renderer.js.map +1 -0
  19. package/dist/geom.d.ts +46 -0
  20. package/dist/geom.d.ts.map +1 -0
  21. package/dist/geom.js +54 -0
  22. package/dist/geom.js.map +1 -0
  23. package/dist/grid.d.ts +12 -0
  24. package/dist/grid.d.ts.map +1 -0
  25. package/dist/grid.js +35 -0
  26. package/dist/grid.js.map +1 -0
  27. package/dist/icons.d.ts +14 -0
  28. package/dist/icons.d.ts.map +1 -0
  29. package/dist/icons.js +32 -0
  30. package/dist/icons.js.map +1 -0
  31. package/dist/index.d.ts +34 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +20 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/interaction.d.ts +69 -0
  36. package/dist/interaction.d.ts.map +1 -0
  37. package/dist/interaction.js +229 -0
  38. package/dist/interaction.js.map +1 -0
  39. package/dist/layout.d.ts +126 -0
  40. package/dist/layout.d.ts.map +1 -0
  41. package/dist/layout.js +360 -0
  42. package/dist/layout.js.map +1 -0
  43. package/dist/macro-frame.d.ts +29 -0
  44. package/dist/macro-frame.d.ts.map +1 -0
  45. package/dist/macro-frame.js +116 -0
  46. package/dist/macro-frame.js.map +1 -0
  47. package/dist/node-renderer.d.ts +102 -0
  48. package/dist/node-renderer.d.ts.map +1 -0
  49. package/dist/node-renderer.js +776 -0
  50. package/dist/node-renderer.js.map +1 -0
  51. package/dist/reroute-renderer.d.ts +25 -0
  52. package/dist/reroute-renderer.d.ts.map +1 -0
  53. package/dist/reroute-renderer.js +163 -0
  54. package/dist/reroute-renderer.js.map +1 -0
  55. package/dist/style.d.ts +56 -0
  56. package/dist/style.d.ts.map +1 -0
  57. package/dist/style.js +102 -0
  58. package/dist/style.js.map +1 -0
  59. package/dist/text-measure.d.ts +6 -0
  60. package/dist/text-measure.d.ts.map +1 -0
  61. package/dist/text-measure.js +21 -0
  62. package/dist/text-measure.js.map +1 -0
  63. package/dist/theme.d.ts +86 -0
  64. package/dist/theme.d.ts.map +1 -0
  65. package/dist/theme.js +2 -0
  66. package/dist/theme.js.map +1 -0
  67. package/dist/viewport-math.d.ts +68 -0
  68. package/dist/viewport-math.d.ts.map +1 -0
  69. package/dist/viewport-math.js +106 -0
  70. package/dist/viewport-math.js.map +1 -0
  71. package/dist/viewport.d.ts +28 -0
  72. package/dist/viewport.d.ts.map +1 -0
  73. package/dist/viewport.js +47 -0
  74. package/dist/viewport.js.map +1 -0
  75. package/dist/virtualize.d.ts +55 -0
  76. package/dist/virtualize.d.ts.map +1 -0
  77. package/dist/virtualize.js +96 -0
  78. package/dist/virtualize.js.map +1 -0
  79. package/dist/widget-renderer.d.ts +150 -0
  80. package/dist/widget-renderer.d.ts.map +1 -0
  81. package/dist/widget-renderer.js +399 -0
  82. package/dist/widget-renderer.js.map +1 -0
  83. package/dist/xen-theme.d.ts +8 -0
  84. package/dist/xen-theme.d.ts.map +1 -0
  85. package/dist/xen-theme.js +23 -0
  86. package/dist/xen-theme.js.map +1 -0
  87. package/package.json +63 -0
@@ -0,0 +1,29 @@
1
+ import { Graphics } from 'pixi.js';
2
+ import type { XenTokens } from '@xenolithengine/graph-theme-xen';
3
+ import { type EdgePathStyle } from './edge-paths.js';
4
+ import type { PinLayout } from './layout.js';
5
+ export type { EdgePathStyle } from './edge-paths.js';
6
+ export interface RenderEdgeOptions {
7
+ /** Pin type at the source — drives wire colour. Defaults to 'any'. */
8
+ sourceType?: string;
9
+ /** Suppress the midpoint handle dot (e.g. the live drag-ghost wire has no interaction point). */
10
+ noMidpoint?: boolean;
11
+ /** Text drawn at the wire's midpoint (rendered by the editor as a PIXI Text, not by drawEdge). */
12
+ label?: string;
13
+ /** End marker drawn at the target pin. `'arrow'` draws a filled arrowhead; omit/`'none'` for none. */
14
+ markerEnd?: 'arrow' | 'none';
15
+ /** Animate a flowing dash along the wire (kept ticking only while ≥1 animated edge exists). */
16
+ animated?: boolean;
17
+ /** Transient per-frame dash offset (px) for animated edges. Not serialized; set by the editor's
18
+ * ticker. Ignored unless `animated`. */
19
+ dashPhase?: number;
20
+ /** Wire shape. Default `'bezier'` (smooth S-curve, the historical Xen look — untouched). Other
21
+ * styles render as orthogonal / straight polylines via `edge-paths.ts`. Per-edge override
22
+ * through `editor.setEdgeOptions(id, { pathStyle })`. */
23
+ pathStyle?: EdgePathStyle;
24
+ }
25
+ /** Repaint an existing Graphics with a fresh edge path. Use during drag to avoid GC pressure
26
+ * from creating a new Graphics on every pointermove. */
27
+ export declare function drawEdge(g: Graphics, from: PinLayout, to: PinLayout, tokens: XenTokens, opts?: RenderEdgeOptions): Graphics;
28
+ export declare function renderEdge(from: PinLayout, to: PinLayout, tokens: XenTokens, opts?: RenderEdgeOptions): Graphics;
29
+ //# sourceMappingURL=edge-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-renderer.d.ts","sourceRoot":"","sources":["../src/edge-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAA;AAEhE,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAG5C,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iGAAiG;IACjG,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,kGAAkG;IAClG,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sGAAsG;IACtG,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC5B,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;6CACyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;8DAE0D;IAC1D,SAAS,CAAC,EAAE,aAAa,CAAA;CAC1B;AAgBD;yDACyD;AACzD,wBAAgB,QAAQ,CACtB,CAAC,EAAE,QAAQ,EACX,IAAI,EAAE,SAAS,EACf,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,SAAS,EACjB,IAAI,GAAE,iBAAsB,GAC3B,QAAQ,CAgFV;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,SAAS,EACf,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,SAAS,EACjB,IAAI,GAAE,iBAAsB,GAC3B,QAAQ,CAEV"}
@@ -0,0 +1,99 @@
1
+ import { Graphics } from 'pixi.js';
2
+ import { bezierMidpoint, computeEdgePath, arrowHead, sampleBezier } from './bezier.js';
3
+ import { computeLinearPolyline, computeStepPolyline, computeSmoothStepPolyline, polylineMidpoint, polylineArrowHead, } from './edge-paths.js';
4
+ import { resolveEdgeColor } from './style.js';
5
+ /** Stroke bright dash segments along a sampled polyline, offset by `phase` so they travel when the
6
+ * caller animates `phase`. Approximated per-segment — fine at ~56 samples per wire. */
7
+ function drawFlowingDashes(g, pts, color, width, phase) {
8
+ const dash = 15, gap = 13, period = dash + gap;
9
+ let s = 0;
10
+ for (let i = 1; i < pts.length; i++) {
11
+ const a = pts[i - 1], b = pts[i];
12
+ const segLen = Math.hypot(b.x - a.x, b.y - a.y);
13
+ const m = (((s + segLen / 2 - phase) % period) + period) % period;
14
+ if (m < dash)
15
+ g.moveTo(a.x, a.y).lineTo(b.x, b.y).stroke({ color, width });
16
+ s += segLen;
17
+ }
18
+ }
19
+ /** Repaint an existing Graphics with a fresh edge path. Use during drag to avoid GC pressure
20
+ * from creating a new Graphics on every pointermove. */
21
+ export function drawEdge(g, from, to, tokens, opts = {}) {
22
+ const sourceType = opts.sourceType ?? 'any';
23
+ const isExec = sourceType === 'exec';
24
+ const color = resolveEdgeColor(sourceType, tokens);
25
+ const width = isExec ? tokens.geometry.edge.execWidth : tokens.geometry.edge.width;
26
+ const style = opts.pathStyle ?? 'bezier';
27
+ g.clear();
28
+ // Bezier path stays on the historical hot path — fastest (native PIXI bezierCurveTo), best-
29
+ // looking for typical DAG edges. The polyline branch below only fires when the user asked for
30
+ // step / smoothstep / linear via opts.pathStyle.
31
+ if (style === 'bezier') {
32
+ const path = computeEdgePath(from, to, {
33
+ bezierTension: tokens.geometry.edge.bezierTension,
34
+ minHorizontalSpread: tokens.geometry.edge.minHorizontalSpread,
35
+ });
36
+ if (opts.animated) {
37
+ g.moveTo(path.start.x, path.start.y)
38
+ .bezierCurveTo(path.c1.x, path.c1.y, path.c2.x, path.c2.y, path.end.x, path.end.y)
39
+ .stroke({ color, width, alpha: 0.3 });
40
+ const approxLen = Math.hypot(path.c1.x - path.start.x, path.c1.y - path.start.y) +
41
+ Math.hypot(path.c2.x - path.c1.x, path.c2.y - path.c1.y) +
42
+ Math.hypot(path.end.x - path.c2.x, path.end.y - path.c2.y);
43
+ const steps = Math.max(24, Math.min(400, Math.round(approxLen / 5)));
44
+ drawFlowingDashes(g, sampleBezier(path, steps), color, width, opts.dashPhase ?? 0);
45
+ }
46
+ else {
47
+ g.moveTo(path.start.x, path.start.y)
48
+ .bezierCurveTo(path.c1.x, path.c1.y, path.c2.x, path.c2.y, path.end.x, path.end.y)
49
+ .stroke({ color, width });
50
+ }
51
+ if (opts.markerEnd === 'arrow') {
52
+ const [tip, l, r] = arrowHead(path, tokens.geometry.edge.arrowSize);
53
+ g.moveTo(tip.x, tip.y).lineTo(l.x, l.y).lineTo(r.x, r.y).closePath().fill({ color });
54
+ }
55
+ const rMid = tokens.geometry.edge.midpointRadius;
56
+ if (!opts.noMidpoint && rMid > 0) {
57
+ const mid = bezierMidpoint(path);
58
+ g.circle(mid.x, mid.y, rMid)
59
+ .fill({ color })
60
+ .stroke({ color: tokens.color.surface.canvas, width: 1, alignment: 0.5 });
61
+ }
62
+ return g;
63
+ }
64
+ // Polyline styles: step / smoothstep / linear. Same colour + width contract as bezier, just a
65
+ // different point list. Animated dashes reuse the same `drawFlowingDashes` (already polyline-
66
+ // based) — no resampling needed.
67
+ const pts = style === 'linear' ? computeLinearPolyline(from, to) :
68
+ style === 'step' ? computeStepPolyline(from, to) :
69
+ /* smoothstep */ computeSmoothStepPolyline(from, to);
70
+ if (opts.animated) {
71
+ g.moveTo(pts[0].x, pts[0].y);
72
+ for (let i = 1; i < pts.length; i++)
73
+ g.lineTo(pts[i].x, pts[i].y);
74
+ g.stroke({ color, width, alpha: 0.3 });
75
+ drawFlowingDashes(g, pts, color, width, opts.dashPhase ?? 0);
76
+ }
77
+ else {
78
+ g.moveTo(pts[0].x, pts[0].y);
79
+ for (let i = 1; i < pts.length; i++)
80
+ g.lineTo(pts[i].x, pts[i].y);
81
+ g.stroke({ color, width });
82
+ }
83
+ if (opts.markerEnd === 'arrow') {
84
+ const [tip, l, r] = polylineArrowHead(pts, tokens.geometry.edge.arrowSize);
85
+ g.moveTo(tip.x, tip.y).lineTo(l.x, l.y).lineTo(r.x, r.y).closePath().fill({ color });
86
+ }
87
+ const rMid = tokens.geometry.edge.midpointRadius;
88
+ if (!opts.noMidpoint && rMid > 0) {
89
+ const mid = polylineMidpoint(pts);
90
+ g.circle(mid.x, mid.y, rMid)
91
+ .fill({ color })
92
+ .stroke({ color: tokens.color.surface.canvas, width: 1, alignment: 0.5 });
93
+ }
94
+ return g;
95
+ }
96
+ export function renderEdge(from, to, tokens, opts = {}) {
97
+ return drawEdge(new Graphics(), from, to, tokens, opts);
98
+ }
99
+ //# sourceMappingURL=edge-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-renderer.js","sourceRoot":"","sources":["../src/edge-renderer.ts"],"names":[],"mappings":"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"}
package/dist/geom.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ import type { Node } from '@xenolithengine/graph-core';
2
+ export interface Vec2 {
3
+ x: number;
4
+ y: number;
5
+ }
6
+ export interface Rect {
7
+ x: number;
8
+ y: number;
9
+ width: number;
10
+ height: number;
11
+ }
12
+ export declare function rectFromPoints(a: Vec2, b: Vec2): Rect;
13
+ /** Strict AABB intersection — touching edges (zero overlap) do not count. */
14
+ export declare function rectIntersects(a: Rect, b: Rect): boolean;
15
+ export interface NodeBoundsTokens {
16
+ geometry: {
17
+ node: {
18
+ minWidth: number;
19
+ headerHeight: number;
20
+ headerPadding: number;
21
+ };
22
+ header: {
23
+ toPinsGap: number;
24
+ };
25
+ };
26
+ }
27
+ /**
28
+ * For each node, compute the set of lower-paint-order nodes whose AABB overlaps it.
29
+ *
30
+ * Used by backdrop-sampling themes (Liquid Glass) to do painter's-order RT compositing:
31
+ * a node with non-empty `lower` entry needs its own RT with those lower nodes baked in, so
32
+ * its glass shader refracts what's visually underneath it. Nodes with empty `lower` share the
33
+ * single base backdrop (cheaper path).
34
+ *
35
+ * Input `rects` are ordered bottom-to-top in paint order (index 0 = bottom of stack).
36
+ */
37
+ export declare function computeOverlapBackdropPlan(rects: ReadonlyArray<{
38
+ id: string;
39
+ x: number;
40
+ y: number;
41
+ width: number;
42
+ height: number;
43
+ }>): Map<string, string[]>;
44
+ /** World-space AABB of a node — used for marquee-selection hit-testing. */
45
+ export declare function nodeBounds(node: Node, tokens: NodeBoundsTokens): Rect;
46
+ //# sourceMappingURL=geom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geom.d.ts","sourceRoot":"","sources":["../src/geom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAA;AAEtD,MAAM,WAAW,IAAI;IACnB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED,MAAM,WAAW,IAAI;IACnB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,CASrD;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,OAAO,CAOxD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE;QACR,IAAI,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAC;YAAC,aAAa,EAAE,MAAM,CAAA;SAAE,CAAA;QACvE,MAAM,EAAE;YAAE,SAAS,EAAE,MAAM,CAAA;SAAE,CAAA;KAC9B,CAAA;CACF;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GACxF,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAYvB;AAED,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAUrE"}
package/dist/geom.js ADDED
@@ -0,0 +1,54 @@
1
+ export function rectFromPoints(a, b) {
2
+ const x = Math.min(a.x, b.x);
3
+ const y = Math.min(a.y, b.y);
4
+ return {
5
+ x,
6
+ y,
7
+ width: Math.abs(b.x - a.x),
8
+ height: Math.abs(b.y - a.y),
9
+ };
10
+ }
11
+ /** Strict AABB intersection — touching edges (zero overlap) do not count. */
12
+ export function rectIntersects(a, b) {
13
+ return (a.x < b.x + b.width &&
14
+ a.x + a.width > b.x &&
15
+ a.y < b.y + b.height &&
16
+ a.y + a.height > b.y);
17
+ }
18
+ /**
19
+ * For each node, compute the set of lower-paint-order nodes whose AABB overlaps it.
20
+ *
21
+ * Used by backdrop-sampling themes (Liquid Glass) to do painter's-order RT compositing:
22
+ * a node with non-empty `lower` entry needs its own RT with those lower nodes baked in, so
23
+ * its glass shader refracts what's visually underneath it. Nodes with empty `lower` share the
24
+ * single base backdrop (cheaper path).
25
+ *
26
+ * Input `rects` are ordered bottom-to-top in paint order (index 0 = bottom of stack).
27
+ */
28
+ export function computeOverlapBackdropPlan(rects) {
29
+ const plan = new Map();
30
+ for (let i = 1; i < rects.length; i++) {
31
+ const ri = rects[i];
32
+ const lower = [];
33
+ for (let j = 0; j < i; j++) {
34
+ const rj = rects[j];
35
+ if (rectIntersects(ri, rj))
36
+ lower.push(rj.id);
37
+ }
38
+ if (lower.length > 0)
39
+ plan.set(ri.id, lower);
40
+ }
41
+ return plan;
42
+ }
43
+ /** World-space AABB of a node — used for marquee-selection hit-testing. */
44
+ export function nodeBounds(node, tokens) {
45
+ const width = node.size?.x ?? tokens.geometry.node.minWidth;
46
+ const height = node.size?.y ?? tokens.geometry.node.headerHeight + tokens.geometry.header.toPinsGap;
47
+ return {
48
+ x: node.position.x,
49
+ y: node.position.y,
50
+ width,
51
+ height,
52
+ };
53
+ }
54
+ //# sourceMappingURL=geom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geom.js","sourceRoot":"","sources":["../src/geom.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,cAAc,CAAC,CAAO,EAAE,CAAO;IAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5B,OAAO;QACL,CAAC;QACD,CAAC;QACD,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KAC5B,CAAA;AACH,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,cAAc,CAAC,CAAO,EAAE,CAAO;IAC7C,OAAO,CACL,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK;QACnB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM;QACpB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CACrB,CAAA;AACH,CAAC;AASD;;;;;;;;;GASG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAyF;IAEzF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAoB,CAAA;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAE,CAAA;QACpB,MAAM,KAAK,GAAa,EAAE,CAAA;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAE,CAAA;YACpB,IAAI,cAAc,CAAC,EAAE,EAAE,EAAE,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;QAC/C,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,UAAU,CAAC,IAAU,EAAE,MAAwB;IAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAA;IAC3D,MAAM,MAAM,GACV,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAA;IACtF,OAAO;QACL,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClB,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClB,KAAK;QACL,MAAM;KACP,CAAA;AACH,CAAC"}
package/dist/grid.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { TilingSprite } from 'pixi.js';
2
+ import type { XenTokens } from '@xenolithengine/graph-theme-xen';
3
+ /**
4
+ * Create a `TilingSprite` filled with the Xen background dot pattern.
5
+ *
6
+ * The grid lives in world space — add it as a child of the same container the viewport applies
7
+ * to, so it scales / pans naturally with zoom and pan. We make the sprite very large (effectively
8
+ * infinite) and pre-offset it to a negative origin, so under any reasonable viewport position the
9
+ * visible area is always covered.
10
+ */
11
+ export declare function createGridSprite(tokens: XenTokens): TilingSprite;
12
+ //# sourceMappingURL=grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,YAAY,EAAE,MAAM,SAAS,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAA;AAEhE;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,YAAY,CAUhE"}
package/dist/grid.js ADDED
@@ -0,0 +1,35 @@
1
+ import { Texture, TilingSprite } from 'pixi.js';
2
+ /**
3
+ * Create a `TilingSprite` filled with the Xen background dot pattern.
4
+ *
5
+ * The grid lives in world space — add it as a child of the same container the viewport applies
6
+ * to, so it scales / pans naturally with zoom and pan. We make the sprite very large (effectively
7
+ * infinite) and pre-offset it to a negative origin, so under any reasonable viewport position the
8
+ * visible area is always covered.
9
+ */
10
+ export function createGridSprite(tokens) {
11
+ const tile = makeDotTile(tokens);
12
+ const sprite = new TilingSprite({
13
+ texture: tile,
14
+ width: 200_000,
15
+ height: 200_000,
16
+ });
17
+ sprite.position.set(-100_000, -100_000);
18
+ sprite.label = 'background-grid';
19
+ return sprite;
20
+ }
21
+ function makeDotTile(tokens) {
22
+ const { spacing, size, color } = tokens.background.grid;
23
+ const canvas = document.createElement('canvas');
24
+ canvas.width = spacing;
25
+ canvas.height = spacing;
26
+ const ctx = canvas.getContext('2d');
27
+ if (!ctx)
28
+ throw new Error('createGridSprite: 2d canvas context unavailable');
29
+ ctx.fillStyle = color;
30
+ ctx.beginPath();
31
+ ctx.arc(spacing / 2, spacing / 2, size, 0, Math.PI * 2);
32
+ ctx.fill();
33
+ return Texture.from(canvas);
34
+ }
35
+ //# sourceMappingURL=grid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid.js","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAG/C;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;IAChC,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC;QAC9B,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,OAAO;KAChB,CAAC,CAAA;IACF,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,CAAC,KAAK,GAAG,iBAAiB,CAAA;IAChC,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,WAAW,CAAC,MAAiB;IACpC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAA;IACvD,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;IAC/C,MAAM,CAAC,KAAK,GAAG,OAAO,CAAA;IACtB,MAAM,CAAC,MAAM,GAAG,OAAO,CAAA;IACvB,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;IAC5E,GAAG,CAAC,SAAS,GAAG,KAAK,CAAA;IACrB,GAAG,CAAC,SAAS,EAAE,CAAA;IACf,GAAG,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;IACvD,GAAG,CAAC,IAAI,EAAE,CAAA;IACV,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,14 @@
1
+ export declare const BUILTIN_ICONS: Record<string, string>;
2
+ /** Registry of header glyph icons by name. Seeded with the built-in Feather set; hosts/plugins add
3
+ * their own via `register(name, svgInner)`. The renderer resolves a node's glyph name to its svg. */
4
+ export declare class IconRegistry {
5
+ #private;
6
+ /** Register (or override) a named icon. `svgInner` is the inner markup of a 24×24 svg — use
7
+ * `<path>`/`<circle>`/`<rect>`/`<ellipse>` (avoid `<polyline>`/`<polygon>` with decimal coords). */
8
+ register(name: string, svgInner: string): void;
9
+ unregister(name: string): boolean;
10
+ has(name: string): boolean;
11
+ get(name: string): string | undefined;
12
+ names(): string[];
13
+ }
14
+ //# sourceMappingURL=icons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA2BhD,CAAA;AAED;sGACsG;AACtG,qBAAa,YAAY;;IAGvB;yGACqG;IACrG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAC9C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IACjC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAC1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IACrC,KAAK,IAAI,MAAM,EAAE;CAClB"}
package/dist/icons.js ADDED
@@ -0,0 +1,32 @@
1
+ // Built-in header glyph icons (Feather, MIT). Each value is the INNER markup of a 24×24 viewBox svg
2
+ // (the editor/renderer wraps it with stroke styling). IMPORTANT: PIXI's SVG parser splits
3
+ // polyline/polygon points on integer boundaries (it drops decimals), so every shape here is a
4
+ // <path>/<circle>/<rect>/<ellipse> — never <polyline>/<polygon>. Lines are written as paths too.
5
+ export const BUILTIN_ICONS = {
6
+ layers: '<path d="M12 2 2 7 12 12 22 7 12 2Z"/><path d="M2 17 12 22 22 17"/><path d="M2 12 12 17 22 12"/>',
7
+ box: '<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="M3.27 6.96 12 12.01 20.73 6.96"/><path d="M12 22.08V12"/>',
8
+ cpu: '<rect x="4" y="4" width="16" height="16" rx="2"/><rect x="9" y="9" width="6" height="6"/><path d="M9 1v3"/><path d="M15 1v3"/><path d="M9 20v3"/><path d="M15 20v3"/><path d="M20 9h3"/><path d="M20 14h3"/><path d="M1 9h3"/><path d="M1 14h3"/>',
9
+ database: '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 5v14c0 1.66-4 3-9 3s-9-1.34-9-3V5"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/>',
10
+ branch: '<path d="M6 3V15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/>',
11
+ code: '<path d="M16 18 22 12 16 6"/><path d="M8 6 2 12 8 18"/>',
12
+ play: '<path d="M5 3 19 12 5 21Z"/>',
13
+ zap: '<path d="M13 2 3 14 12 14 11 22 21 10 12 10 13 2Z"/>',
14
+ clock: '<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>',
15
+ flag: '<path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><path d="M4 22v-7"/>',
16
+ circle: '<circle cx="12" cy="12" r="9"/>',
17
+ square: '<rect x="4" y="4" width="16" height="16" rx="2"/>',
18
+ diamond: '<path d="M12 3 21 12 12 21 3 12Z"/>',
19
+ };
20
+ /** Registry of header glyph icons by name. Seeded with the built-in Feather set; hosts/plugins add
21
+ * their own via `register(name, svgInner)`. The renderer resolves a node's glyph name to its svg. */
22
+ export class IconRegistry {
23
+ #icons = new Map(Object.entries(BUILTIN_ICONS));
24
+ /** Register (or override) a named icon. `svgInner` is the inner markup of a 24×24 svg — use
25
+ * `<path>`/`<circle>`/`<rect>`/`<ellipse>` (avoid `<polyline>`/`<polygon>` with decimal coords). */
26
+ register(name, svgInner) { this.#icons.set(name, svgInner); }
27
+ unregister(name) { return this.#icons.delete(name); }
28
+ has(name) { return this.#icons.has(name); }
29
+ get(name) { return this.#icons.get(name); }
30
+ names() { return [...this.#icons.keys()]; }
31
+ }
32
+ //# sourceMappingURL=icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.js","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,0FAA0F;AAC1F,8FAA8F;AAC9F,iGAAiG;AACjG,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,MAAM,EACJ,kGAAkG;IACpG,GAAG,EACD,yMAAyM;IAC3M,GAAG,EACD,mPAAmP;IACrP,QAAQ,EACN,uIAAuI;IACzI,MAAM,EACJ,gHAAgH;IAClH,IAAI,EACF,yDAAyD;IAC3D,IAAI,EACF,8BAA8B;IAChC,GAAG,EACD,sDAAsD;IACxD,KAAK,EACH,wDAAwD;IAC1D,IAAI,EACF,2FAA2F;IAC7F,MAAM,EACJ,iCAAiC;IACnC,MAAM,EACJ,mDAAmD;IACrD,OAAO,EACL,qCAAqC;CACxC,CAAA;AAED;sGACsG;AACtG,MAAM,OAAO,YAAY;IACd,MAAM,GAAG,IAAI,GAAG,CAAiB,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAA;IAExE;yGACqG;IACrG,QAAQ,CAAC,IAAY,EAAE,QAAgB,IAAU,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA,CAAC,CAAC;IAClF,UAAU,CAAC,IAAY,IAAa,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,CAAC,CAAC;IACrE,GAAG,CAAC,IAAY,IAAa,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA,CAAC,CAAC;IAC3D,GAAG,CAAC,IAAY,IAAwB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA,CAAC,CAAC;IACtE,KAAK,KAAe,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA,CAAC,CAAC;CACrD"}
@@ -0,0 +1,34 @@
1
+ export declare const VERSION = "0.7.0-beta.0";
2
+ export { computeNodeLayout, measureNodeSize, findPinByKey, pinRowIndexFor, effectivePinRowHeight } from './layout.js';
3
+ export type { LayoutTokens, NodeLayout, PinLayout, Rect, NodeSizeTokens, TextMeasurer } from './layout.js';
4
+ export { createPixiTextMeasurer } from './text-measure.js';
5
+ export { computeEdgePath, sampleBezier, bezierMidpoint } from './bezier.js';
6
+ export type { EdgePath, EdgeTokens, Vec2 } from './bezier.js';
7
+ export { resolveCategoryAccent, resolvePinFill, resolvePinStroke, resolvePinShape, resolveEdgeColor, resolveCategoryGradient, hexToRgba, } from './style.js';
8
+ export type { CategoryGradient, CategoryColorSpec, GraphCategoryPalette } from './style.js';
9
+ export { renderNode, makeHeaderIcon, buildPinShape, readPinHandle, markPinInteractive, clearGlowTextureCache, clearGradientCache } from './node-renderer.js';
10
+ export { IconRegistry, BUILTIN_ICONS } from './icons.js';
11
+ export type { RenderNodeOptions, NodeView, NodeVisualState, PinHandle } from './node-renderer.js';
12
+ export { renderRerouteNode, rerouteSize, renderRerouteNodeBox, rerouteBoxSize, rerouteStateColor } from './reroute-renderer.js';
13
+ export { renderWidgets, computeWidgetRects, resolveWidgetStyle, widgetCssVars, themeCssVars, isDomWidgetController } from './widget-renderer.js';
14
+ export type { WidgetRect, WidgetHit, WidgetsView, WidgetLayoutTokens, ComputeWidgetRectsCtx, ResolvedWidgetStyle, CustomWidgetController, CanvasWidgetController, DomWidgetController, CustomWidgetContext } from './widget-renderer.js';
15
+ export { renderEdge, drawEdge } from './edge-renderer.js';
16
+ export type { RenderEdgeOptions, EdgePathStyle } from './edge-renderer.js';
17
+ export { screenToWorld, worldToScreen, zoomAt, clampZoom, snapToGrid, computeDragTarget, computeGroupSnappedDelta, fitView, } from './viewport-math.js';
18
+ export type { ViewportState, ZoomBounds, Vec2 as ViewportVec2, Rect as ViewportRect, FitViewOptions } from './viewport-math.js';
19
+ export { Viewport } from './viewport.js';
20
+ export type { ApplyTarget } from './viewport.js';
21
+ export { InteractionManager, wheelDeltaToZoomFactor } from './interaction.js';
22
+ export type { InteractionManagerOptions } from './interaction.js';
23
+ export { createGridSprite } from './grid.js';
24
+ export type { XenolithTheme, ThemeRenderContext, PaletteStyle } from './theme.js';
25
+ export { xenTheme } from './xen-theme.js';
26
+ export { rectFromPoints, rectIntersects, nodeBounds, computeOverlapBackdropPlan } from './geom.js';
27
+ export type { Rect as GeomRect, Vec2 as GeomVec2, NodeBoundsTokens } from './geom.js';
28
+ export { renderComment } from './comment-renderer.js';
29
+ export type { CommentView } from './comment-renderer.js';
30
+ export { renderMacroFrame } from './macro-frame.js';
31
+ export type { MacroFrameView, MacroFrameState, FrameRect } from './macro-frame.js';
32
+ export { shouldVirtualize, visibleWorldRect, reconcileVisibleNodes, useLOD, lodLevel, cellKey, cellsForRect } from './virtualize.js';
33
+ export type { Reconciliation, LODLevel, LODThresholds } from './virtualize.js';
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ export const VERSION = '0.7.0-beta.0';
2
+ export { computeNodeLayout, measureNodeSize, findPinByKey, pinRowIndexFor, effectivePinRowHeight } from './layout.js';
3
+ export { createPixiTextMeasurer } from './text-measure.js';
4
+ export { computeEdgePath, sampleBezier, bezierMidpoint } from './bezier.js';
5
+ export { resolveCategoryAccent, resolvePinFill, resolvePinStroke, resolvePinShape, resolveEdgeColor, resolveCategoryGradient, hexToRgba, } from './style.js';
6
+ export { renderNode, makeHeaderIcon, buildPinShape, readPinHandle, markPinInteractive, clearGlowTextureCache, clearGradientCache } from './node-renderer.js';
7
+ export { IconRegistry, BUILTIN_ICONS } from './icons.js';
8
+ export { renderRerouteNode, rerouteSize, renderRerouteNodeBox, rerouteBoxSize, rerouteStateColor } from './reroute-renderer.js';
9
+ export { renderWidgets, computeWidgetRects, resolveWidgetStyle, widgetCssVars, themeCssVars, isDomWidgetController } from './widget-renderer.js';
10
+ export { renderEdge, drawEdge } from './edge-renderer.js';
11
+ export { screenToWorld, worldToScreen, zoomAt, clampZoom, snapToGrid, computeDragTarget, computeGroupSnappedDelta, fitView, } from './viewport-math.js';
12
+ export { Viewport } from './viewport.js';
13
+ export { InteractionManager, wheelDeltaToZoomFactor } from './interaction.js';
14
+ export { createGridSprite } from './grid.js';
15
+ export { xenTheme } from './xen-theme.js';
16
+ export { rectFromPoints, rectIntersects, nodeBounds, computeOverlapBackdropPlan } from './geom.js';
17
+ export { renderComment } from './comment-renderer.js';
18
+ export { renderMacroFrame } from './macro-frame.js';
19
+ export { shouldVirtualize, visibleWorldRect, reconcileVisibleNodes, useLOD, lodLevel, cellKey, cellsForRect } from './virtualize.js';
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,cAAc,CAAA;AAErC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAGrH,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAE1D,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAG3E,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,uBAAuB,EACvB,SAAS,GACV,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAC5J,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAGxD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,oBAAoB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE/H,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,aAAa,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAGhJ,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAGzD,OAAO,EACL,aAAa,EACb,aAAa,EACb,MAAM,EACN,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,wBAAwB,EACxB,OAAO,GACR,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAGxC,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAG7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAG5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAA;AAGlG,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAGnD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,69 @@
1
+ import { type Unsubscribe } from '@xenolithengine/graph-core';
2
+ import type { Vec2 } from './viewport-math.js';
3
+ /**
4
+ * Convert a `WheelEvent.deltaY` to a multiplicative zoom factor. Positive delta (scroll down)
5
+ * zooms out (factor < 1), negative zooms in (factor > 1). Uses an exponential curve so the same
6
+ * notch always changes zoom by the same proportion, regardless of current zoom level.
7
+ *
8
+ * One default OS scroll click produces deltaY ≈ ±100; we map that to ~0.82× / 1.22× zoom step.
9
+ */
10
+ export declare function wheelDeltaToZoomFactor(deltaY: number): number;
11
+ /**
12
+ * Native trackpad pinch on macOS arrives as a wheel event with `ctrlKey` set and small deltaY
13
+ * (typically ±1–10). We want a gentler curve here than scroll wheel — pinch should feel buttery,
14
+ * not catapulty. Same exponential shape, larger divisor.
15
+ */
16
+ export declare function pinchDeltaToZoomFactor(deltaY: number): number;
17
+ type InteractionEvents = {
18
+ 'intent:zoom': {
19
+ focal: Vec2;
20
+ factor: number;
21
+ };
22
+ 'intent:pan': {
23
+ dx: number;
24
+ dy: number;
25
+ };
26
+ 'intent:gesture-begin': Record<string, never>;
27
+ 'intent:gesture-end': Record<string, never>;
28
+ 'intent:long-press': Vec2;
29
+ 'intent:long-press-start': {
30
+ x: number;
31
+ y: number;
32
+ ms: number;
33
+ };
34
+ 'intent:long-press-cancel': Record<string, never>;
35
+ };
36
+ export interface InteractionManagerOptions {
37
+ /** Mouse buttons that initiate a pan-drag. Defaults to middle (1) and right (2). */
38
+ panButtons?: readonly number[];
39
+ /** Milliseconds a stationary single touch must hold to fire `intent:long-press`. Default 500. */
40
+ longPressMs?: number;
41
+ /** Movement tolerance (client px) for the long-press timer — moving farther cancels it. Default 8. */
42
+ longPressSlop?: number;
43
+ }
44
+ export declare class InteractionManager {
45
+ #private;
46
+ constructor(target: HTMLElement, opts?: InteractionManagerOptions);
47
+ attach(): void;
48
+ detach(): void;
49
+ onZoom(handler: (e: InteractionEvents['intent:zoom']) => void): Unsubscribe;
50
+ onPan(handler: (e: InteractionEvents['intent:pan']) => void): Unsubscribe;
51
+ /**
52
+ * Fires the moment a second touch arrives. The editor uses this to cancel any in-flight
53
+ * single-pointer drag (node move, edge drag, marquee) so the gesture takes over cleanly
54
+ * instead of half a node being dragged while we also pan + zoom.
55
+ */
56
+ onGestureBegin(handler: () => void): Unsubscribe;
57
+ /** Fires when the active touch count drops back below 2. */
58
+ onGestureEnd(handler: () => void): Unsubscribe;
59
+ /** Fires after a stationary single touch holds for `longPressMs` — mobile equivalent of right-click. */
60
+ onLongPress(handler: (e: InteractionEvents['intent:long-press']) => void): Unsubscribe;
61
+ /** Fires the moment a single touch lands, with the local point and the duration the user must
62
+ * hold for the long-press to fire. Editors paint a growing ring at the point so the user gets
63
+ * feedback during the hold. Paired with onLongPressCancel; followed by onLongPress on success. */
64
+ onLongPressStart(handler: (e: InteractionEvents['intent:long-press-start']) => void): Unsubscribe;
65
+ /** Fires when the in-progress long-press is aborted (move past slop, lift early, second touch). */
66
+ onLongPressCancel(handler: () => void): Unsubscribe;
67
+ }
68
+ export {};
69
+ //# sourceMappingURL=interaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction.d.ts","sourceRoot":"","sources":["../src/interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC3E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAE9C;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,KAAK,iBAAiB,GAAG;IACvB,aAAa,EAAkB;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9D,YAAY,EAAmB;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACzD,sBAAsB,EAAS,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IACpD,oBAAoB,EAAW,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IACpD,mBAAmB,EAAY,IAAI,CAAA;IACnC,yBAAyB,EAAM;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACnE,0BAA0B,EAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;CACrD,CAAA;AAED,MAAM,WAAW,yBAAyB;IACxC,oFAAoF;IACpF,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sGAAsG;IACtG,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAID,qBAAa,kBAAkB;;gBAkBjB,MAAM,EAAE,WAAW,EAAE,IAAI,GAAE,yBAA8B;IAOrE,MAAM,IAAI,IAAI;IAkBd,MAAM,IAAI,IAAI;IASd,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,iBAAiB,CAAC,aAAa,CAAC,KAAK,IAAI,GAAG,WAAW;IAI3E,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,KAAK,IAAI,GAAG,WAAW;IAIzE;;;;OAIG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,WAAW;IAIhD,4DAA4D;IAC5D,YAAY,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,WAAW;IAI9C,wGAAwG;IACxG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,iBAAiB,CAAC,mBAAmB,CAAC,KAAK,IAAI,GAAG,WAAW;IAItF;;uGAEmG;IACnG,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,iBAAiB,CAAC,yBAAyB,CAAC,KAAK,IAAI,GAAG,WAAW;IAIjG,mGAAmG;IACnG,iBAAiB,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,WAAW;CAqIpD"}