@kanzo-tech/graph 0.13.0 → 0.14.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.
@@ -1,43 +1,43 @@
1
- import { Graph as nt } from "@cosmos.gl/graph";
2
- import { denseOf as it } from "../core/resident.js";
3
- import { tileOfDense as et } from "../core/tile-matrix.js";
4
- import { createComposer as ot } from "./compose.js";
5
- import { resolveLook as U } from "./graph-looks.js";
6
- import { forces as Z, appearance as _, paint as st } from "./graph-model.js";
7
- import { resolveSim as j } from "./graph-sim.js";
8
- import { whenReady as c, isReady as y } from "./when-ready.js";
9
- import { hasWebGL as rt, releaseContext as at } from "./webgl.js";
10
- const b = 420, k = 0.18, L = 0.35, H = 20, C = (u) => [u.x, u.y, u.x + u.w, u.y + u.h];
11
- function xt(u, i, l = {}) {
12
- const M = (t) => i.getOptions().onFailure(t);
13
- if (!rt())
1
+ import { Graph as v } from "@cosmos.gl/graph";
2
+ import { denseOf as ii } from "../core/resident.js";
3
+ import { tileOfDense as ni } from "../core/tile-matrix.js";
4
+ import { createComposer as ti } from "./compose.js";
5
+ import { resolveLook as _ } from "./graph-looks.js";
6
+ import { forces as R, appearance as U, paint as ei } from "./graph-model.js";
7
+ import { resolveSim as Z } from "./graph-sim.js";
8
+ import { hasWebGL as oi, releaseContext as ri } from "./webgl.js";
9
+ const S = 420, y = 0.18, O = 0.35, j = 20, C = (c) => [c.x, c.y, c.x + c.w, c.y + c.h];
10
+ function gi(c, e, o = {}) {
11
+ const M = (i) => e.getOptions().onFailure(i);
12
+ if (!oi())
14
13
  return M("This canvas renders on the GPU, and this browser offers no WebGL context."), null;
15
- let I = j(i.getOptions().sim), R = null, w = null, B = -1;
16
- const D = (t) => {
17
- const n = Math.round(t * H);
18
- n !== B && (B = n, i.reportProgress(n / H));
19
- }, Y = ot();
20
- let m = null, O = U(i.getOptions().look), E = i.getOptions().look;
21
- const a = { compose: !0, paint: !0, state: !0 };
22
- let x = 0, F = null, S = null, d = i.getSnapshot(), P = i.getOptions();
23
- const h = () => (m == null ? void 0 : m.resident) ?? lt, A = () => {
24
- const { height: t, width: n } = u.getBoundingClientRect();
25
- if (!y(e) || n === 0 || t === 0) return null;
26
- const [o, r] = e.screenToSpacePosition([0, 0]), [p, g] = e.screenToSpacePosition([n, t]), f = { xMin: Math.min(o, p), yMin: Math.min(r, g), xMax: Math.max(o, p), yMax: Math.max(r, g) };
27
- return { view: f, perPixel: (f.xMax - f.xMin) / n };
28
- }, z = () => {
29
- const t = A();
30
- t && i.setViewport(t.view);
14
+ let b = Z(e.getOptions().sim), g = e.getOptions().simulate ?? !1, T = null, k = null, F = -1;
15
+ const B = (i) => {
16
+ const n = Math.round(i * j);
17
+ n !== F && (F = n, e.reportProgress(n / j));
18
+ }, Y = ti();
19
+ let d = null, w = _(e.getOptions().look), E = e.getOptions().look;
20
+ const s = { compose: !0, paint: !0, state: !0, pinned: !0 };
21
+ let P = 0, I = !1, A = null, x = null, f = e.getSnapshot(), h = e.getOptions();
22
+ const m = () => (d == null ? void 0 : d.resident) ?? ai, z = () => {
23
+ const { height: i, width: n } = c.getBoundingClientRect();
24
+ if (!t.isReady || n === 0 || i === 0) return null;
25
+ const [a, l] = t.screenToSpacePosition([0, 0]), [u, p] = t.screenToSpacePosition([n, i]), r = { xMin: Math.min(a, u), yMin: Math.min(l, p), xMax: Math.max(a, u), yMax: Math.max(l, p) };
26
+ return { view: r, perPixel: (r.xMax - r.xMin) / n };
27
+ }, G = () => {
28
+ const i = z();
29
+ i && e.setViewport(i.view);
31
30
  };
32
- let e;
31
+ let t;
33
32
  try {
34
- e = new nt(u, {
33
+ t = new v(c, {
35
34
  // No `spaceSize` here: the box is the corpus's extent, set when the matrix arrives.
36
35
  // `rescalePositions: false` because the corpus's coordinates are the camera's — a rescale
37
36
  // between them means the cull and the viewport describe different places.
38
37
  rescalePositions: !1,
39
- enableSimulation: i.getOptions().simulate ?? !1,
40
- ...Z(I),
38
+ transitionDuration: 0,
39
+ enableSimulation: g,
40
+ ...R(b),
41
41
  // Frames to convergence: alpha reaches its floor after exactly this many rendered frames.
42
42
  simulationDecay: 400,
43
43
  randomSeed: "kanzo-discovery",
@@ -45,191 +45,188 @@ function xt(u, i, l = {}) {
45
45
  enableDrag: !0,
46
46
  hoveredPointCursor: "pointer",
47
47
  attribution: "",
48
- onSimulationStart: () => i.report("running"),
48
+ onSimulationStart: () => e.report("running"),
49
49
  onSimulationEnd: () => {
50
- var t;
51
- i.report("settled"), D(1), (t = l.onFrame) == null || t.call(l);
50
+ var i;
51
+ e.report("settled"), B(1), (i = o.onFrame) == null || i.call(o);
52
52
  },
53
- onSimulationPause: () => i.report("paused"),
54
- onSimulationUnpause: () => i.report("running"),
55
- onSimulationTick: () => {
56
- var t;
57
- D(e.progress), (t = l.onFrame) == null || t.call(l);
53
+ onSimulationPause: () => e.report("paused"),
54
+ onSimulationUnpause: () => e.report("running"),
55
+ onSimulationTick: (i, n, a) => {
56
+ var l, u;
57
+ B(t.progress), n !== void 0 && a && ((l = o.onHover) == null || l.call(o, a)), (u = o.onFrame) == null || u.call(o);
58
58
  },
59
59
  onZoom: () => {
60
- var t;
61
- z(), (t = l.onFrame) == null || t.call(l);
60
+ var i;
61
+ G(), (i = o.onFrame) == null || i.call(o);
62
62
  },
63
- onPointMouseOver: (t) => {
64
- R = t, i.hover(h().at(t) ?? null);
63
+ onPointMouseOver: (i, n) => {
64
+ var a;
65
+ T = i, (a = o.onHover) == null || a.call(o, n), e.hover(m().at(i) ?? null);
65
66
  },
66
67
  onPointMouseOut: () => {
67
- R = null, i.hover(null);
68
+ var i;
69
+ T = null, (i = o.onHover) == null || i.call(o, null), e.hover(null);
68
70
  },
69
71
  onDragStart: () => {
70
- w = R;
72
+ k = T;
73
+ },
74
+ onDrag: (i) => {
75
+ var n, a;
76
+ (n = o.onHover) == null || n.call(o, t.screenToSpacePosition([i.x, i.y])), (a = o.onFrame) == null || a.call(o);
71
77
  },
72
78
  onDragEnd: () => {
73
- const t = w === null ? void 0 : h().at(w);
74
- w = null, t !== void 0 && i.pin([...i.getSnapshot().pinned, t]);
79
+ const i = k === null ? void 0 : m().at(k);
80
+ k = null, i !== void 0 && e.pin([...e.getSnapshot().pinned, i]);
75
81
  },
76
- onPointClick: (t) => {
77
- const n = h().at(t);
78
- n !== void 0 && V(n, t);
82
+ onPointClick: (i) => {
83
+ const n = m().at(i);
84
+ n !== void 0 && H(n, i);
79
85
  },
80
86
  onBackgroundClick: () => W()
81
87
  });
82
- } catch (t) {
83
- return M(`The renderer failed to start. (${String(t)})`), null;
88
+ } catch (i) {
89
+ return M(`The renderer failed to start. (${String(i)})`), null;
84
90
  }
85
- const T = () => {
86
- x || (x = requestAnimationFrame(() => {
87
- x = 0, c(e, $);
91
+ const D = () => {
92
+ P || (P = requestAnimationFrame(() => {
93
+ P = 0, $();
88
94
  }));
89
95
  };
90
- function $(t) {
91
- var p, g, f;
92
- const n = i.getSnapshot(), o = i.getOptions();
93
- let r = !1;
94
- if (a.compose && n.matrix) {
95
- a.compose = !1;
96
- const s = Y({
97
- matrix: n.matrix,
98
- typeIndex: n.typeIndex,
99
- binding: n.binding,
100
- modeColumn: n.modeColumn,
101
- domain: n.domain,
102
- visible: n.visible,
103
- cached: n.cached,
104
- perPixel: ((p = A()) == null ? void 0 : p.perPixel) ?? 0
96
+ function $() {
97
+ var l, u, p;
98
+ const i = e.getSnapshot(), n = e.getOptions();
99
+ let a = !1;
100
+ if (s.compose && i.matrix) {
101
+ s.compose = !1;
102
+ const r = Y({
103
+ matrix: i.matrix,
104
+ typeIndex: i.typeIndex,
105
+ binding: i.binding,
106
+ modeColumn: i.modeColumn,
107
+ domain: i.domain,
108
+ visible: i.visible,
109
+ cached: i.cached,
110
+ perPixel: ((l = z()) == null ? void 0 : l.perPixel) ?? 0
105
111
  });
106
- if (s && (m = s, t.setPointPositions(s.positions, !0), t.setLinks(s.links), a.paint = !0, a.state = !0, r = !0, (g = l.onComposed) == null || g.call(l, s), S !== null && s.resident.indexOf(S) !== void 0)) {
107
- const tt = S;
108
- S = null, queueMicrotask(() => q(tt));
112
+ if (r && (d = r, t.setPointPositions(r.positions, !0), t.setLinks(r.links), s.paint = !0, s.state = !0, s.pinned = !0, a = !0, (u = o.onComposed) == null || u.call(o, r), x !== null && r.resident.indexOf(x) !== void 0)) {
113
+ const X = x;
114
+ x = null, queueMicrotask(() => q(X));
109
115
  }
110
- const v = s && { marks: s.marks, represented: s.represented, domain: s.domain, tally: s.tally };
111
- i.reportDrawn(n.visible, v);
116
+ const Q = r && { marks: r.marks, represented: r.represented, domain: r.domain, tally: r.tally };
117
+ e.reportDrawn(i.visible, Q);
112
118
  }
113
- if (a.paint && m) {
114
- a.paint = !1;
115
- const s = st(m, O, u, o);
116
- t.setPointColors(s.colors), t.setPointSizes(s.sizes), t.setPointShapes(s.shapes), t.setLinkColors(s.linkColors), t.setLinkWidths(s.linkWidths), t.setConfigPartial(_(O, u)), r = !0;
119
+ if (s.paint && d) {
120
+ s.paint = !1;
121
+ const r = ei(d, w, c, n);
122
+ t.setPointColors(r.colors), t.setPointSizes(r.sizes), t.setPointShapes(r.shapes), t.setLinkColors(r.linkColors), t.setLinkWidths(r.linkWidths), t.setConfigPartial(U(w, c)), a = !0;
117
123
  }
118
- if (a.state && m) {
119
- a.state = !1;
120
- const s = m.resident;
124
+ if (s.state && d) {
125
+ s.state = !1;
126
+ const r = d.resident;
121
127
  t.setConfigPartial({
122
- highlightedPointIndices: n.selection ? s.indicesOf(n.selection.vertices) : void 0,
123
- focusedPointIndex: n.focus === null ? void 0 : s.indexOf(n.focus)
128
+ highlightedPointIndices: i.selection ? r.indicesOf(i.selection.vertices) : void 0,
129
+ focusedPointIndex: i.focus === null ? void 0 : r.indexOf(i.focus)
124
130
  });
125
- const v = s.indicesOf(n.pinned);
126
- t.setPinnedPoints(v.length > 0 ? v : null), r = !0;
127
131
  }
128
- r && t.render(), (f = l.onFrame) == null || f.call(l);
132
+ if (s.pinned && d) {
133
+ s.pinned = !1;
134
+ const r = d.resident.indicesOf(i.pinned);
135
+ t.setPinnedPoints(r.length > 0 ? r : null);
136
+ }
137
+ a && t.render(), (p = o.onFrame) == null || p.call(o);
129
138
  }
130
- const G = (t) => {
131
- var o;
132
- const n = (o = t.matrix) == null ? void 0 : o.extent;
133
- !n || t.matrix === F || (F = t.matrix, c(e, (r) => {
134
- r.setConfigPartial({ spaceSize: Math.max(n.w, n.h) }), r.fitViewByPointPositions(C(n), 0, k), z();
139
+ const V = (i) => {
140
+ var a;
141
+ const n = (a = i.matrix) == null ? void 0 : a.extent;
142
+ !n || i.matrix === A || (A = i.matrix, t.setConfigPartial({ spaceSize: Math.max(n.w, n.h) }), t.fitViewByPointPositions(C(n), 0, y), t.ready.then(() => {
143
+ I || G();
135
144
  }));
136
- }, J = i.subscribe(() => {
137
- const t = i.getSnapshot(), n = i.getOptions();
138
- G(t), (t.visible !== d.visible || t.binding !== d.binding || t.domain !== d.domain) && (a.compose = !0), n.look !== E && (E = n.look, O = U(n.look), a.paint = !0), (n.fill !== P.fill || n.symbol !== P.symbol || n.stroke !== P.stroke) && (a.paint = !0), (t.selection !== d.selection || t.focus !== d.focus || t.pinned !== d.pinned) && (a.state = !0), (n.sim !== P.sim || n.simulate !== P.simulate) && K(n.sim, n.simulate), d = t, P = n, (a.compose || a.paint || a.state) && T();
145
+ }, J = e.subscribe(() => {
146
+ const i = e.getSnapshot(), n = e.getOptions();
147
+ V(i), (i.visible !== f.visible || i.binding !== f.binding || i.domain !== f.domain) && (s.compose = !0), n.look !== E && (E = n.look, w = _(n.look), s.paint = !0), (n.fill !== h.fill || n.symbol !== h.symbol || n.stroke !== h.stroke) && (s.paint = !0), (i.selection !== f.selection || i.focus !== f.focus) && (s.state = !0), i.pinned !== f.pinned && (s.pinned = !0), n.sim !== h.sim && K(n.sim), (n.simulate ?? !1) !== (h.simulate ?? !1) && (n.simulate ? L(O) : t.pause()), f = i, h = n, (s.compose || s.paint || s.state || s.pinned) && D();
139
148
  });
140
- function K(t, n = !1) {
141
- const o = j(t), r = Object.keys(o).some((p) => o[p] !== I[p]);
142
- I = o, c(e, (p) => {
143
- p.setConfigPartial({ enableSimulation: n, ...Z(o) }), n && r && p.start(L);
144
- });
149
+ function K(i) {
150
+ const n = Z(i), a = Object.keys(n).some((l) => n[l] !== b[l]);
151
+ b = n, g && (t.setConfigPartial(R(n)), a && e.getSnapshot().motion !== "paused" && t.start(O));
152
+ }
153
+ function L(i) {
154
+ g || (g = !0, t.setConfigPartial({ enableSimulation: !0, ...R(b) })), t.start(i);
145
155
  }
146
- function V(t, n) {
147
- const o = h(), r = y(e) ? o.verticesAt(e.getNeighboringPointIndices(n)) : [];
148
- i.select([t, ...r], "node", "Node"), i.focus(t);
156
+ function H(i, n) {
157
+ const l = m().verticesAt(t.getNeighboringPointIndices(n));
158
+ e.select([i, ...l], "node", "Node"), e.focus(i);
149
159
  }
150
160
  function W() {
151
- i.select(null), i.focus(null);
161
+ e.select(null), e.focus(null);
152
162
  }
153
- function q(t) {
154
- var g, f;
155
- const n = h().indexOf(t);
163
+ function q(i) {
164
+ var p, r;
165
+ const n = m().indexOf(i);
156
166
  if (n !== void 0) {
157
- V(t, n), c(e, (s) => s.zoomToPointByIndex(n, 500, 5, !0));
167
+ H(i, n), t.zoomToPointByIndex(n, 500, 5, !0);
158
168
  return;
159
169
  }
160
- const o = i.getSnapshot().matrix, r = o ? et(o, it(t)) : null, p = r && ((f = (g = o == null ? void 0 : o.tileMatrices[r.z]) == null ? void 0 : g.tiles[r.tile]) == null ? void 0 : f.bbox);
161
- p && (S = t, c(e, (s) => s.fitViewByPointPositions(C(p), b, k)));
170
+ const a = e.getSnapshot().matrix, l = a ? ni(a, ii(i)) : null, u = l && ((r = (p = a == null ? void 0 : a.tileMatrices[l.z]) == null ? void 0 : p.tiles[l.tile]) == null ? void 0 : r.bbox);
171
+ u && (x = i, t.fitViewByPointPositions(C(u), S, y));
162
172
  }
163
- y(e);
164
- const Q = c(e, (t) => {
165
- t.setConfigPartial(_(O, u)), t.render();
166
- }), N = (t) => {
167
- t.preventDefault(), M("The graph's WebGL context was lost. A browser keeps a limited number of them and drops the oldest; reload the page to get one back.");
168
- }, X = c(e, () => {
169
- var t;
170
- (t = u.querySelector("canvas")) == null || t.addEventListener("webglcontextlost", N);
171
- });
172
- return i.report(i.getOptions().simulate && e.isSimulationRunning ? "running" : "settled"), G(d), T(), {
173
- graph: e,
174
- resident: h,
175
- composition: () => m,
173
+ t.setConfigPartial(U(w, c)), t.render();
174
+ const N = (i) => {
175
+ i.preventDefault(), M("The graph's WebGL context was lost. A browser keeps a limited number of them and drops the oldest; reload the page to get one back.");
176
+ };
177
+ return t.ready.then(() => {
178
+ var i;
179
+ I || (i = c.querySelector("canvas")) == null || i.addEventListener("webglcontextlost", N);
180
+ }), e.report(g && t.isSimulationRunning ? "running" : "settled"), V(f), D(), {
181
+ graph: t,
182
+ resident: m,
183
+ composition: () => d,
176
184
  repaint() {
177
- a.paint = !0, T();
185
+ s.paint = !0, D();
178
186
  },
179
- hit(t) {
180
- if (!y(e)) return [];
181
- const n = "rect" in t ? e.findPointsInRect(t.rect) : e.findPointsInPolygon(t.polygon);
187
+ hit(i) {
188
+ const n = "rect" in i ? t.findPointsInRect(i.rect) : t.findPointsInPolygon(i.polygon);
182
189
  return Array.from(n);
183
190
  },
184
- zoomBy(t) {
185
- c(e, (n) => n.setZoomLevel(n.getZoomLevel() * t, 220));
191
+ zoomBy(i) {
192
+ t.setZoomLevel(t.getZoomLevel() * i, 220);
186
193
  },
187
194
  fit() {
188
195
  var n;
189
- const t = (n = i.getSnapshot().matrix) == null ? void 0 : n.extent;
190
- c(
191
- e,
192
- (o) => t ? o.fitViewByPointPositions(C(t), b, k) : o.fitView(b, k)
193
- );
196
+ const i = (n = e.getSnapshot().matrix) == null ? void 0 : n.extent;
197
+ i ? t.fitViewByPointPositions(C(i), S, y) : t.fitView(S, y);
194
198
  },
195
- pause: () => c(e, (t) => t.pause()),
199
+ pause: () => t.pause(),
196
200
  resume() {
197
- const t = i.getSnapshot().motion === "settled";
198
- c(e, (n) => t ? n.start(L) : n.unpause());
201
+ e.getSnapshot().motion === "settled" || !g ? L(O) : t.unpause();
199
202
  },
200
203
  restart() {
201
- i.pin([]), c(e, (t) => t.start(1));
204
+ e.pin([]), L(1);
202
205
  },
203
206
  unpin() {
204
- i.getSnapshot().pinned.length !== 0 && (i.pin([]), c(e, (t) => t.start(L)));
207
+ e.getSnapshot().pinned.length !== 0 && (e.pin([]), e.getSnapshot().motion === "running" && t.start(O));
205
208
  },
206
209
  reveal: q,
207
- frameBox(t, { duration: n = b, padding: o = k } = {}) {
208
- c(e, (r) => r.fitViewByPointPositions(C(t), n, o));
210
+ frameBox(i, { duration: n = S, padding: a = y } = {}) {
211
+ t.fitViewByPointPositions(C(i), n, a);
209
212
  },
210
213
  frameSelection() {
211
214
  var n;
212
- const t = h().indicesOf(((n = i.getSnapshot().selection) == null ? void 0 : n.vertices) ?? []);
213
- t.length > 0 && c(e, (o) => o.fitViewByPointIndices(t, b, 0.25));
215
+ const i = m().indicesOf(((n = e.getSnapshot().selection) == null ? void 0 : n.vertices) ?? []);
216
+ i.length > 0 && t.fitViewByPointIndices(i, S, 0.25);
214
217
  },
215
218
  clear: W,
216
219
  destroy() {
217
- J(), x && cancelAnimationFrame(x), Q(), X();
218
- const t = u.querySelector("canvas");
219
- t == null || t.removeEventListener("webglcontextlost", N), e.destroy(), at(t);
220
+ J(), P && cancelAnimationFrame(P), I = !0;
221
+ const i = c.querySelector("canvas");
222
+ i == null || i.removeEventListener("webglcontextlost", N), t.destroy(), ri(i);
220
223
  }
221
224
  };
222
225
  }
223
- const lt = {
224
- size: 0,
225
- indexOf: () => {
226
- },
227
- at: () => {
228
- },
229
- indicesOf: () => [],
230
- verticesAt: () => []
231
- };
226
+ const ai = { size: 0, indexOf: () => {
227
+ }, at: () => {
228
+ }, indicesOf: () => [], verticesAt: () => [] };
232
229
  export {
233
- xt as createRenderer
230
+ gi as createRenderer
234
231
  };
235
232
  //# sourceMappingURL=renderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.js","sources":["../../src/render/renderer.ts"],"sourcesContent":["import { Graph } from \"@cosmos.gl/graph\";\nimport type { Box } from \"@fossil-lang/corpus\";\nimport type { Resident, VertexId } from \"../core/resident\";\nimport { denseOf } from \"../core/resident\";\nimport type { GraphSnapshot, GraphStore } from \"../core/store\";\nimport { tileOfDense, type Viewport } from \"../core/tile-matrix\";\nimport type { GraphCommands } from \"../core/types\";\nimport { createComposer, type Composition } from \"./compose\";\nimport { resolveLook, type Look } from \"./graph-looks\";\nimport { appearance, forces, paint } from \"./graph-model\";\nimport { resolveSim, type Sim } from \"./graph-sim\";\nimport { isReady, whenReady } from \"./when-ready\";\nimport { hasWebGL, releaseContext } from \"./webgl\";\n\nexport interface RendererEvents {\n /** After every frame and every camera move — where the overlays repaint. */\n onFrame?: () => void;\n /** A new composition was uploaded. */\n onComposed?: (composition: Composition) => void;\n}\n\nexport interface Renderer extends GraphCommands {\n readonly graph: Graph;\n resident(): Resident;\n composition(): Composition | null;\n /** The theme moved under the canvas: colours are resolved again, nothing else. */\n repaint(): void;\n /** The drawn points inside a screen rectangle or polygon, once the device is ready. */\n hit(shape: { rect: [[number, number], [number, number]] } | { polygon: [number, number][] }): number[];\n destroy(): void;\n}\n\nconst FIT_DURATION = 420;\nconst FIT_PADDING = 0.18;\nconst REHEAT = 0.35;\n/** Twentieths: a settle costs twenty reports rather than one per frame. */\nconst PROGRESS_STEPS = 20;\n\nconst corners = (box: Box) => [box.x, box.y, box.x + box.w, box.y + box.h];\n\n/**\n * **cosmos.gl's lifetime, and the frame that renders once.** Built once per element; it subscribes to\n * the store and discharges what changed in one `requestAnimationFrame`:\n *\n * - a change of visible tiles recomposes, and dirties positions, links and the per-point arrays;\n * - a look or a theme change dirties colours, sizes and shapes and nothing else;\n * - a selection, a focus or a pin sets two config fields and uploads nothing;\n * - a snapshot that changed none of those schedules nothing.\n *\n * Every callback reads the store's latest options, so a host's inline `onFailure` never rebuilds it.\n */\nexport function createRenderer(host: HTMLDivElement, store: GraphStore, events: RendererEvents = {}): Renderer | null {\n const fail = (message: string) => store.getOptions().onFailure(message);\n if (!hasWebGL()) {\n fail(\"This canvas renders on the GPU, and this browser offers no WebGL context.\");\n return null;\n }\n\n let sim: Sim = resolveSim(store.getOptions().sim);\n let hovering: number | null = null;\n let dragging: number | null = null;\n let reported = -1;\n const progress = (value: number) => {\n const bucket = Math.round(value * PROGRESS_STEPS);\n if (bucket === reported) return;\n reported = bucket;\n store.reportProgress(bucket / PROGRESS_STEPS);\n };\n\n const compose = createComposer();\n let composition: Composition | null = null;\n let look: Look = resolveLook(store.getOptions().look);\n let lookPatch = store.getOptions().look;\n const dirty = { compose: true, paint: true, state: true };\n let frame = 0;\n let framed: GraphSnapshot[\"matrix\"] = null;\n let pendingReveal: VertexId | null = null;\n let last = store.getSnapshot();\n let lastOptions = store.getOptions();\n\n const resident = () => composition?.resident ?? EMPTY;\n\n const viewport = (): { view: Viewport; perPixel: number } | null => {\n const { height, width } = host.getBoundingClientRect();\n if (!isReady(graph) || width === 0 || height === 0) return null;\n const [ax, ay] = graph.screenToSpacePosition([0, 0]);\n const [bx, by] = graph.screenToSpacePosition([width, height]);\n const view = { xMin: Math.min(ax, bx), yMin: Math.min(ay, by), xMax: Math.max(ax, bx), yMax: Math.max(ay, by) };\n return { view, perPixel: (view.xMax - view.xMin) / width };\n };\n const observe = () => {\n const camera = viewport();\n if (camera) store.setViewport(camera.view);\n };\n\n let graph: Graph;\n try {\n graph = new Graph(host, {\n // No `spaceSize` here: the box is the corpus's extent, set when the matrix arrives.\n // `rescalePositions: false` because the corpus's coordinates are the camera's — a rescale\n // between them means the cull and the viewport describe different places.\n rescalePositions: false,\n enableSimulation: store.getOptions().simulate ?? false,\n ...forces(sim),\n // Frames to convergence: alpha reaches its floor after exactly this many rendered frames.\n simulationDecay: 400,\n randomSeed: \"kanzo-discovery\",\n pixelRatio: window.devicePixelRatio || 1,\n enableDrag: true,\n hoveredPointCursor: \"pointer\",\n attribution: \"\",\n onSimulationStart: () => store.report(\"running\"),\n onSimulationEnd: () => {\n store.report(\"settled\");\n progress(1);\n events.onFrame?.();\n },\n onSimulationPause: () => store.report(\"paused\"),\n onSimulationUnpause: () => store.report(\"running\"),\n onSimulationTick: () => {\n progress(graph.progress);\n events.onFrame?.();\n },\n onZoom: () => {\n observe();\n events.onFrame?.();\n },\n onPointMouseOver: (index) => {\n hovering = index;\n store.hover(resident().at(index) ?? null);\n },\n onPointMouseOut: () => {\n hovering = null;\n store.hover(null);\n },\n onDragStart: () => {\n dragging = hovering;\n },\n onDragEnd: () => {\n const vertex = dragging === null ? undefined : resident().at(dragging);\n dragging = null;\n if (vertex !== undefined) store.pin([...store.getSnapshot().pinned, vertex]);\n },\n onPointClick: (index) => {\n const vertex = resident().at(index);\n if (vertex !== undefined) focusOn(vertex, index);\n },\n onBackgroundClick: () => clear(),\n });\n } catch (error) {\n fail(`The renderer failed to start. (${String(error)})`);\n return null;\n }\n\n const schedule = () => {\n if (frame) return;\n frame = requestAnimationFrame(() => {\n frame = 0;\n whenReady(graph, draw);\n });\n };\n\n function draw(ready: Graph): void {\n const snapshot = store.getSnapshot();\n const options = store.getOptions();\n let changed = false;\n if (dirty.compose && snapshot.matrix) {\n dirty.compose = false;\n const next = compose({\n matrix: snapshot.matrix,\n typeIndex: snapshot.typeIndex,\n binding: snapshot.binding,\n modeColumn: snapshot.modeColumn,\n domain: snapshot.domain,\n visible: snapshot.visible,\n cached: snapshot.cached,\n perPixel: viewport()?.perPixel ?? 0,\n });\n if (next) {\n composition = next;\n ready.setPointPositions(next.positions, true);\n ready.setLinks(next.links);\n dirty.paint = true;\n dirty.state = true;\n changed = true;\n events.onComposed?.(next);\n if (pendingReveal !== null && next.resident.indexOf(pendingReveal) !== undefined) {\n const vertex = pendingReveal;\n pendingReveal = null;\n queueMicrotask(() => reveal(vertex));\n }\n }\n const drawn = next && { marks: next.marks, represented: next.represented, domain: next.domain, tally: next.tally };\n store.reportDrawn(snapshot.visible, drawn);\n }\n if (dirty.paint && composition) {\n dirty.paint = false;\n const buffers = paint(composition, look, host, options);\n ready.setPointColors(buffers.colors);\n ready.setPointSizes(buffers.sizes);\n ready.setPointShapes(buffers.shapes);\n ready.setLinkColors(buffers.linkColors);\n ready.setLinkWidths(buffers.linkWidths);\n ready.setConfigPartial(appearance(look, host));\n changed = true;\n }\n if (dirty.state && composition) {\n dirty.state = false;\n const drawn = composition.resident;\n ready.setConfigPartial({\n highlightedPointIndices: snapshot.selection ? drawn.indicesOf(snapshot.selection.vertices) : undefined,\n focusedPointIndex: snapshot.focus === null ? undefined : drawn.indexOf(snapshot.focus),\n });\n const pinned = drawn.indicesOf(snapshot.pinned);\n ready.setPinnedPoints(pinned.length > 0 ? pinned : null);\n changed = true;\n }\n if (changed) ready.render();\n events.onFrame?.();\n }\n\n const frameExtent = (snapshot: GraphSnapshot) => {\n const extent = snapshot.matrix?.extent;\n if (!extent || snapshot.matrix === framed) return;\n framed = snapshot.matrix;\n whenReady(graph, (ready) => {\n ready.setConfigPartial({ spaceSize: Math.max(extent.w, extent.h) });\n ready.fitViewByPointPositions(corners(extent), 0, FIT_PADDING);\n observe();\n });\n };\n\n const unsubscribe = store.subscribe(() => {\n const snapshot = store.getSnapshot();\n const options = store.getOptions();\n frameExtent(snapshot);\n if (snapshot.visible !== last.visible || snapshot.binding !== last.binding || snapshot.domain !== last.domain) {\n dirty.compose = true;\n }\n if (options.look !== lookPatch) {\n lookPatch = options.look;\n look = resolveLook(options.look);\n dirty.paint = true;\n }\n if (options.fill !== lastOptions.fill || options.symbol !== lastOptions.symbol || options.stroke !== lastOptions.stroke) {\n dirty.paint = true;\n }\n if (snapshot.selection !== last.selection || snapshot.focus !== last.focus || snapshot.pinned !== last.pinned) {\n dirty.state = true;\n }\n if (options.sim !== lastOptions.sim || options.simulate !== lastOptions.simulate) applyForces(options.sim, options.simulate);\n last = snapshot;\n lastOptions = options;\n if (dirty.compose || dirty.paint || dirty.state) schedule();\n });\n\n function applyForces(patch: Partial<Sim> | undefined, simulate = false): void {\n const next = resolveSim(patch);\n const moved = Object.keys(next).some((key) => next[key as keyof Sim] !== sim[key as keyof Sim]);\n sim = next;\n whenReady(graph, (ready) => {\n ready.setConfigPartial({ enableSimulation: simulate, ...forces(next) });\n if (simulate && moved) ready.start(REHEAT);\n });\n }\n\n function focusOn(vertex: VertexId, index: number): void {\n const drawn = resident();\n const around = isReady(graph) ? drawn.verticesAt(graph.getNeighboringPointIndices(index)) : [];\n store.select([vertex, ...around], \"node\", \"Node\");\n store.focus(vertex);\n }\n\n function clear(): void {\n store.select(null);\n store.focus(null);\n }\n\n /** Centre and select one vertex; one that is not drawn is framed by its tile first, then revealed. */\n function reveal(vertex: VertexId): void {\n const index = resident().indexOf(vertex);\n if (index !== undefined) {\n focusOn(vertex, index);\n whenReady(graph, (ready) => ready.zoomToPointByIndex(index, 500, 5, true));\n return;\n }\n const matrix = store.getSnapshot().matrix;\n const address = matrix ? tileOfDense(matrix, denseOf(vertex)) : null;\n const box = address && matrix?.tileMatrices[address.z]?.tiles[address.tile]?.bbox;\n if (!box) return;\n pendingReveal = vertex;\n whenReady(graph, (ready) => ready.fitViewByPointPositions(corners(box), FIT_DURATION, FIT_PADDING));\n }\n\n // Primed first, so every `whenReady` below runs with `isReady` already answering true.\n isReady(graph);\n const painted = whenReady(graph, (ready) => {\n ready.setConfigPartial(appearance(look, host));\n ready.render();\n });\n const onLost = (event: Event) => {\n event.preventDefault();\n fail(\"The graph's WebGL context was lost. A browser keeps a limited number of them and drops the oldest; reload the page to get one back.\");\n };\n // Inside `whenReady`: cosmos.gl makes its canvas with the device, which is asynchronous.\n const listening = whenReady(graph, () => {\n host.querySelector(\"canvas\")?.addEventListener(\"webglcontextlost\", onLost);\n });\n store.report(store.getOptions().simulate && graph.isSimulationRunning ? \"running\" : \"settled\");\n frameExtent(last);\n schedule();\n\n return {\n graph,\n resident,\n composition: () => composition,\n repaint() {\n dirty.paint = true;\n schedule();\n },\n hit(shape) {\n if (!isReady(graph)) return [];\n const found = \"rect\" in shape ? graph.findPointsInRect(shape.rect) : graph.findPointsInPolygon(shape.polygon);\n return Array.from(found);\n },\n zoomBy(factor) {\n whenReady(graph, (ready) => ready.setZoomLevel(ready.getZoomLevel() * factor, 220));\n },\n fit() {\n const extent = store.getSnapshot().matrix?.extent;\n whenReady(graph, (ready) =>\n extent ? ready.fitViewByPointPositions(corners(extent), FIT_DURATION, FIT_PADDING) : ready.fitView(FIT_DURATION, FIT_PADDING),\n );\n },\n pause: () => whenReady(graph, (ready) => ready.pause()),\n resume() {\n const settled = store.getSnapshot().motion === \"settled\";\n whenReady(graph, (ready) => (settled ? ready.start(REHEAT) : ready.unpause()));\n },\n restart() {\n store.pin([]);\n whenReady(graph, (ready) => ready.start(1));\n },\n unpin() {\n if (store.getSnapshot().pinned.length === 0) return;\n store.pin([]);\n whenReady(graph, (ready) => ready.start(REHEAT));\n },\n reveal,\n frameBox(box, { duration = FIT_DURATION, padding = FIT_PADDING } = {}) {\n whenReady(graph, (ready) => ready.fitViewByPointPositions(corners(box), duration, padding));\n },\n frameSelection() {\n const indices = resident().indicesOf(store.getSnapshot().selection?.vertices ?? []);\n if (indices.length > 0) whenReady(graph, (ready) => ready.fitViewByPointIndices(indices, FIT_DURATION, 0.25));\n },\n clear,\n destroy() {\n unsubscribe();\n if (frame) cancelAnimationFrame(frame);\n painted();\n listening();\n // Read here rather than remembered from construction: the element exists only with the device.\n const canvas = host.querySelector(\"canvas\");\n canvas?.removeEventListener(\"webglcontextlost\", onLost);\n graph.destroy();\n releaseContext(canvas);\n },\n };\n}\n\nconst EMPTY: Resident = {\n size: 0,\n indexOf: () => undefined,\n at: () => undefined,\n indicesOf: () => [],\n verticesAt: () => [],\n};\n"],"names":["FIT_DURATION","FIT_PADDING","REHEAT","PROGRESS_STEPS","corners","box","createRenderer","host","store","events","fail","message","hasWebGL","sim","resolveSim","hovering","dragging","reported","progress","value","bucket","compose","createComposer","composition","look","resolveLook","lookPatch","dirty","frame","framed","pendingReveal","last","lastOptions","resident","EMPTY","viewport","height","width","isReady","graph","ax","ay","bx","by","view","observe","camera","Graph","forces","_a","index","vertex","focusOn","clear","error","schedule","whenReady","draw","ready","snapshot","options","changed","next","_b","reveal","drawn","buffers","paint","appearance","pinned","_c","frameExtent","extent","unsubscribe","applyForces","patch","simulate","moved","key","around","matrix","address","tileOfDense","denseOf","painted","onLost","event","listening","shape","found","factor","settled","duration","padding","indices","canvas","releaseContext"],"mappings":"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"}
1
+ {"version":3,"file":"renderer.js","sources":["../../src/render/renderer.ts"],"sourcesContent":["import { Graph } from \"@cosmos.gl/graph\";\nimport type { Box } from \"@fossil-lang/corpus\";\nimport type { Resident, VertexId } from \"../core/resident\";\nimport { denseOf } from \"../core/resident\";\nimport type { GraphSnapshot, GraphStore } from \"../core/store\";\nimport { tileOfDense, type Viewport } from \"../core/tile-matrix\";\nimport type { GraphCommands } from \"../core/types\";\nimport { createComposer, type Composition } from \"./compose\";\nimport { resolveLook, type Look } from \"./graph-looks\";\nimport { appearance, forces, paint } from \"./graph-model\";\nimport { resolveSim, type Sim } from \"./graph-sim\";\nimport { hasWebGL, releaseContext } from \"./webgl\";\n\nexport interface RendererEvents {\n /** After every frame and every camera move — where the overlays repaint. */\n onFrame?: () => void;\n /** A new composition was uploaded. */\n onComposed?: (composition: Composition) => void;\n /** Where the hovered point is in space, as cosmos.gl reports it: no GPU readback per hover. */\n onHover?: (position: [number, number] | null) => void;\n}\n\nexport interface Renderer extends GraphCommands {\n readonly graph: Graph;\n resident(): Resident;\n composition(): Composition | null;\n /** The theme moved under the canvas: colours are resolved again, nothing else. */\n repaint(): void;\n /** The drawn points inside a screen rectangle or polygon, once the device is ready. */\n hit(shape: { rect: [[number, number], [number, number]] } | { polygon: [number, number][] }): number[];\n destroy(): void;\n}\n\nconst FIT_DURATION = 420;\nconst FIT_PADDING = 0.18;\nconst REHEAT = 0.35;\n/** Twentieths: a settle costs twenty reports rather than one per frame. */\nconst PROGRESS_STEPS = 20;\n\nconst corners = (box: Box) => [box.x, box.y, box.x + box.w, box.y + box.h];\n\n/**\n * **cosmos.gl's lifetime, and the frame that renders once.** Built once per element; it subscribes to\n * the store and discharges what changed in one `requestAnimationFrame`:\n *\n * - a change of visible tiles recomposes, and dirties positions, links and the per-point arrays;\n * - a look or a theme change dirties colours, sizes and shapes and nothing else;\n * - a selection, a focus or a pin sets config and uploads nothing, and never calls `render()`:\n * `render()` walks every point and link in JS, and `setConfigPartial` asks for its own frame;\n * - a snapshot that changed none of those schedules nothing.\n *\n * `transitionDuration` is 0: the default animates every upload for 800 ms and keeps the loop awake.\n * The live layout is off unless `simulate` or the toolbar asks, and runs from the current positions;\n * a drag needs none, since cosmos.gl moves the dragged point itself. Every callback reads the store's latest options, so a host's inline `onFailure` never rebuilds it.\n */\nexport function createRenderer(host: HTMLDivElement, store: GraphStore, events: RendererEvents = {}): Renderer | null {\n const fail = (message: string) => store.getOptions().onFailure(message);\n if (!hasWebGL()) {\n fail(\"This canvas renders on the GPU, and this browser offers no WebGL context.\");\n return null;\n }\n\n let sim: Sim = resolveSim(store.getOptions().sim);\n let live = store.getOptions().simulate ?? false;\n let hovering: number | null = null;\n let dragging: number | null = null;\n let reported = -1;\n const progress = (value: number) => {\n const bucket = Math.round(value * PROGRESS_STEPS);\n if (bucket === reported) return;\n reported = bucket;\n store.reportProgress(bucket / PROGRESS_STEPS);\n };\n\n const compose = createComposer();\n let composition: Composition | null = null;\n let look: Look = resolveLook(store.getOptions().look);\n let lookPatch = store.getOptions().look;\n const dirty = { compose: true, paint: true, state: true, pinned: true };\n let frame = 0;\n let destroyed = false;\n let framed: GraphSnapshot[\"matrix\"] = null;\n let pendingReveal: VertexId | null = null;\n let last = store.getSnapshot();\n let lastOptions = store.getOptions();\n\n const resident = () => composition?.resident ?? EMPTY;\n\n const viewport = (): { view: Viewport; perPixel: number } | null => {\n const { height, width } = host.getBoundingClientRect();\n if (!graph.isReady || width === 0 || height === 0) return null;\n const [ax, ay] = graph.screenToSpacePosition([0, 0]);\n const [bx, by] = graph.screenToSpacePosition([width, height]);\n const view = { xMin: Math.min(ax, bx), yMin: Math.min(ay, by), xMax: Math.max(ax, bx), yMax: Math.max(ay, by) };\n return { view, perPixel: (view.xMax - view.xMin) / width };\n };\n const observe = () => {\n const camera = viewport();\n if (camera) store.setViewport(camera.view);\n };\n\n let graph: Graph;\n try {\n graph = new Graph(host, {\n // No `spaceSize` here: the box is the corpus's extent, set when the matrix arrives.\n // `rescalePositions: false` because the corpus's coordinates are the camera's — a rescale\n // between them means the cull and the viewport describe different places.\n rescalePositions: false,\n transitionDuration: 0,\n enableSimulation: live,\n ...forces(sim),\n // Frames to convergence: alpha reaches its floor after exactly this many rendered frames.\n simulationDecay: 400,\n randomSeed: \"kanzo-discovery\",\n pixelRatio: window.devicePixelRatio || 1,\n enableDrag: true,\n hoveredPointCursor: \"pointer\",\n attribution: \"\",\n onSimulationStart: () => store.report(\"running\"),\n onSimulationEnd: () => {\n store.report(\"settled\");\n progress(1);\n events.onFrame?.();\n },\n onSimulationPause: () => store.report(\"paused\"),\n onSimulationUnpause: () => store.report(\"running\"),\n onSimulationTick: (_alpha, index, position) => {\n progress(graph.progress);\n if (index !== undefined && position) events.onHover?.(position);\n events.onFrame?.();\n },\n onZoom: () => {\n observe();\n events.onFrame?.();\n },\n onPointMouseOver: (index, position) => {\n hovering = index;\n events.onHover?.(position);\n store.hover(resident().at(index) ?? null);\n },\n onPointMouseOut: () => {\n hovering = null;\n events.onHover?.(null);\n store.hover(null);\n },\n onDragStart: () => {\n dragging = hovering;\n },\n onDrag: (event) => {\n events.onHover?.(graph.screenToSpacePosition([event.x, event.y]));\n events.onFrame?.();\n },\n onDragEnd: () => {\n const vertex = dragging === null ? undefined : resident().at(dragging);\n dragging = null;\n if (vertex !== undefined) store.pin([...store.getSnapshot().pinned, vertex]);\n },\n onPointClick: (index) => {\n const vertex = resident().at(index);\n if (vertex !== undefined) focusOn(vertex, index);\n },\n onBackgroundClick: () => clear(),\n });\n } catch (error) {\n fail(`The renderer failed to start. (${String(error)})`);\n return null;\n }\n\n const schedule = () => {\n if (frame) return;\n frame = requestAnimationFrame(() => {\n frame = 0;\n draw();\n });\n };\n\n function draw(): void {\n const snapshot = store.getSnapshot();\n const options = store.getOptions();\n let changed = false;\n if (dirty.compose && snapshot.matrix) {\n dirty.compose = false;\n const next = compose({\n matrix: snapshot.matrix,\n typeIndex: snapshot.typeIndex,\n binding: snapshot.binding,\n modeColumn: snapshot.modeColumn,\n domain: snapshot.domain,\n visible: snapshot.visible,\n cached: snapshot.cached,\n perPixel: viewport()?.perPixel ?? 0,\n });\n if (next) {\n composition = next;\n graph.setPointPositions(next.positions, true);\n graph.setLinks(next.links);\n dirty.paint = true;\n dirty.state = true;\n dirty.pinned = true;\n changed = true;\n events.onComposed?.(next);\n if (pendingReveal !== null && next.resident.indexOf(pendingReveal) !== undefined) {\n const vertex = pendingReveal;\n pendingReveal = null;\n queueMicrotask(() => reveal(vertex));\n }\n }\n const drawn = next && { marks: next.marks, represented: next.represented, domain: next.domain, tally: next.tally };\n store.reportDrawn(snapshot.visible, drawn);\n }\n if (dirty.paint && composition) {\n dirty.paint = false;\n const buffers = paint(composition, look, host, options);\n graph.setPointColors(buffers.colors);\n graph.setPointSizes(buffers.sizes);\n graph.setPointShapes(buffers.shapes);\n graph.setLinkColors(buffers.linkColors);\n graph.setLinkWidths(buffers.linkWidths);\n graph.setConfigPartial(appearance(look, host));\n changed = true;\n }\n if (dirty.state && composition) {\n dirty.state = false;\n const drawn = composition.resident;\n graph.setConfigPartial({\n highlightedPointIndices: snapshot.selection ? drawn.indicesOf(snapshot.selection.vertices) : undefined,\n focusedPointIndex: snapshot.focus === null ? undefined : drawn.indexOf(snapshot.focus),\n });\n }\n if (dirty.pinned && composition) {\n dirty.pinned = false;\n const pinned = composition.resident.indicesOf(snapshot.pinned);\n graph.setPinnedPoints(pinned.length > 0 ? pinned : null);\n }\n if (changed) graph.render();\n events.onFrame?.();\n }\n\n const frameExtent = (snapshot: GraphSnapshot) => {\n const extent = snapshot.matrix?.extent;\n if (!extent || snapshot.matrix === framed) return;\n framed = snapshot.matrix;\n graph.setConfigPartial({ spaceSize: Math.max(extent.w, extent.h) });\n graph.fitViewByPointPositions(corners(extent), 0, FIT_PADDING);\n void graph.ready.then(() => {\n if (!destroyed) observe();\n });\n };\n\n const unsubscribe = store.subscribe(() => {\n const snapshot = store.getSnapshot();\n const options = store.getOptions();\n frameExtent(snapshot);\n if (snapshot.visible !== last.visible || snapshot.binding !== last.binding || snapshot.domain !== last.domain) {\n dirty.compose = true;\n }\n if (options.look !== lookPatch) {\n lookPatch = options.look;\n look = resolveLook(options.look);\n dirty.paint = true;\n }\n if (options.fill !== lastOptions.fill || options.symbol !== lastOptions.symbol || options.stroke !== lastOptions.stroke) {\n dirty.paint = true;\n }\n if (snapshot.selection !== last.selection || snapshot.focus !== last.focus) dirty.state = true;\n if (snapshot.pinned !== last.pinned) dirty.pinned = true;\n if (options.sim !== lastOptions.sim) applyForces(options.sim);\n if ((options.simulate ?? false) !== (lastOptions.simulate ?? false)) {\n if (options.simulate) run(REHEAT);\n else graph.pause();\n }\n last = snapshot;\n lastOptions = options;\n if (dirty.compose || dirty.paint || dirty.state || dirty.pinned) schedule();\n });\n\n function applyForces(patch: Partial<Sim> | undefined): void {\n const next = resolveSim(patch);\n const moved = Object.keys(next).some((key) => next[key as keyof Sim] !== sim[key as keyof Sim]);\n sim = next;\n if (!live) return;\n graph.setConfigPartial(forces(next));\n if (moved && store.getSnapshot().motion !== \"paused\") graph.start(REHEAT);\n }\n\n /** A layout runs from where the points are: enabling cosmos.gl's simulation keeps its positions. */\n function run(alpha: number): void {\n if (!live) {\n live = true;\n graph.setConfigPartial({ enableSimulation: true, ...forces(sim) });\n }\n graph.start(alpha);\n }\n\n function focusOn(vertex: VertexId, index: number): void {\n const drawn = resident();\n const around = drawn.verticesAt(graph.getNeighboringPointIndices(index));\n store.select([vertex, ...around], \"node\", \"Node\");\n store.focus(vertex);\n }\n\n function clear(): void {\n store.select(null);\n store.focus(null);\n }\n\n /** Centre and select one vertex; one that is not drawn is framed by its tile first, then revealed. */\n function reveal(vertex: VertexId): void {\n const index = resident().indexOf(vertex);\n if (index !== undefined) {\n focusOn(vertex, index);\n graph.zoomToPointByIndex(index, 500, 5, true);\n return;\n }\n const matrix = store.getSnapshot().matrix;\n const address = matrix ? tileOfDense(matrix, denseOf(vertex)) : null;\n const box = address && matrix?.tileMatrices[address.z]?.tiles[address.tile]?.bbox;\n if (!box) return;\n pendingReveal = vertex;\n graph.fitViewByPointPositions(corners(box), FIT_DURATION, FIT_PADDING);\n }\n\n // cosmos.gl 3.4 queues every setter and command until its device exists (`ensureDevice`), and its\n // two synchronous hit tests answer `[]` until then; only the canvas element has to wait for `ready`.\n graph.setConfigPartial(appearance(look, host));\n graph.render();\n const onLost = (event: Event) => {\n event.preventDefault();\n fail(\"The graph's WebGL context was lost. A browser keeps a limited number of them and drops the oldest; reload the page to get one back.\");\n };\n void graph.ready.then(() => {\n if (!destroyed) host.querySelector(\"canvas\")?.addEventListener(\"webglcontextlost\", onLost);\n });\n store.report(live && graph.isSimulationRunning ? \"running\" : \"settled\");\n frameExtent(last);\n schedule();\n\n return {\n graph,\n resident,\n composition: () => composition,\n repaint() {\n dirty.paint = true;\n schedule();\n },\n hit(shape) {\n const found = \"rect\" in shape ? graph.findPointsInRect(shape.rect) : graph.findPointsInPolygon(shape.polygon);\n return Array.from(found);\n },\n zoomBy(factor) {\n graph.setZoomLevel(graph.getZoomLevel() * factor, 220);\n },\n fit() {\n const extent = store.getSnapshot().matrix?.extent;\n if (extent) graph.fitViewByPointPositions(corners(extent), FIT_DURATION, FIT_PADDING);\n else graph.fitView(FIT_DURATION, FIT_PADDING);\n },\n pause: () => graph.pause(),\n resume() {\n const settled = store.getSnapshot().motion === \"settled\";\n if (settled || !live) run(REHEAT);\n else graph.unpause();\n },\n restart() {\n store.pin([]);\n run(1);\n },\n unpin() {\n if (store.getSnapshot().pinned.length === 0) return;\n store.pin([]);\n if (store.getSnapshot().motion === \"running\") graph.start(REHEAT);\n },\n reveal,\n frameBox(box, { duration = FIT_DURATION, padding = FIT_PADDING } = {}) {\n graph.fitViewByPointPositions(corners(box), duration, padding);\n },\n frameSelection() {\n const indices = resident().indicesOf(store.getSnapshot().selection?.vertices ?? []);\n if (indices.length > 0) graph.fitViewByPointIndices(indices, FIT_DURATION, 0.25);\n },\n clear,\n destroy() {\n unsubscribe();\n if (frame) cancelAnimationFrame(frame);\n destroyed = true;\n // Read here rather than remembered from construction: the element exists only with the device.\n const canvas = host.querySelector(\"canvas\");\n canvas?.removeEventListener(\"webglcontextlost\", onLost);\n graph.destroy();\n releaseContext(canvas);\n },\n };\n}\n\nconst EMPTY: Resident = { size: 0, indexOf: () => undefined, at: () => undefined, indicesOf: () => [], verticesAt: () => [] };\n"],"names":["FIT_DURATION","FIT_PADDING","REHEAT","PROGRESS_STEPS","corners","box","createRenderer","host","store","events","fail","message","hasWebGL","sim","resolveSim","live","hovering","dragging","reported","progress","value","bucket","compose","createComposer","composition","look","resolveLook","lookPatch","dirty","frame","destroyed","framed","pendingReveal","last","lastOptions","resident","EMPTY","viewport","height","width","graph","ax","ay","bx","by","view","observe","camera","Graph","forces","_a","_alpha","index","position","_b","event","vertex","focusOn","clear","error","schedule","draw","snapshot","options","changed","next","reveal","drawn","buffers","paint","appearance","pinned","_c","frameExtent","extent","unsubscribe","applyForces","run","patch","moved","key","alpha","around","matrix","address","tileOfDense","denseOf","onLost","shape","found","factor","duration","padding","indices","canvas","releaseContext"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanzo-tech/graph",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Kanzo graph view — a tileset over a fossil corpus's scan, drawn with cosmos.gl, inside the page's Mosaic crossfilter. Sibling of @kanzo-tech/ui, not part of it: the admission rules exclude graphs from the generic vocabulary by name.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -23,18 +23,18 @@
23
23
  "./package.json": "./package.json"
24
24
  },
25
25
  "//peers": "All required. cosmos.gl draws; `lucide-react` is the icon set the parts draw their buttons with, `@kanzo-tech/ui`'s own peer; `@fossil-lang/corpus` is the backend — the host opens a corpus with its `open` on `@kanzo-tech/mosaic`'s `engine()` and this package draws it through `tileMatrix`, `scan` and `edges`, writing no SQL of its own; `@kanzo-tech/mosaic` carries the crossfilter the graph listens to and publishes into. They were optional while a root barrel with no source and a `./duckdb` entry with one existed side by side; there is one path now and nothing on it is optional (`/docs/design/graph`, *the one host path*). The Mosaic stack itself — mosaic-core, mosaic-sql — is `@kanzo-tech/mosaic`'s peer, declared once there.",
26
- "//fossil": "The floor is `0.3.0-alpha.13`, the release whose `scan(…).read` and `edges` take a list of addresses and answer one batch per tile, and an `Engine.query` that answers in columns and interrupts on abort, over corpora whose `dense_id` is the Hilbert rank. Only types and the writer's role table (`PAYLOAD_*`) are imported; `src/layers.test.ts` holds that.",
26
+ "//fossil": "The floor is `0.3.0-alpha.14`, the release whose `scan(…).read` and `edges` take a list of addresses and answer one batch per tile, and an `Engine.query` that answers in columns and interrupts on abort, over corpora whose `dense_id` is the Hilbert rank. Only types and the writer's role table (`PAYLOAD_*`) are imported; `src/layers.test.ts` holds that.",
27
27
  "peerDependencies": {
28
28
  "@cosmos.gl/graph": "^3.4.0",
29
- "@fossil-lang/corpus": "^0.3.0-alpha.13",
29
+ "@fossil-lang/corpus": "^0.3.0-alpha.14",
30
30
  "lucide-react": ">=1",
31
31
  "react": "^19.0.0",
32
- "@kanzo-tech/mosaic": "0.13.0",
33
- "@kanzo-tech/ui": "0.13.0"
32
+ "@kanzo-tech/mosaic": "0.14.0",
33
+ "@kanzo-tech/ui": "0.14.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@cosmos.gl/graph": "^3.4.0",
37
- "@fossil-lang/corpus": "^0.3.0-alpha.13",
37
+ "@fossil-lang/corpus": "^0.3.0-alpha.14",
38
38
  "@testing-library/dom": "^10.4.1",
39
39
  "@testing-library/react": "^16.3.2",
40
40
  "@types/react": "^19.0.0",
@@ -46,8 +46,26 @@
46
46
  "react": "^19.0.0",
47
47
  "react-dom": "^19.0.0",
48
48
  "rollup-plugin-preserve-directives": "^0.4.0",
49
- "@kanzo-tech/mosaic": "0.13.0"
49
+ "@kanzo-tech/mosaic": "0.14.0"
50
50
  },
51
+ "//size-limit": "Budgets our code only: `ignore` mirrors the peers the build externalises in vite.config.ts, cosmos.gl included (about 190 kB gzipped on its own, and the consumer pays it once whatever this package does). First measured 2026-09-30 at 19.07 kB, before the lag work of `perf/phase1-lag`; budget set just above so real growth trips the gate.",
52
+ "size-limit": [
53
+ {
54
+ "name": "root barrel (JS)",
55
+ "path": "dist/index.js",
56
+ "limit": "19.5 kB",
57
+ "ignore": [
58
+ "react",
59
+ "react-dom",
60
+ "react/jsx-runtime",
61
+ "@cosmos.gl/graph",
62
+ "@fossil-lang/corpus",
63
+ "@kanzo-tech/mosaic",
64
+ "@kanzo-tech/ui",
65
+ "lucide-react"
66
+ ]
67
+ }
68
+ ],
51
69
  "repository": {
52
70
  "type": "git",
53
71
  "url": "git+https://github.com/Kanzo-Tech/ui.git",
@@ -60,6 +78,7 @@
60
78
  "scripts": {
61
79
  "build": "vite build",
62
80
  "typecheck": "tsc --noEmit",
63
- "test": "vitest run"
81
+ "test": "vitest run",
82
+ "size": "size-limit"
64
83
  }
65
84
  }