@kanzo-tech/graph 0.25.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/core/categories.d.ts +1 -1
- package/dist/core/categories.d.ts.map +1 -1
- package/dist/core/categories.js.map +1 -1
- package/dist/core/channels.d.ts +12 -6
- package/dist/core/channels.d.ts.map +1 -1
- package/dist/core/channels.js +15 -12
- package/dist/core/channels.js.map +1 -1
- package/dist/core/client.d.ts +26 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/client.js +62 -0
- package/dist/core/client.js.map +1 -0
- package/dist/core/error.d.ts +3 -3
- package/dist/core/error.d.ts.map +1 -1
- package/dist/core/error.js.map +1 -1
- package/dist/core/load.d.ts +30 -39
- package/dist/core/load.d.ts.map +1 -1
- package/dist/core/load.js +63 -117
- package/dist/core/load.js.map +1 -1
- package/dist/core/source.d.ts +90 -0
- package/dist/core/source.d.ts.map +1 -0
- package/dist/core/source.js +105 -0
- package/dist/core/source.js.map +1 -0
- package/dist/core/state.d.ts +19 -20
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +138 -158
- package/dist/core/store.js.map +1 -1
- package/dist/core/types.d.ts +5 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -18
- package/dist/index.js.map +1 -1
- package/dist/parts/graph-canvas.d.ts.map +1 -1
- package/dist/parts/graph-canvas.js +49 -48
- package/dist/parts/graph-canvas.js.map +1 -1
- package/dist/parts/graph-counts.js +4 -4
- package/dist/parts/graph-counts.js.map +1 -1
- package/dist/parts/graph-inspector.d.ts +3 -3
- package/dist/parts/graph-inspector.d.ts.map +1 -1
- package/dist/parts/graph-inspector.js +45 -43
- package/dist/parts/graph-inspector.js.map +1 -1
- package/dist/parts/graph-search.d.ts +7 -7
- package/dist/parts/graph-search.d.ts.map +1 -1
- package/dist/parts/graph-search.js +60 -69
- package/dist/parts/graph-search.js.map +1 -1
- package/dist/parts/graph-select.d.ts +27 -0
- package/dist/parts/graph-select.d.ts.map +1 -0
- package/dist/parts/graph-select.js +53 -0
- package/dist/parts/graph-select.js.map +1 -0
- package/dist/parts/graph-toolbar.js +1 -1
- package/dist/parts/graph-toolbar.js.map +1 -1
- package/dist/react/use-graph.js +31 -31
- package/dist/react/use-graph.js.map +1 -1
- package/dist/render/camera.d.ts +12 -1
- package/dist/render/camera.d.ts.map +1 -1
- package/dist/render/camera.js +33 -21
- package/dist/render/camera.js.map +1 -1
- package/dist/render/graph-sim.d.ts +1 -1
- package/dist/render/graph-sim.d.ts.map +1 -1
- package/dist/render/graph-sim.js.map +1 -1
- package/dist/render/motion.d.ts +33 -0
- package/dist/render/motion.d.ts.map +1 -0
- package/dist/render/motion.js +19 -0
- package/dist/render/motion.js.map +1 -0
- package/dist/render/placement.d.ts +2 -4
- package/dist/render/placement.d.ts.map +1 -1
- package/dist/render/placement.js +12 -16
- package/dist/render/placement.js.map +1 -1
- package/dist/render/renderer.d.ts +6 -5
- package/dist/render/renderer.d.ts.map +1 -1
- package/dist/render/renderer.js +130 -118
- package/dist/render/renderer.js.map +1 -1
- package/dist/section.js +1 -1
- package/dist/section.js.map +1 -1
- package/package.json +12 -14
- package/dist/core/detail.d.ts +0 -26
- package/dist/core/detail.d.ts.map +0 -1
- package/dist/core/detail.js +0 -63
- package/dist/core/detail.js.map +0 -1
- package/dist/core/filter.d.ts +0 -23
- package/dist/core/filter.d.ts.map +0 -1
- package/dist/core/filter.js +0 -95
- package/dist/core/filter.js.map +0 -1
package/dist/core/store.js
CHANGED
|
@@ -1,32 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
function
|
|
8
|
-
const f =
|
|
9
|
-
let
|
|
10
|
-
for (let
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
f[
|
|
1
|
+
import { domainOf as L } from "./categories.js";
|
|
2
|
+
import { bindingOf as $ } from "./channels.js";
|
|
3
|
+
import { GraphClient as M, publish as R } from "./client.js";
|
|
4
|
+
import { GraphError as V } from "./error.js";
|
|
5
|
+
import { loadGeometry as W, loadEncoding as X } from "./load.js";
|
|
6
|
+
import { readStructure as Y } from "./source.js";
|
|
7
|
+
function Z(d, o, a) {
|
|
8
|
+
const f = o.domain.map(() => 0), y = new Uint8Array(d.size);
|
|
9
|
+
let l = 0;
|
|
10
|
+
for (let r = 0; r < d.size; r++) {
|
|
11
|
+
if (a && !a[r] || Number.isNaN(d.positions[r * 2])) continue;
|
|
12
|
+
y[r] = 1, l++;
|
|
13
|
+
const p = o.ranks[r];
|
|
14
|
+
f[p] = (f[p] ?? 0) + 1;
|
|
15
15
|
}
|
|
16
|
-
let
|
|
17
|
-
const { links:
|
|
18
|
-
for (let
|
|
19
|
-
|
|
20
|
-
return { vertices:
|
|
16
|
+
let u = 0;
|
|
17
|
+
const { links: i } = d;
|
|
18
|
+
for (let r = 0; r < i.length; r += 2)
|
|
19
|
+
y[i[r]] && y[i[r + 1]] && u++;
|
|
20
|
+
return { vertices: l, edges: u, domain: o.domain, tally: f };
|
|
21
21
|
}
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
function H(d, o) {
|
|
23
|
+
const a = new Uint8Array(d);
|
|
24
|
+
for (const f of o) f < d && (a[f] = 1);
|
|
25
|
+
return a;
|
|
26
|
+
}
|
|
27
|
+
function re(d) {
|
|
28
|
+
let o = d;
|
|
29
|
+
const a = /* @__PURE__ */ new Set();
|
|
30
|
+
let f = !1, y = !1, l = $(d), u = null, i = null, r = null, p = null, h = null, O = [];
|
|
31
|
+
const k = { structure: 0, geometry: 0, encoding: 0 }, b = { structure: !1, geometry: !1, encoding: !1 };
|
|
32
|
+
let m = null, B = null, z = !1, C = !0, N = null;
|
|
33
|
+
const G = (e) => {
|
|
34
|
+
C ? N = { error: e } : o.onFailure(e);
|
|
28
35
|
};
|
|
29
|
-
let
|
|
36
|
+
let c = {
|
|
30
37
|
status: "none",
|
|
31
38
|
total: void 0,
|
|
32
39
|
drawn: null,
|
|
@@ -38,197 +45,170 @@ function ye(u) {
|
|
|
38
45
|
tool: null,
|
|
39
46
|
motion: "settled",
|
|
40
47
|
progress: 1,
|
|
41
|
-
options:
|
|
42
|
-
|
|
43
|
-
binding:
|
|
48
|
+
options: o,
|
|
49
|
+
structure: null,
|
|
50
|
+
binding: l,
|
|
44
51
|
geometry: null,
|
|
45
52
|
encoding: null,
|
|
46
53
|
mask: null
|
|
47
|
-
},
|
|
48
|
-
function
|
|
49
|
-
const e = [
|
|
50
|
-
return
|
|
54
|
+
}, T = { key: [], value: [] };
|
|
55
|
+
function E() {
|
|
56
|
+
const e = (u == null ? void 0 : u.vertices) ?? [], n = [e, l.byTable, l.category, o.categories];
|
|
57
|
+
return n.some((t, s) => t !== T.key[s]) && (T = { key: n, value: L(e, l, o.categories) }), T.value;
|
|
51
58
|
}
|
|
52
|
-
let
|
|
53
|
-
function
|
|
54
|
-
const e = [
|
|
55
|
-
return e.some((n, t) => n !==
|
|
59
|
+
let F = { key: [], value: null };
|
|
60
|
+
function I() {
|
|
61
|
+
const e = [i, r, h];
|
|
62
|
+
return e.some((n, t) => n !== F.key[t]) && (F = { key: e, value: i && r ? Z(i, r, h) : null }), F.value;
|
|
56
63
|
}
|
|
57
|
-
function
|
|
58
|
-
if (
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return d || i || !n ? "loading" : "idle";
|
|
64
|
+
function J() {
|
|
65
|
+
if (f || y) return "failed";
|
|
66
|
+
if (o.from === null || o.coordinator === null) return "none";
|
|
67
|
+
const n = i !== null && [i, r, h].every((t, s) => t === O[s]);
|
|
68
|
+
return b.structure || b.geometry || b.encoding || !n ? "loading" : "idle";
|
|
63
69
|
}
|
|
64
70
|
function g(e = {}) {
|
|
65
|
-
|
|
66
|
-
...
|
|
67
|
-
total:
|
|
68
|
-
drawn:
|
|
69
|
-
domain:
|
|
70
|
-
options:
|
|
71
|
-
|
|
72
|
-
binding:
|
|
73
|
-
geometry:
|
|
74
|
-
encoding:
|
|
75
|
-
mask:
|
|
71
|
+
c = {
|
|
72
|
+
...c,
|
|
73
|
+
total: u == null ? void 0 : u.size,
|
|
74
|
+
drawn: I(),
|
|
75
|
+
domain: E(),
|
|
76
|
+
options: o,
|
|
77
|
+
structure: u,
|
|
78
|
+
binding: l,
|
|
79
|
+
geometry: i,
|
|
80
|
+
encoding: r,
|
|
81
|
+
mask: h,
|
|
76
82
|
...e
|
|
77
|
-
},
|
|
83
|
+
}, c = { ...c, status: J() }, P();
|
|
78
84
|
}
|
|
79
|
-
function
|
|
80
|
-
|
|
85
|
+
function v(e) {
|
|
86
|
+
c = { ...c, ...e }, P();
|
|
81
87
|
}
|
|
82
|
-
function
|
|
83
|
-
for (const e of
|
|
88
|
+
function P() {
|
|
89
|
+
for (const e of a) e();
|
|
84
90
|
}
|
|
85
|
-
function
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
(K) => {
|
|
91
|
-
e() === O && (n(null), S(K), g());
|
|
91
|
+
function S(e, n, t) {
|
|
92
|
+
const s = ++k[e];
|
|
93
|
+
b[e] = !0, n().then(
|
|
94
|
+
(w) => {
|
|
95
|
+
k[e] === s && (b[e] = !1, t(w), g());
|
|
92
96
|
},
|
|
93
|
-
(
|
|
94
|
-
e
|
|
97
|
+
(w) => {
|
|
98
|
+
k[e] === s && (b[e] = !1, f = !0, G(w), g());
|
|
95
99
|
}
|
|
96
100
|
);
|
|
97
101
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
});
|
|
107
|
-
C(...H, (o) => oe(e, c, n, o), (o) => {
|
|
108
|
-
a = o.geometry, b = o.encoding, v = a && N ? R(a, N) : null;
|
|
102
|
+
function U() {
|
|
103
|
+
const { coordinator: e, from: n } = o;
|
|
104
|
+
e === null || n === null || S("structure", () => Y(e, n), (t) => {
|
|
105
|
+
if (t.size === 0) {
|
|
106
|
+
f = !0, G(new V("graph/nothing-to-draw", `the corpus attached as ${n} has no vertex`));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
u = t, j(), m == null || m.requestQuery();
|
|
109
110
|
});
|
|
110
111
|
}
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (F === void 0) {
|
|
116
|
-
N = null, v = null;
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
const n = F;
|
|
120
|
-
C(...X, (t) => le(e, l, n, t), (t) => {
|
|
121
|
-
N = t, v = a ? R(a, t) : null;
|
|
112
|
+
function j() {
|
|
113
|
+
const { coordinator: e } = o, n = u;
|
|
114
|
+
e === null || n === null || S("geometry", () => W(e, n, l), (t) => {
|
|
115
|
+
i = t, h = p ? H(t.size, p) : null, q();
|
|
122
116
|
});
|
|
123
117
|
}
|
|
124
|
-
function
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
return h = !0, T(n), g(e);
|
|
132
|
-
}
|
|
133
|
-
J(), P(), g(e);
|
|
118
|
+
function q() {
|
|
119
|
+
const { coordinator: e } = o, n = i;
|
|
120
|
+
if (e === null || n === null) return;
|
|
121
|
+
const t = E();
|
|
122
|
+
S("encoding", () => X(e, n, l, t), (s) => {
|
|
123
|
+
r = s;
|
|
124
|
+
});
|
|
134
125
|
}
|
|
135
|
-
function
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
126
|
+
function K() {
|
|
127
|
+
for (const e of Object.keys(k))
|
|
128
|
+
k[e]++, b[e] = !1;
|
|
129
|
+
f = !1, u = i = r = null, p = h = null, O = [], g({ selection: null, focus: null, hovered: null, pinned: [] }), U();
|
|
130
|
+
}
|
|
131
|
+
function A() {
|
|
132
|
+
D();
|
|
133
|
+
const { coordinator: e, filterBy: n } = o;
|
|
134
|
+
e !== null && (m = new M(
|
|
135
|
+
n,
|
|
136
|
+
() => u,
|
|
140
137
|
(t) => {
|
|
141
|
-
|
|
138
|
+
p = t, h = t && i ? H(i.size, t) : null, g();
|
|
142
139
|
},
|
|
143
|
-
(t) =>
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
);
|
|
140
|
+
(t) => G(t)
|
|
141
|
+
), e.connect(m), B = e);
|
|
147
142
|
}
|
|
148
143
|
function D() {
|
|
149
|
-
|
|
150
|
-
const e = r.filterBy, n = () => {
|
|
151
|
-
let t;
|
|
152
|
-
try {
|
|
153
|
-
t = e ? ne(e, f) : void 0;
|
|
154
|
-
} catch (o) {
|
|
155
|
-
T(o);
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
ie(t, F) || (F = t, P(), g());
|
|
159
|
-
};
|
|
160
|
-
e && (e.addEventListener("value", n), w = () => e.removeEventListener("value", n)), n();
|
|
144
|
+
m && B && B.disconnect(m), m = null, B = null;
|
|
161
145
|
}
|
|
162
|
-
const
|
|
146
|
+
const Q = {
|
|
163
147
|
/**
|
|
164
|
-
* The first subscriber
|
|
165
|
-
* graph go — `QueryObserver`'s `onSubscribe`/`onUnsubscribe`, which is what
|
|
166
|
-
* mounting everything twice.
|
|
148
|
+
* The first subscriber connects the client to the coordinator, and the last one disconnects it
|
|
149
|
+
* and lets the graph go — `QueryObserver`'s `onSubscribe`/`onUnsubscribe`, which is what
|
|
150
|
+
* survives StrictMode mounting everything twice.
|
|
167
151
|
*/
|
|
168
152
|
subscribe(e) {
|
|
169
|
-
if (
|
|
170
|
-
const { error: n } =
|
|
171
|
-
|
|
153
|
+
if (a.add(e), !z && (z = !0, A(), N !== null)) {
|
|
154
|
+
const { error: n } = N;
|
|
155
|
+
N = null, o.onFailure(n);
|
|
172
156
|
}
|
|
173
157
|
return () => {
|
|
174
|
-
|
|
158
|
+
a.delete(e), a.size === 0 && Q.destroy();
|
|
175
159
|
};
|
|
176
160
|
},
|
|
177
|
-
getSnapshot: () =>
|
|
178
|
-
getOptions: () =>
|
|
161
|
+
getSnapshot: () => c,
|
|
162
|
+
getOptions: () => o,
|
|
179
163
|
setOptions(e) {
|
|
180
|
-
const n =
|
|
181
|
-
|
|
182
|
-
const t =
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
z && e.filterBy !== n.filterBy && D(), o && J(), g();
|
|
164
|
+
const n = o;
|
|
165
|
+
o = e;
|
|
166
|
+
const t = l;
|
|
167
|
+
if (l = $(e), e.from !== n.from || e.coordinator !== n.coordinator)
|
|
168
|
+
return z && e.coordinator !== n.coordinator && A(), K();
|
|
169
|
+
z && e.filterBy !== n.filterBy && A(), l.x !== t.x || l.y !== t.y ? j() : (l.category !== t.category || l.byTable !== t.byTable || l.size !== t.size || l.cluster !== t.cluster || e.categories !== n.categories) && q(), g();
|
|
188
170
|
},
|
|
189
171
|
destroy() {
|
|
190
|
-
z = !1,
|
|
172
|
+
z = !1, D(), a.clear();
|
|
191
173
|
},
|
|
192
|
-
select(e, n = "
|
|
193
|
-
var
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
const S = (E = l[0]) == null ? void 0 : E.key;
|
|
197
|
-
r.filterBy && S && ee(r.filterBy, f, S, o ? o.vertices : null);
|
|
174
|
+
select(e, n = "external", t = "") {
|
|
175
|
+
var w;
|
|
176
|
+
const s = e && e.length > 0 ? { vertices: [...e], source: n, label: t } : null;
|
|
177
|
+
v({ selection: s }), (w = o.onSelect) == null || w.call(o, s), o.filterBy && m && R(o.filterBy, m, s ? s.vertices : null);
|
|
198
178
|
},
|
|
199
179
|
focus(e) {
|
|
200
180
|
var n;
|
|
201
|
-
e !==
|
|
181
|
+
e !== c.focus && (v({ focus: e }), (n = o.onFocus) == null || n.call(o, e));
|
|
202
182
|
},
|
|
203
183
|
hover(e) {
|
|
204
|
-
e !==
|
|
184
|
+
e !== c.hovered && v({ hovered: e });
|
|
205
185
|
},
|
|
206
186
|
pin(e) {
|
|
207
|
-
|
|
187
|
+
v({ pinned: [...e] });
|
|
208
188
|
},
|
|
209
189
|
setTool(e) {
|
|
210
|
-
e !==
|
|
190
|
+
e !== c.tool && v({ tool: e });
|
|
211
191
|
},
|
|
212
192
|
report(e) {
|
|
213
|
-
e !==
|
|
193
|
+
e !== c.motion && v({ motion: e });
|
|
214
194
|
},
|
|
215
195
|
reportProgress(e) {
|
|
216
|
-
e !==
|
|
196
|
+
e !== c.progress && v({ progress: e });
|
|
217
197
|
},
|
|
218
198
|
renderable() {
|
|
219
|
-
|
|
199
|
+
y && (y = !1, g());
|
|
220
200
|
},
|
|
221
201
|
unrenderable(e) {
|
|
222
|
-
|
|
202
|
+
y = !0, G(e), g();
|
|
223
203
|
},
|
|
224
204
|
reportDrawn(e) {
|
|
225
205
|
const n = [e.geometry, e.encoding, e.mask];
|
|
226
|
-
n.every((t,
|
|
206
|
+
n.every((t, s) => t === O[s]) || (O = n, g());
|
|
227
207
|
}
|
|
228
208
|
};
|
|
229
|
-
return
|
|
209
|
+
return U(), g(), C = !1, Q;
|
|
230
210
|
}
|
|
231
211
|
export {
|
|
232
|
-
|
|
212
|
+
re as createGraph
|
|
233
213
|
};
|
|
234
214
|
//# sourceMappingURL=store.js.map
|
package/dist/core/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sources":["../../src/core/store.ts"],"sourcesContent":["import { GraphError } from \"./error\";\nimport type { MosaicClient } from \"@kanzo-tech/mosaic\";\nimport { domainOf } from \"./categories\";\nimport { bindingOf } from \"./channels\";\nimport type { Corpus, Filter, VertexTable } from \"@fossil-lang/corpus\";\nimport { filterFor, graphClient, publish } from \"./filter\";\nimport { drawnTables, loadEncoding, loadGraph, maskOf, readKept, type Encoding, type Geometry, type Kept } from \"./load\";\nimport type { Drawn, GraphOptions, GraphSnapshot, GraphStatus, GraphStore } from \"./state\";\n\nexport type { Drawn, GraphOptions, GraphSnapshot, GraphState, GraphStatus, GraphStore } from \"./state\";\n\nconst sameFilter = (a: Filter | undefined, b: Filter | undefined) =>\n JSON.stringify(a, (_, v: unknown) => (typeof v === \"bigint\" ? `${v}n` : v)) ===\n JSON.stringify(b, (_, v: unknown) => (typeof v === \"bigint\" ? `${v}n` : v));\n\nconst isPromise = (value: unknown): value is PromiseLike<Corpus> =>\n typeof (value as PromiseLike<Corpus> | null)?.then === \"function\";\n\nfunction drawnOf(geometry: Geometry, encoding: Encoding, mask: Uint8Array | null): Drawn {\n const tally = encoding.domain.map(() => 0);\n const shown = new Uint8Array(geometry.size);\n let vertices = 0;\n for (let id = 0; id < geometry.size; id++) {\n if ((mask && !mask[id]) || Number.isNaN(geometry.positions[id * 2])) continue;\n shown[id] = 1;\n vertices++;\n const rank = encoding.ranks[id] as number;\n tally[rank] = (tally[rank] ?? 0) + 1;\n }\n let edges = 0;\n const { links } = geometry;\n for (let i = 0; i < links.length; i += 2) {\n if (shown[links[i] as number] && shown[links[i + 1] as number]) edges++;\n }\n return { vertices, edges, domain: encoding.domain, tally };\n}\n\nexport function createGraph(initial: GraphOptions): GraphStore {\n let options = initial;\n const listeners = new Set<() => void>();\n const self: MosaicClient = graphClient();\n\n let corpus: Corpus | null = null;\n let opening: PromiseLike<Corpus> | null = null;\n let failed = false;\n let unrenderable = false;\n let tables: readonly VertexTable[] = [];\n let binding = bindingOf(initial);\n let filter: Filter | undefined;\n let loading: AbortController | null = null;\n let filtering: AbortController | null = null;\n let geometry: Geometry | null = null;\n let encoding: Encoding | null = null;\n let kept: Kept | null = null;\n let mask: Uint8Array | null = null;\n let uploaded: readonly unknown[] = [];\n let unlisten: (() => void) | null = null;\n let active = false;\n\n // A failure found while the store is being built is found while React is still rendering —\n // `useGraph` builds it in `useState` — and a host's `onFailure` is usually a `setState`. It is held\n // and reported to the first subscriber, which arrives in the commit phase.\n let building = true;\n let held: { error: unknown } | null = null;\n const fail = (error: unknown) => {\n if (building) held = { error };\n else options.onFailure(error);\n };\n\n let snapshot: GraphSnapshot = {\n status: \"none\",\n total: undefined,\n drawn: null,\n domain: [],\n selection: null,\n focus: null,\n hovered: null,\n pinned: [],\n tool: null,\n motion: \"settled\",\n progress: 1,\n options,\n corpus: null,\n binding,\n geometry: null,\n encoding: null,\n mask: null,\n };\n\n let domain: { key: unknown[]; value: readonly unknown[] } = { key: [], value: [] };\n function domainNow(): readonly unknown[] {\n const key = [tables, binding.byTable, binding.category, options.categories];\n if (key.some((part, i) => part !== domain.key[i])) domain = { key, value: domainOf(tables, binding, options.categories) };\n return domain.value;\n }\n\n let drawn: { key: unknown[]; value: Drawn | null } = { key: [], value: null };\n function drawnNow(): Drawn | null {\n const key = [geometry, encoding, mask];\n if (key.some((part, i) => part !== drawn.key[i])) {\n drawn = { key, value: geometry && encoding ? drawnOf(geometry, encoding, mask) : null };\n }\n return drawn.value;\n }\n\n function statusOf(): GraphStatus {\n if (failed || unrenderable) return \"failed\";\n if (opening) return \"opening\";\n if (!corpus) return \"none\";\n const current = [geometry, encoding, mask];\n const shown = geometry !== null && current.every((part, i) => part === uploaded[i]);\n return loading || filtering || !shown ? \"loading\" : \"idle\";\n }\n\n function notify(fields: Partial<GraphSnapshot> = {}): void {\n snapshot = {\n ...snapshot,\n total: corpus ? tables.reduce((sum, table) => sum + table.record_count, 0) : undefined,\n drawn: drawnNow(),\n domain: domainNow(),\n options,\n corpus,\n binding,\n geometry,\n encoding,\n mask,\n ...fields,\n };\n snapshot = { ...snapshot, status: statusOf() };\n emit();\n }\n\n /** A change of state only — hover, focus, selection, tool, motion — derives nothing. */\n function patch(fields: Partial<GraphSnapshot>): void {\n snapshot = { ...snapshot, ...fields };\n emit();\n }\n\n function emit(): void {\n for (const listener of listeners) listener();\n }\n\n /**\n * One read in flight per kind, and a newer ask aborts the older one's statements. A load that\n * fails leaves nothing to draw; a filter that fails leaves the last picture.\n */\n function run<T>(\n current: () => AbortController | null,\n set: (aborter: AbortController | null) => void,\n fatal: boolean,\n read: (signal: AbortSignal) => Promise<T>,\n done: (value: T) => void,\n ): void {\n current()?.abort();\n const aborter = new AbortController();\n set(aborter);\n read(aborter.signal).then(\n (value) => {\n if (current() !== aborter) return;\n set(null);\n done(value);\n notify();\n },\n (error: unknown) => {\n // An aborted read is one this store cancelled, not a failure of the corpus.\n if (current() !== aborter || aborter.signal.aborted) return;\n set(null);\n failed ||= fatal;\n fail(error);\n notify();\n },\n );\n }\n\n const asLoad = [() => loading, (a: AbortController | null) => (loading = a), true] as const;\n const asFilter = [() => filtering, (a: AbortController | null) => (filtering = a), false] as const;\n\n function load(): void {\n const open = corpus;\n if (!open) return;\n const seed = domainNow();\n const given = geometry;\n if (given) {\n return run(...asLoad, (signal) => loadEncoding(open, given, binding, seed, signal), (next) => {\n encoding = next;\n });\n }\n run(...asLoad, (signal) => loadGraph(open, binding, seed, signal), (next) => {\n geometry = next.geometry;\n encoding = next.encoding;\n mask = geometry && kept ? maskOf(geometry, kept) : null;\n });\n }\n\n function refilter(): void {\n filtering?.abort();\n filtering = null;\n const open = corpus;\n if (!open || tables.length === 0) return;\n if (filter === undefined) {\n kept = null;\n mask = null;\n return;\n }\n const given = filter;\n run(...asFilter, (signal) => readKept(open, tables, given, signal), (next) => {\n kept = next;\n mask = geometry ? maskOf(geometry, next) : null;\n });\n }\n\n function reopen(): void {\n loading?.abort();\n filtering?.abort();\n loading = filtering = null;\n failed = false;\n geometry = encoding = mask = kept = null;\n uploaded = [];\n tables = [];\n const cleared = { selection: null, focus: null, hovered: null, pinned: [] };\n if (!corpus) return notify(cleared);\n try {\n tables = drawnTables(corpus);\n if (tables.length === 0) throw new GraphError(\"graph/nothing-to-draw\", \"the corpus has no vertex type with a position to draw\");\n } catch (error) {\n failed = true;\n fail(error);\n return notify(cleared);\n }\n load();\n refilter();\n notify(cleared);\n }\n\n /** A promise is adopted when it settles, and only if it is still the corpus the host means. */\n function adopt(given: GraphOptions[\"corpus\"]): void {\n corpus = null;\n opening = isPromise(given) ? given : null;\n if (!opening) {\n corpus = given as Corpus | null;\n return reopen();\n }\n const promised = opening;\n reopen();\n promised.then(\n (opened) => {\n if (opening !== promised) return;\n opening = null;\n corpus = opened;\n reopen();\n },\n (error: unknown) => {\n if (opening !== promised) return;\n opening = null;\n failed = true;\n fail(error);\n notify();\n },\n );\n }\n\n function listen(): void {\n unlisten?.();\n unlisten = null;\n const crossfilter = options.filterBy;\n const changed = () => {\n let next: Filter | undefined;\n try {\n next = crossfilter ? filterFor(crossfilter, self) : undefined;\n } catch (error) {\n fail(error);\n return;\n }\n if (sameFilter(next, filter)) return;\n filter = next;\n refilter();\n notify();\n };\n if (crossfilter) {\n crossfilter.addEventListener(\"value\", changed);\n unlisten = () => crossfilter.removeEventListener(\"value\", changed);\n }\n changed();\n }\n\n const store: GraphStore = {\n /**\n * The first subscriber starts listening to the crossfilter and the last one stops it and lets the\n * graph go — `QueryObserver`'s `onSubscribe`/`onUnsubscribe`, which is what survives StrictMode\n * mounting everything twice.\n */\n subscribe(listener) {\n listeners.add(listener);\n if (!active) {\n active = true;\n listen();\n // StrictMode unsubscribes and subscribes again: what the unsubscribe cancelled starts over.\n if (corpus && !failed && tables.length > 0) {\n if (!loading && (!geometry || !encoding)) load();\n if (!filtering && filter !== undefined && !kept) refilter();\n }\n if (held !== null) {\n const { error } = held;\n held = null;\n options.onFailure(error);\n }\n }\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0) store.destroy();\n };\n },\n getSnapshot: () => snapshot,\n getOptions: () => options,\n setOptions(next) {\n const previous = options;\n options = next;\n const nextBinding = bindingOf(next);\n const rebound =\n nextBinding.category !== binding.category ||\n nextBinding.byTable !== binding.byTable ||\n nextBinding.size !== binding.size ||\n next.categories !== previous.categories;\n binding = nextBinding;\n if (next.corpus !== previous.corpus) {\n adopt(next.corpus);\n if (active && next.filterBy !== previous.filterBy) listen();\n return;\n }\n if (active && next.filterBy !== previous.filterBy) listen();\n if (rebound) load();\n notify();\n },\n destroy() {\n active = false;\n unlisten?.();\n unlisten = null;\n loading?.abort();\n filtering?.abort();\n loading = filtering = null;\n listeners.clear();\n },\n select(vertices, source = \"node\", label = \"\") {\n const selection = vertices && vertices.length > 0 ? { vertices: [...vertices], source, label } : null;\n patch({ selection });\n options.onSelect?.(selection);\n const key = tables[0]?.key;\n if (options.filterBy && key) publish(options.filterBy, self, key, selection ? selection.vertices : null);\n },\n focus(vertex) {\n if (vertex === snapshot.focus) return;\n patch({ focus: vertex });\n options.onFocus?.(vertex);\n },\n hover(vertex) {\n if (vertex !== snapshot.hovered) patch({ hovered: vertex });\n },\n pin(vertices) {\n patch({ pinned: [...vertices] });\n },\n setTool(tool) {\n if (tool !== snapshot.tool) patch({ tool });\n },\n report(motion) {\n if (motion !== snapshot.motion) patch({ motion });\n },\n reportProgress(value) {\n if (value !== snapshot.progress) patch({ progress: value });\n },\n renderable() {\n if (!unrenderable) return;\n unrenderable = false;\n notify();\n },\n unrenderable(error) {\n unrenderable = true;\n fail(error);\n notify();\n },\n reportDrawn(drawnSnapshot) {\n const next = [drawnSnapshot.geometry, drawnSnapshot.encoding, drawnSnapshot.mask];\n if (next.every((part, i) => part === uploaded[i])) return;\n uploaded = next;\n notify();\n },\n };\n\n adopt(initial.corpus);\n building = false;\n return store;\n}\n"],"names":["sameFilter","a","b","_","v","isPromise","value","drawnOf","geometry","encoding","mask","tally","shown","vertices","id","rank","edges","links","i","createGraph","initial","options","listeners","self","graphClient","corpus","opening","failed","unrenderable","tables","binding","bindingOf","filter","loading","filtering","kept","uploaded","unlisten","active","building","held","fail","error","snapshot","domain","domainNow","key","part","domainOf","drawn","drawnNow","statusOf","notify","fields","sum","table","emit","patch","listener","run","current","set","fatal","read","done","_a","aborter","asLoad","asFilter","load","open","seed","given","signal","loadEncoding","next","loadGraph","maskOf","refilter","readKept","reopen","cleared","drawnTables","GraphError","adopt","promised","opened","listen","crossfilter","changed","filterFor","store","previous","nextBinding","rebound","source","label","selection","_b","publish","vertex","tool","motion","drawnSnapshot"],"mappings":";;;;;AAWA,MAAMA,KAAa,CAACC,GAAuBC,MACzC,KAAK,UAAUD,GAAG,CAACE,GAAGC,MAAgB,OAAOA,KAAM,WAAW,GAAGA,CAAC,MAAMA,CAAE,MAC1E,KAAK,UAAUF,GAAG,CAACC,GAAGC,MAAgB,OAAOA,KAAM,WAAW,GAAGA,CAAC,MAAMA,CAAE,GAEtEC,KAAY,CAACC,MACjB,QAAQA,KAAA,gBAAAA,EAAsC,SAAS;AAEzD,SAASC,GAAQC,GAAoBC,GAAoBC,GAAgC;AACvF,QAAMC,IAAQF,EAAS,OAAO,IAAI,MAAM,CAAC,GACnCG,IAAQ,IAAI,WAAWJ,EAAS,IAAI;AAC1C,MAAIK,IAAW;AACf,WAASC,IAAK,GAAGA,IAAKN,EAAS,MAAMM,KAAM;AACzC,QAAKJ,KAAQ,CAACA,EAAKI,CAAE,KAAM,OAAO,MAAMN,EAAS,UAAUM,IAAK,CAAC,CAAC,EAAG;AACrE,IAAAF,EAAME,CAAE,IAAI,GACZD;AACA,UAAME,IAAON,EAAS,MAAMK,CAAE;AAC9B,IAAAH,EAAMI,CAAI,KAAKJ,EAAMI,CAAI,KAAK,KAAK;AAAA,EACrC;AACA,MAAIC,IAAQ;AACZ,QAAM,EAAE,OAAAC,MAAUT;AAClB,WAASU,IAAI,GAAGA,IAAID,EAAM,QAAQC,KAAK;AACrC,IAAIN,EAAMK,EAAMC,CAAC,CAAW,KAAKN,EAAMK,EAAMC,IAAI,CAAC,CAAW,KAAGF;AAElE,SAAO,EAAE,UAAAH,GAAU,OAAAG,GAAO,QAAQP,EAAS,QAAQ,OAAAE,EAAA;AACrD;AAEO,SAASQ,GAAYC,GAAmC;AAC7D,MAAIC,IAAUD;AACd,QAAME,wBAAgB,IAAA,GAChBC,IAAqBC,EAAA;AAE3B,MAAIC,IAAwB,MACxBC,IAAsC,MACtCC,IAAS,IACTC,IAAe,IACfC,IAAiC,CAAA,GACjCC,IAAUC,EAAUX,CAAO,GAC3BY,GACAC,IAAkC,MAClCC,IAAoC,MACpC1B,IAA4B,MAC5BC,IAA4B,MAC5B0B,IAAoB,MACpBzB,IAA0B,MAC1B0B,IAA+B,CAAA,GAC/BC,IAAgC,MAChCC,IAAS,IAKTC,IAAW,IACXC,IAAkC;AACtC,QAAMC,IAAO,CAACC,MAAmB;AAC/B,IAAIH,IAAUC,IAAO,EAAE,OAAAE,EAAA,IAClBrB,EAAQ,UAAUqB,CAAK;AAAA,EAC9B;AAEA,MAAIC,IAA0B;AAAA,IAC5B,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ,CAAA;AAAA,IACR,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ,CAAA;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,SAAAtB;AAAA,IACA,QAAQ;AAAA,IACR,SAAAS;AAAA,IACA,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,EAAA,GAGJc,IAAwD,EAAE,KAAK,CAAA,GAAI,OAAO,CAAA,EAAC;AAC/E,WAASC,IAAgC;AACvC,UAAMC,IAAM,CAACjB,GAAQC,EAAQ,SAASA,EAAQ,UAAUT,EAAQ,UAAU;AAC1E,WAAIyB,EAAI,KAAK,CAACC,GAAM7B,MAAM6B,MAASH,EAAO,IAAI1B,CAAC,CAAC,MAAG0B,IAAS,EAAE,KAAAE,GAAK,OAAOE,EAASnB,GAAQC,GAAST,EAAQ,UAAU,EAAA,IAC/GuB,EAAO;AAAA,EAChB;AAEA,MAAIK,IAAiD,EAAE,KAAK,CAAA,GAAI,OAAO,KAAA;AACvE,WAASC,IAAyB;AAChC,UAAMJ,IAAM,CAACtC,GAAUC,GAAUC,CAAI;AACrC,WAAIoC,EAAI,KAAK,CAACC,GAAM7B,MAAM6B,MAASE,EAAM,IAAI/B,CAAC,CAAC,MAC7C+B,IAAQ,EAAE,KAAAH,GAAK,OAAOtC,KAAYC,IAAWF,GAAQC,GAAUC,GAAUC,CAAI,IAAI,KAAA,IAE5EuC,EAAM;AAAA,EACf;AAEA,WAASE,IAAwB;AAC/B,QAAIxB,KAAUC,EAAc,QAAO;AACnC,QAAIF,EAAS,QAAO;AACpB,QAAI,CAACD,EAAQ,QAAO;AAEpB,UAAMb,IAAQJ,MAAa,QADX,CAACA,GAAUC,GAAUC,CAAI,EACE,MAAM,CAACqC,GAAM7B,MAAM6B,MAASX,EAASlB,CAAC,CAAC;AAClF,WAAOe,KAAWC,KAAa,CAACtB,IAAQ,YAAY;AAAA,EACtD;AAEA,WAASwC,EAAOC,IAAiC,IAAU;AACzD,IAAAV,IAAW;AAAA,MACT,GAAGA;AAAA,MACH,OAAOlB,IAASI,EAAO,OAAO,CAACyB,GAAKC,MAAUD,IAAMC,EAAM,cAAc,CAAC,IAAI;AAAA,MAC7E,OAAOL,EAAA;AAAA,MACP,QAAQL,EAAA;AAAA,MACR,SAAAxB;AAAA,MACA,QAAAI;AAAA,MACA,SAAAK;AAAA,MACA,UAAAtB;AAAA,MACA,UAAAC;AAAA,MACA,MAAAC;AAAA,MACA,GAAG2C;AAAA,IAAA,GAELV,IAAW,EAAE,GAAGA,GAAU,QAAQQ,IAAS,GAC3CK,EAAA;AAAA,EACF;AAGA,WAASC,EAAMJ,GAAsC;AACnD,IAAAV,IAAW,EAAE,GAAGA,GAAU,GAAGU,EAAA,GAC7BG,EAAA;AAAA,EACF;AAEA,WAASA,IAAa;AACpB,eAAWE,KAAYpC,EAAW,CAAAoC,EAAA;AAAA,EACpC;AAMA,WAASC,EACPC,GACAC,GACAC,GACAC,GACAC,GACM;;AACN,KAAAC,IAAAL,EAAA,MAAA,QAAAK,EAAW;AACX,UAAMC,IAAU,IAAI,gBAAA;AACpB,IAAAL,EAAIK,CAAO,GACXH,EAAKG,EAAQ,MAAM,EAAE;AAAA,MACnB,CAAC5D,MAAU;AACT,QAAIsD,EAAA,MAAcM,MAClBL,EAAI,IAAI,GACRG,EAAK1D,CAAK,GACV8C,EAAA;AAAA,MACF;AAAA,MACA,CAACV,MAAmB;AAElB,QAAIkB,EAAA,MAAcM,KAAWA,EAAQ,OAAO,YAC5CL,EAAI,IAAI,GACRlC,UAAWmC,IACXrB,EAAKC,CAAK,GACVU,EAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AAEA,QAAMe,IAAS,CAAC,MAAMlC,GAAS,CAAChC,MAA+BgC,IAAUhC,GAAI,EAAI,GAC3EmE,IAAW,CAAC,MAAMlC,GAAW,CAACjC,MAA+BiC,IAAYjC,GAAI,EAAK;AAExF,WAASoE,IAAa;AACpB,UAAMC,IAAO7C;AACb,QAAI,CAAC6C,EAAM;AACX,UAAMC,IAAO1B,EAAA,GACP2B,IAAQhE;AACd,QAAIgE;AACF,aAAOb,EAAI,GAAGQ,GAAQ,CAACM,MAAWC,GAAaJ,GAAME,GAAO1C,GAASyC,GAAME,CAAM,GAAG,CAACE,MAAS;AAC5F,QAAAlE,IAAWkE;AAAA,MACb,CAAC;AAEH,IAAAhB,EAAI,GAAGQ,GAAQ,CAACM,MAAWG,GAAUN,GAAMxC,GAASyC,GAAME,CAAM,GAAG,CAACE,MAAS;AAC3E,MAAAnE,IAAWmE,EAAK,UAChBlE,IAAWkE,EAAK,UAChBjE,IAAOF,KAAY2B,IAAO0C,EAAOrE,GAAU2B,CAAI,IAAI;AAAA,IACrD,CAAC;AAAA,EACH;AAEA,WAAS2C,IAAiB;AACxB,IAAA5C,KAAA,QAAAA,EAAW,SACXA,IAAY;AACZ,UAAMoC,IAAO7C;AACb,QAAI,CAAC6C,KAAQzC,EAAO,WAAW,EAAG;AAClC,QAAIG,MAAW,QAAW;AACxB,MAAAG,IAAO,MACPzB,IAAO;AACP;AAAA,IACF;AACA,UAAM8D,IAAQxC;AACd,IAAA2B,EAAI,GAAGS,GAAU,CAACK,MAAWM,GAAST,GAAMzC,GAAQ2C,GAAOC,CAAM,GAAG,CAACE,MAAS;AAC5E,MAAAxC,IAAOwC,GACPjE,IAAOF,IAAWqE,EAAOrE,GAAUmE,CAAI,IAAI;AAAA,IAC7C,CAAC;AAAA,EACH;AAEA,WAASK,IAAe;AACtB,IAAA/C,KAAA,QAAAA,EAAS,SACTC,KAAA,QAAAA,EAAW,SACXD,IAAUC,IAAY,MACtBP,IAAS,IACTnB,IAAWC,IAAWC,IAAOyB,IAAO,MACpCC,IAAW,CAAA,GACXP,IAAS,CAAA;AACT,UAAMoD,IAAU,EAAE,WAAW,MAAM,OAAO,MAAM,SAAS,MAAM,QAAQ,GAAC;AACxE,QAAI,CAACxD,EAAQ,QAAO2B,EAAO6B,CAAO;AAClC,QAAI;AAEF,UADApD,IAASqD,GAAYzD,CAAM,GACvBI,EAAO,WAAW,SAAS,IAAIsD,EAAW,yBAAyB,uDAAuD;AAAA,IAChI,SAASzC,GAAO;AACd,aAAAf,IAAS,IACTc,EAAKC,CAAK,GACHU,EAAO6B,CAAO;AAAA,IACvB;AACA,IAAAZ,EAAA,GACAS,EAAA,GACA1B,EAAO6B,CAAO;AAAA,EAChB;AAGA,WAASG,EAAMZ,GAAqC;AAGlD,QAFA/C,IAAS,MACTC,IAAUrB,GAAUmE,CAAK,IAAIA,IAAQ,MACjC,CAAC9C;AACH,aAAAD,IAAS+C,GACFQ,EAAA;AAET,UAAMK,IAAW3D;AACjB,IAAAsD,EAAA,GACAK,EAAS;AAAA,MACP,CAACC,MAAW;AACV,QAAI5D,MAAY2D,MAChB3D,IAAU,MACVD,IAAS6D,GACTN,EAAA;AAAA,MACF;AAAA,MACA,CAACtC,MAAmB;AAClB,QAAIhB,MAAY2D,MAChB3D,IAAU,MACVC,IAAS,IACTc,EAAKC,CAAK,GACVU,EAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AAEA,WAASmC,IAAe;AACtB,IAAAlD,KAAA,QAAAA,KACAA,IAAW;AACX,UAAMmD,IAAcnE,EAAQ,UACtBoE,IAAU,MAAM;AACpB,UAAId;AACJ,UAAI;AACF,QAAAA,IAAOa,IAAcE,GAAUF,GAAajE,CAAI,IAAI;AAAA,MACtD,SAASmB,GAAO;AACd,QAAAD,EAAKC,CAAK;AACV;AAAA,MACF;AACA,MAAI1C,GAAW2E,GAAM3C,CAAM,MAC3BA,IAAS2C,GACTG,EAAA,GACA1B,EAAA;AAAA,IACF;AACA,IAAIoC,MACFA,EAAY,iBAAiB,SAASC,CAAO,GAC7CpD,IAAW,MAAMmD,EAAY,oBAAoB,SAASC,CAAO,IAEnEA,EAAA;AAAA,EACF;AAEA,QAAME,IAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMxB,UAAUjC,GAAU;AAElB,UADApC,EAAU,IAAIoC,CAAQ,GAClB,CAACpB,MACHA,IAAS,IACTiD,EAAA,GAEI9D,KAAU,CAACE,KAAUE,EAAO,SAAS,MACnC,CAACI,MAAY,CAACzB,KAAY,CAACC,MAAW4D,EAAA,GACtC,CAACnC,KAAaF,MAAW,UAAa,CAACG,KAAM2C,EAAA,IAE/CtC,MAAS,OAAM;AACjB,cAAM,EAAE,OAAAE,MAAUF;AAClB,QAAAA,IAAO,MACPnB,EAAQ,UAAUqB,CAAK;AAAA,MACzB;AAEF,aAAO,MAAM;AACX,QAAApB,EAAU,OAAOoC,CAAQ,GACrBpC,EAAU,SAAS,KAAGqE,EAAM,QAAA;AAAA,MAClC;AAAA,IACF;AAAA,IACA,aAAa,MAAMhD;AAAA,IACnB,YAAY,MAAMtB;AAAA,IAClB,WAAWsD,GAAM;AACf,YAAMiB,IAAWvE;AACjB,MAAAA,IAAUsD;AACV,YAAMkB,IAAc9D,EAAU4C,CAAI,GAC5BmB,IACJD,EAAY,aAAa/D,EAAQ,YACjC+D,EAAY,YAAY/D,EAAQ,WAChC+D,EAAY,SAAS/D,EAAQ,QAC7B6C,EAAK,eAAeiB,EAAS;AAE/B,UADA9D,IAAU+D,GACNlB,EAAK,WAAWiB,EAAS,QAAQ;AACnC,QAAAR,EAAMT,EAAK,MAAM,GACbrC,KAAUqC,EAAK,aAAaiB,EAAS,YAAUL,EAAA;AACnD;AAAA,MACF;AACA,MAAIjD,KAAUqC,EAAK,aAAaiB,EAAS,YAAUL,EAAA,GAC/CO,KAASzB,EAAA,GACbjB,EAAA;AAAA,IACF;AAAA,IACA,UAAU;AACR,MAAAd,IAAS,IACTD,KAAA,QAAAA,KACAA,IAAW,MACXJ,KAAA,QAAAA,EAAS,SACTC,KAAA,QAAAA,EAAW,SACXD,IAAUC,IAAY,MACtBZ,EAAU,MAAA;AAAA,IACZ;AAAA,IACA,OAAOT,GAAUkF,IAAS,QAAQC,IAAQ,IAAI;;AAC5C,YAAMC,IAAYpF,KAAYA,EAAS,SAAS,IAAI,EAAE,UAAU,CAAC,GAAGA,CAAQ,GAAG,QAAAkF,GAAQ,OAAAC,MAAU;AACjG,MAAAvC,EAAM,EAAE,WAAAwC,GAAW,IACnBhC,IAAA5C,EAAQ,aAAR,QAAA4C,EAAA,KAAA5C,GAAmB4E;AACnB,YAAMnD,KAAMoD,IAAArE,EAAO,CAAC,MAAR,gBAAAqE,EAAW;AACvB,MAAI7E,EAAQ,YAAYyB,KAAKqD,GAAQ9E,EAAQ,UAAUE,GAAMuB,GAAKmD,IAAYA,EAAU,WAAW,IAAI;AAAA,IACzG;AAAA,IACA,MAAMG,GAAQ;;AACZ,MAAIA,MAAWzD,EAAS,UACxBc,EAAM,EAAE,OAAO2C,GAAQ,IACvBnC,IAAA5C,EAAQ,YAAR,QAAA4C,EAAA,KAAA5C,GAAkB+E;AAAA,IACpB;AAAA,IACA,MAAMA,GAAQ;AACZ,MAAIA,MAAWzD,EAAS,aAAe,EAAE,SAASyD,GAAQ;AAAA,IAC5D;AAAA,IACA,IAAIvF,GAAU;AACZ,MAAA4C,EAAM,EAAE,QAAQ,CAAC,GAAG5C,CAAQ,GAAG;AAAA,IACjC;AAAA,IACA,QAAQwF,GAAM;AACZ,MAAIA,MAAS1D,EAAS,QAAMc,EAAM,EAAE,MAAA4C,GAAM;AAAA,IAC5C;AAAA,IACA,OAAOC,GAAQ;AACb,MAAIA,MAAW3D,EAAS,UAAQc,EAAM,EAAE,QAAA6C,GAAQ;AAAA,IAClD;AAAA,IACA,eAAehG,GAAO;AACpB,MAAIA,MAAUqC,EAAS,cAAgB,EAAE,UAAUrC,GAAO;AAAA,IAC5D;AAAA,IACA,aAAa;AACX,MAAKsB,MACLA,IAAe,IACfwB,EAAA;AAAA,IACF;AAAA,IACA,aAAaV,GAAO;AAClB,MAAAd,IAAe,IACfa,EAAKC,CAAK,GACVU,EAAA;AAAA,IACF;AAAA,IACA,YAAYmD,GAAe;AACzB,YAAM5B,IAAO,CAAC4B,EAAc,UAAUA,EAAc,UAAUA,EAAc,IAAI;AAChF,MAAI5B,EAAK,MAAM,CAAC5B,GAAM7B,MAAM6B,MAASX,EAASlB,CAAC,CAAC,MAChDkB,IAAWuC,GACXvB,EAAA;AAAA,IACF;AAAA,EAAA;AAGF,SAAAgC,EAAMhE,EAAQ,MAAM,GACpBmB,IAAW,IACJoD;AACT;"}
|
|
1
|
+
{"version":3,"file":"store.js","sources":["../../src/core/store.ts"],"sourcesContent":["import type { Coordinator } from \"@kanzo-tech/mosaic\";\nimport { domainOf } from \"./categories\";\nimport { bindingOf } from \"./channels\";\nimport { GraphClient, publish } from \"./client\";\nimport { GraphError } from \"./error\";\nimport { loadEncoding, loadGeometry, type Encoding, type Geometry } from \"./load\";\nimport { readStructure, type Structure } from \"./source\";\nimport type { Drawn, GraphOptions, GraphSnapshot, GraphStatus, GraphStore } from \"./state\";\n\nexport type { Drawn, GraphOptions, GraphSnapshot, GraphState, GraphStatus, GraphStore } from \"./state\";\n\nfunction drawnOf(geometry: Geometry, encoding: Encoding, mask: Uint8Array | null): Drawn {\n const tally = encoding.domain.map(() => 0);\n const shown = new Uint8Array(geometry.size);\n let vertices = 0;\n for (let id = 0; id < geometry.size; id++) {\n if ((mask && !mask[id]) || Number.isNaN(geometry.positions[id * 2])) continue;\n shown[id] = 1;\n vertices++;\n const rank = encoding.ranks[id] as number;\n tally[rank] = (tally[rank] ?? 0) + 1;\n }\n let edges = 0;\n const { links } = geometry;\n for (let i = 0; i < links.length; i += 2) {\n if (shown[links[i] as number] && shown[links[i + 1] as number]) edges++;\n }\n return { vertices, edges, domain: encoding.domain, tally };\n}\n\n/** `1` where a vertex is among `ids`. */\nfunction maskOf(size: number, ids: Float64Array): Uint8Array {\n const mask = new Uint8Array(size);\n for (const id of ids) if (id < size) mask[id] = 1;\n return mask;\n}\n\nexport function createGraph(initial: GraphOptions): GraphStore {\n let options = initial;\n const listeners = new Set<() => void>();\n\n let failed = false;\n let unrenderable = false;\n let binding = bindingOf(initial);\n let structure: Structure | null = null;\n let geometry: Geometry | null = null;\n let encoding: Encoding | null = null;\n let kept: Float64Array | null = null;\n let mask: Uint8Array | null = null;\n let uploaded: readonly unknown[] = [];\n /** One read per kind in flight; a newer one makes an older one's answer stale. */\n const reading = { structure: 0, geometry: 0, encoding: 0 };\n const pending = { structure: false, geometry: false, encoding: false };\n let client: GraphClient | null = null;\n let connected: Coordinator | null = null;\n let active = false;\n\n // A failure found while the store is being built is found while React is still rendering —\n // `useGraph` builds it in `useState` — and a host's `onFailure` is usually a `setState`. It is held\n // and reported to the first subscriber, which arrives in the commit phase.\n let building = true;\n let held: { error: unknown } | null = null;\n const fail = (error: unknown) => {\n if (building) held = { error };\n else options.onFailure(error);\n };\n\n let snapshot: GraphSnapshot = {\n status: \"none\",\n total: undefined,\n drawn: null,\n domain: [],\n selection: null,\n focus: null,\n hovered: null,\n pinned: [],\n tool: null,\n motion: \"settled\",\n progress: 1,\n options,\n structure: null,\n binding,\n geometry: null,\n encoding: null,\n mask: null,\n };\n\n let domain: { key: unknown[]; value: readonly unknown[] } = { key: [], value: [] };\n function domainNow(): readonly unknown[] {\n const tables = structure?.vertices ?? [];\n const key = [tables, binding.byTable, binding.category, options.categories];\n if (key.some((part, i) => part !== domain.key[i])) domain = { key, value: domainOf(tables, binding, options.categories) };\n return domain.value;\n }\n\n let drawn: { key: unknown[]; value: Drawn | null } = { key: [], value: null };\n function drawnNow(): Drawn | null {\n const key = [geometry, encoding, mask];\n if (key.some((part, i) => part !== drawn.key[i])) {\n drawn = { key, value: geometry && encoding ? drawnOf(geometry, encoding, mask) : null };\n }\n return drawn.value;\n }\n\n function statusOf(): GraphStatus {\n if (failed || unrenderable) return \"failed\";\n if (options.from === null || options.coordinator === null) return \"none\";\n const current = [geometry, encoding, mask];\n const shown = geometry !== null && current.every((part, i) => part === uploaded[i]);\n return pending.structure || pending.geometry || pending.encoding || !shown ? \"loading\" : \"idle\";\n }\n\n function notify(fields: Partial<GraphSnapshot> = {}): void {\n snapshot = {\n ...snapshot,\n total: structure?.size,\n drawn: drawnNow(),\n domain: domainNow(),\n options,\n structure,\n binding,\n geometry,\n encoding,\n mask,\n ...fields,\n };\n snapshot = { ...snapshot, status: statusOf() };\n emit();\n }\n\n /** A change of state only — hover, focus, selection, tool, motion — derives nothing. */\n function patch(fields: Partial<GraphSnapshot>): void {\n snapshot = { ...snapshot, ...fields };\n emit();\n }\n\n function emit(): void {\n for (const listener of listeners) listener();\n }\n\n /**\n * Read `kind`, and keep the answer only if no newer read of the same kind started meanwhile. The\n * coordinator cannot be told to stop a statement, so a stale answer is dropped rather than aborted.\n */\n function read<T>(kind: keyof typeof reading, ask: () => Promise<T>, done: (value: T) => void): void {\n const ticket = ++reading[kind];\n pending[kind] = true;\n ask().then(\n (value) => {\n if (reading[kind] !== ticket) return;\n pending[kind] = false;\n done(value);\n notify();\n },\n (error: unknown) => {\n if (reading[kind] !== ticket) return;\n pending[kind] = false;\n failed = true;\n fail(error);\n notify();\n },\n );\n }\n\n function loadStructure(): void {\n const { coordinator, from } = options;\n if (coordinator === null || from === null) return;\n read(\"structure\", () => readStructure(coordinator, from), (next) => {\n if (next.size === 0) {\n failed = true;\n fail(new GraphError(\"graph/nothing-to-draw\", `the corpus attached as ${from} has no vertex`));\n return;\n }\n structure = next;\n loadPositions();\n client?.requestQuery();\n });\n }\n\n function loadPositions(): void {\n const { coordinator } = options;\n const given = structure;\n if (coordinator === null || given === null) return;\n read(\"geometry\", () => loadGeometry(coordinator, given, binding), (next) => {\n geometry = next;\n mask = kept ? maskOf(next.size, kept) : null;\n loadChannels();\n });\n }\n\n function loadChannels(): void {\n const { coordinator } = options;\n const given = geometry;\n if (coordinator === null || given === null) return;\n const seed = domainNow();\n read(\"encoding\", () => loadEncoding(coordinator, given, binding, seed), (next) => {\n encoding = next;\n });\n }\n\n function reset(): void {\n for (const kind of Object.keys(reading) as (keyof typeof reading)[]) {\n reading[kind]++;\n pending[kind] = false;\n }\n failed = false;\n structure = geometry = encoding = null;\n kept = mask = null;\n uploaded = [];\n notify({ selection: null, focus: null, hovered: null, pinned: [] });\n loadStructure();\n }\n\n /** The graph's Mosaic client, connected to the coordinator while anything is subscribed. */\n function connect(): void {\n disconnect();\n const { coordinator, filterBy } = options;\n if (coordinator === null) return;\n client = new GraphClient(\n filterBy,\n () => structure,\n (ids) => {\n kept = ids;\n mask = ids && geometry ? maskOf(geometry.size, ids) : null;\n notify();\n },\n (error) => fail(error),\n );\n coordinator.connect(client);\n connected = coordinator;\n }\n\n function disconnect(): void {\n if (client && connected) connected.disconnect(client);\n client = null;\n connected = null;\n }\n\n const store: GraphStore = {\n /**\n * The first subscriber connects the client to the coordinator, and the last one disconnects it\n * and lets the graph go — `QueryObserver`'s `onSubscribe`/`onUnsubscribe`, which is what\n * survives StrictMode mounting everything twice.\n */\n subscribe(listener) {\n listeners.add(listener);\n if (!active) {\n active = true;\n connect();\n if (held !== null) {\n const { error } = held;\n held = null;\n options.onFailure(error);\n }\n }\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0) store.destroy();\n };\n },\n getSnapshot: () => snapshot,\n getOptions: () => options,\n setOptions(next) {\n const previous = options;\n options = next;\n const before = binding;\n binding = bindingOf(next);\n if (next.from !== previous.from || next.coordinator !== previous.coordinator) {\n if (active && next.coordinator !== previous.coordinator) connect();\n return reset();\n }\n if (active && next.filterBy !== previous.filterBy) connect();\n if (binding.x !== before.x || binding.y !== before.y) loadPositions();\n else if (\n binding.category !== before.category ||\n binding.byTable !== before.byTable ||\n binding.size !== before.size ||\n binding.cluster !== before.cluster ||\n next.categories !== previous.categories\n ) {\n loadChannels();\n }\n notify();\n },\n destroy() {\n active = false;\n disconnect();\n listeners.clear();\n },\n select(vertices, source = \"external\", label = \"\") {\n const selection = vertices && vertices.length > 0 ? { vertices: [...vertices], source, label } : null;\n patch({ selection });\n options.onSelect?.(selection);\n if (options.filterBy && client) publish(options.filterBy, client, selection ? selection.vertices : null);\n },\n focus(vertex) {\n if (vertex === snapshot.focus) return;\n patch({ focus: vertex });\n options.onFocus?.(vertex);\n },\n hover(vertex) {\n if (vertex !== snapshot.hovered) patch({ hovered: vertex });\n },\n pin(vertices) {\n patch({ pinned: [...vertices] });\n },\n setTool(tool) {\n if (tool !== snapshot.tool) patch({ tool });\n },\n report(motion) {\n if (motion !== snapshot.motion) patch({ motion });\n },\n reportProgress(value) {\n if (value !== snapshot.progress) patch({ progress: value });\n },\n renderable() {\n if (!unrenderable) return;\n unrenderable = false;\n notify();\n },\n unrenderable(error) {\n unrenderable = true;\n fail(error);\n notify();\n },\n reportDrawn(drawnSnapshot) {\n const next = [drawnSnapshot.geometry, drawnSnapshot.encoding, drawnSnapshot.mask];\n if (next.every((part, i) => part === uploaded[i])) return;\n uploaded = next;\n notify();\n },\n };\n\n loadStructure();\n notify();\n building = false;\n return store;\n}\n"],"names":["drawnOf","geometry","encoding","mask","tally","shown","vertices","id","rank","edges","links","i","maskOf","size","ids","createGraph","initial","options","listeners","failed","unrenderable","binding","bindingOf","structure","kept","uploaded","reading","pending","client","connected","active","building","held","fail","error","snapshot","domain","domainNow","tables","key","part","domainOf","drawn","drawnNow","statusOf","notify","fields","emit","patch","listener","read","kind","ask","done","ticket","value","loadStructure","coordinator","from","readStructure","next","GraphError","loadPositions","given","loadGeometry","loadChannels","seed","loadEncoding","reset","connect","disconnect","filterBy","GraphClient","store","previous","before","source","label","selection","_a","publish","vertex","tool","motion","drawnSnapshot"],"mappings":"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"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -30,10 +30,12 @@ export type Tool = "rect" | "lasso" | null;
|
|
|
30
30
|
/** `settled` converged on its own; `paused` is waiting for you. */
|
|
31
31
|
export type Motion = "running" | "settled" | "paused";
|
|
32
32
|
/**
|
|
33
|
-
* Where a selection came from
|
|
34
|
-
*
|
|
33
|
+
* Where a selection came from: one of the canvas's own gestures, or `"external"` — a selection the
|
|
34
|
+
* host set through `select`, from a panel of its own. An external selection's identity is its
|
|
35
|
+
* `label`, which is how `GraphSelect` knows the live selection is the one it made. The graph names
|
|
36
|
+
* no host's panels here: a source per panel would be a host's vocabulary in the renderer's type.
|
|
35
37
|
*/
|
|
36
|
-
export type SelectionSource = "marquee" | "lasso" | "node" | "
|
|
38
|
+
export type SelectionSource = "marquee" | "lasso" | "node" | "external";
|
|
37
39
|
/**
|
|
38
40
|
* The selection — one value, published once.
|
|
39
41
|
*
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B;;;;;;GAMG;AACH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE3C,mEAAmE;AACnE,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtD
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B;;;;;;GAMG;AACH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE3C,mEAAmE;AACnE,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,GAAG,IAAI,IAAI,CAAC;IACZ,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;IAChB,qGAAqG;IACrG,KAAK,IAAI,IAAI,CAAC;IACd,oCAAoC;IACpC,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B,wDAAwD;IACxD,cAAc,IAAI,IAAI,CAAC;IACvB,KAAK,IAAI,IAAI,CAAC;CACf"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* `useGraphState`, TanStack Store's selector, because the api is commands and the state moves at
|
|
14
14
|
* frame rate.
|
|
15
15
|
* - `parts/` — `GraphCanvas`, `GraphLegend`, `GraphCounts`, `GraphToolbar`, `GraphInspector`,
|
|
16
|
-
* `GraphSearch`: flat parts over the one context; and `GraphLooks`, the picture's preferences,
|
|
16
|
+
* `GraphSearch`, `GraphSelect`: flat parts over the one context; and `GraphLooks`, the picture's preferences,
|
|
17
17
|
* which needs only the theme provider. They own the vocabulary; the root's callbacks are the host's policy.
|
|
18
18
|
*
|
|
19
19
|
* **Why a package and not `@kanzo-tech/ui`.** The first admission rule is *domain-free — nothing
|
|
@@ -30,6 +30,7 @@ export { GraphCounts, type GraphCountsProps } from './parts/graph-counts';
|
|
|
30
30
|
export { GraphToolbar, type GraphToolbarProps } from './parts/graph-toolbar';
|
|
31
31
|
export { GraphInspector, type GraphInspectorProps } from './parts/graph-inspector';
|
|
32
32
|
export { GraphSearch, type GraphSearchProps } from './parts/graph-search';
|
|
33
|
+
export { GraphSelect, type GraphSelectProps } from './parts/graph-select';
|
|
33
34
|
export { GraphLooks, type GraphLooksProps } from './parts/graph-looks';
|
|
34
35
|
export { ShapeGlyph, type ShapeGlyphProps } from './parts/shape-glyph';
|
|
35
36
|
export { lookFrom, type Look, type LookPatch, type LookPreset, type Shape } from './render/graph-looks';
|
|
@@ -38,6 +39,6 @@ export { scaleOf } from './render/graph-model';
|
|
|
38
39
|
export type { Channels } from './core/channels';
|
|
39
40
|
export type { GraphCommands, Motion, Selection, SelectionSource, Tool, VertexId } from './core/types';
|
|
40
41
|
export type { Drawn, GraphState, GraphStatus } from './core/state';
|
|
41
|
-
export type { VertexDetail } from './core/
|
|
42
|
+
export type { VertexDetail } from './core/source';
|
|
42
43
|
export { GraphError } from './core/error';
|
|
43
44
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,sBAAsB,GAC5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAIvE,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,YAAY,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACtG,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,sBAAsB,GAC5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAIvE,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,YAAY,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACtG,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,33 +2,35 @@ import { GraphRoot as p, GraphRootProvider as e, useGraphContext as t } from "./
|
|
|
2
2
|
import { useGraph as m } from "./react/use-graph.js";
|
|
3
3
|
import { useGraphState as h } from "./react/use-graph-state.js";
|
|
4
4
|
import { useGraphPrefs as G } from "./react/use-graph-prefs.js";
|
|
5
|
-
import { GraphCanvas as
|
|
6
|
-
import { GraphLegend as
|
|
7
|
-
import { GraphCounts as
|
|
5
|
+
import { GraphCanvas as l } from "./parts/graph-canvas.js";
|
|
6
|
+
import { GraphLegend as u } from "./parts/graph-legend.js";
|
|
7
|
+
import { GraphCounts as S } from "./parts/graph-counts.js";
|
|
8
8
|
import { GraphToolbar as d } from "./parts/graph-toolbar.js";
|
|
9
9
|
import { GraphInspector as k } from "./parts/graph-inspector.js";
|
|
10
10
|
import { GraphSearch as F } from "./parts/graph-search.js";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
11
|
+
import { GraphSelect as P } from "./parts/graph-select.js";
|
|
12
|
+
import { GraphLooks as b } from "./parts/graph-looks.js";
|
|
13
|
+
import { ShapeGlyph as y } from "./parts/shape-glyph.js";
|
|
14
|
+
import { lookFrom as I } from "./render/graph-looks.js";
|
|
15
|
+
import { simFrom as T } from "./render/graph-sim.js";
|
|
16
|
+
import { scaleOf as q } from "./render/graph-model.js";
|
|
17
|
+
import { GraphError as z } from "./core/error.js";
|
|
17
18
|
export {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
l as GraphCanvas,
|
|
20
|
+
S as GraphCounts,
|
|
21
|
+
z as GraphError,
|
|
21
22
|
k as GraphInspector,
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
u as GraphLegend,
|
|
24
|
+
b as GraphLooks,
|
|
24
25
|
p as GraphRoot,
|
|
25
26
|
e as GraphRootProvider,
|
|
26
27
|
F as GraphSearch,
|
|
28
|
+
P as GraphSelect,
|
|
27
29
|
d as GraphToolbar,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
y as ShapeGlyph,
|
|
31
|
+
I as lookFrom,
|
|
32
|
+
q as scaleOf,
|
|
33
|
+
T as simFrom,
|
|
32
34
|
m as useGraph,
|
|
33
35
|
t as useGraphContext,
|
|
34
36
|
G as useGraphPrefs,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-canvas.d.ts","sourceRoot":"","sources":["../../src/parts/graph-canvas.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAe1F,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IACnE,oFAAoF;IACpF,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"graph-canvas.d.ts","sourceRoot":"","sources":["../../src/parts/graph-canvas.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAe1F,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IACnE,oFAAoF;IACpF,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAmDD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB,+BAgJnF"}
|