@kanzo-tech/graph 0.18.0 → 0.19.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,26 +1,26 @@
1
- import { domainOf as Y } from "./categories.js";
2
- import { bindingOf as Q } from "./channels.js";
3
- import { graphClient as Z, publish as x, filterFor as ee } from "./filter.js";
4
- import { drawnTables as ne, loadEncoding as te, loadGraph as re, maskOf as U, readKept as oe } from "./load.js";
5
- const le = (a, r) => JSON.stringify(a, (m, s) => typeof s == "bigint" ? `${s}n` : s) === JSON.stringify(r, (m, s) => typeof s == "bigint" ? `${s}n` : s), ie = (a) => typeof (a == null ? void 0 : a.then) == "function";
1
+ import { GraphError as Y } from "./error.js";
2
+ import { domainOf as Z } from "./categories.js";
3
+ import { bindingOf as R } from "./channels.js";
4
+ import { graphClient as x, publish as ee, filterFor as ne } from "./filter.js";
5
+ import { drawnTables as te, loadEncoding as re, loadGraph as oe, maskOf as U, readKept as le } from "./load.js";
6
+ const ie = (a, r) => JSON.stringify(a, (m, i) => typeof i == "bigint" ? `${i}n` : i) === JSON.stringify(r, (m, i) => typeof i == "bigint" ? `${i}n` : i), ue = (a) => typeof (a == null ? void 0 : a.then) == "function";
6
7
  function se(a, r, m) {
7
- const s = r.domain.map(() => 0);
8
- let l = 0;
9
- for (let u = 0; u < a.size; u++) {
10
- if (m && !m[u] || Number.isNaN(a.positions[u * 2])) continue;
11
- l++;
12
- const h = r.ranks[u];
13
- s[h] = (s[h] ?? 0) + 1;
8
+ const i = r.domain.map(() => 0);
9
+ let u = 0;
10
+ for (let s = 0; s < a.size; s++) {
11
+ if (m && !m[s] || Number.isNaN(a.positions[s * 2])) continue;
12
+ u++;
13
+ const b = r.ranks[s];
14
+ i[b] = (i[b] ?? 0) + 1;
14
15
  }
15
- return { vertices: l, domain: r.domain, tally: s };
16
+ return { vertices: u, domain: r.domain, tally: i };
16
17
  }
17
- function de(a) {
18
+ function ye(a) {
18
19
  let r = a;
19
- const m = /* @__PURE__ */ new Set(), s = Z();
20
- let l = null, u = null, h = !1, _ = !1, y = [], p = Q(a), N, c = null, i = null, f = null, b = null, B = null, v = null, T = [], w = null, E = !1, R = !0, z = null;
21
- const S = (e) => {
22
- const n = e instanceof Error ? e.message : String(e);
23
- R ? z = n : r.onFailure(n);
20
+ const m = /* @__PURE__ */ new Set(), i = x();
21
+ let u = null, s = null, b = !1, E = !1, g = [], p = R(a), N, c = null, l = null, f = null, h = null, B = null, w = null, G = [], v = null, F = !1, j = !0, L = null;
22
+ const T = (e) => {
23
+ j ? L = { error: e } : r.onFailure(e);
24
24
  };
25
25
  let d = {
26
26
  status: "none",
@@ -40,135 +40,134 @@ function de(a) {
40
40
  geometry: null,
41
41
  encoding: null,
42
42
  mask: null
43
- }, $ = { key: [], value: [] };
44
- function j() {
45
- const e = [y, p.byTable, p.category, r.categories];
46
- return e.some((n, t) => n !== $.key[t]) && ($ = { key: e, value: Y(y, p, r.categories) }), $.value;
43
+ }, _ = { key: [], value: [] };
44
+ function q() {
45
+ const e = [g, p.byTable, p.category, r.categories];
46
+ return e.some((n, t) => n !== _.key[t]) && (_ = { key: e, value: Z(g, p, r.categories) }), _.value;
47
47
  }
48
48
  let C = { key: [], value: null };
49
49
  function V() {
50
- const e = [f, b, v];
51
- return e.some((n, t) => n !== C.key[t]) && (C = { key: e, value: f && b ? se(f, b, v) : null }), C.value;
50
+ const e = [f, h, w];
51
+ return e.some((n, t) => n !== C.key[t]) && (C = { key: e, value: f && h ? se(f, h, w) : null }), C.value;
52
52
  }
53
53
  function W() {
54
- if (h || _) return "failed";
55
- if (u) return "opening";
56
- if (!l) return "none";
57
- const n = f !== null && [f, b, v].every((t, o) => t === T[o]);
58
- return c || i || !n ? "loading" : "idle";
54
+ if (b || E) return "failed";
55
+ if (s) return "opening";
56
+ if (!u) return "none";
57
+ const n = f !== null && [f, h, w].every((t, o) => t === G[o]);
58
+ return c || l || !n ? "loading" : "idle";
59
59
  }
60
- function g(e = {}) {
60
+ function y(e = {}) {
61
61
  d = {
62
62
  ...d,
63
- total: l ? y.reduce((n, t) => n + t.record_count, 0) : void 0,
63
+ total: u ? g.reduce((n, t) => n + t.record_count, 0) : void 0,
64
64
  drawn: V(),
65
- domain: j(),
65
+ domain: q(),
66
66
  options: r,
67
- corpus: l,
67
+ corpus: u,
68
68
  binding: p,
69
69
  geometry: f,
70
- encoding: b,
71
- mask: v,
70
+ encoding: h,
71
+ mask: w,
72
72
  ...e
73
- }, d = { ...d, status: W() }, q();
73
+ }, d = { ...d, status: W() }, H();
74
74
  }
75
75
  function O(e) {
76
- d = { ...d, ...e }, q();
76
+ d = { ...d, ...e }, H();
77
77
  }
78
- function q() {
78
+ function H() {
79
79
  for (const e of m) e();
80
80
  }
81
- function G(e, n, t, o, L) {
82
- var F;
83
- (F = e()) == null || F.abort();
81
+ function J(e, n, t, o, S) {
82
+ var z;
83
+ (z = e()) == null || z.abort();
84
84
  const k = new AbortController();
85
85
  n(k), o(k.signal).then(
86
86
  (K) => {
87
- e() === k && (n(null), L(K), g());
87
+ e() === k && (n(null), S(K), y());
88
88
  },
89
89
  (K) => {
90
- e() !== k || k.signal.aborted || (n(null), h || (h = t), S(K), g());
90
+ e() !== k || k.signal.aborted || (n(null), b || (b = t), T(K), y());
91
91
  }
92
92
  );
93
93
  }
94
- const H = [() => c, (e) => c = e, !0], X = [() => i, (e) => i = e, !1];
95
- function J() {
96
- const e = l;
94
+ const I = [() => c, (e) => c = e, !0], X = [() => l, (e) => l = e, !1];
95
+ function P() {
96
+ const e = u;
97
97
  if (!e) return;
98
- const n = j(), t = f;
98
+ const n = q(), t = f;
99
99
  if (t)
100
- return G(...H, (o) => te(e, t, p, n, o), (o) => {
101
- b = o;
100
+ return J(...I, (o) => re(e, t, p, n, o), (o) => {
101
+ h = o;
102
102
  });
103
- G(...H, (o) => re(e, p, n, o), (o) => {
104
- f = o.geometry, b = o.encoding, v = f && B ? U(f, B) : null;
103
+ J(...I, (o) => oe(e, p, n, o), (o) => {
104
+ f = o.geometry, h = o.encoding, w = f && B ? U(f, B) : null;
105
105
  });
106
106
  }
107
- function P() {
108
- i == null || i.abort(), i = null;
109
- const e = l;
110
- if (!e || y.length === 0) return;
107
+ function $() {
108
+ l == null || l.abort(), l = null;
109
+ const e = u;
110
+ if (!e || g.length === 0) return;
111
111
  if (N === void 0) {
112
- B = null, v = null;
112
+ B = null, w = null;
113
113
  return;
114
114
  }
115
115
  const n = N;
116
- G(...X, (t) => oe(e, y, n, t), (t) => {
117
- B = t, v = f ? U(f, t) : null;
116
+ J(...X, (t) => le(e, g, n, t), (t) => {
117
+ B = t, w = f ? U(f, t) : null;
118
118
  });
119
119
  }
120
120
  function A() {
121
- c == null || c.abort(), i == null || i.abort(), c = i = null, h = !1, f = b = v = B = null, T = [], y = [];
121
+ c == null || c.abort(), l == null || l.abort(), c = l = null, b = !1, f = h = w = B = null, G = [], g = [];
122
122
  const e = { selection: null, focus: null, hovered: null, pinned: [] };
123
- if (!l) return g(e);
123
+ if (!u) return y(e);
124
124
  try {
125
- if (l.manifest.format !== "fossil/1") throw new Error(`the graph reads fossil/1, and this corpus is ${l.manifest.format}`);
126
- if (y = ne(l), y.length === 0) throw new Error("the corpus has no vertex type with a position to draw");
125
+ if (g = te(u), g.length === 0) throw new Y("graph/nothing-to-draw", "the corpus has no vertex type with a position to draw");
127
126
  } catch (n) {
128
- return h = !0, S(n), g(e);
127
+ return b = !0, T(n), y(e);
129
128
  }
130
- J(), P(), g(e);
129
+ P(), $(), y(e);
131
130
  }
132
- function I(e) {
133
- if (l = null, u = ie(e) ? e : null, !u)
134
- return l = e, A();
135
- const n = u;
131
+ function M(e) {
132
+ if (u = null, s = ue(e) ? e : null, !s)
133
+ return u = e, A();
134
+ const n = s;
136
135
  A(), n.then(
137
136
  (t) => {
138
- u === n && (u = null, l = t, A());
137
+ s === n && (s = null, u = t, A());
139
138
  },
140
139
  (t) => {
141
- u === n && (u = null, h = !0, S(t), g());
140
+ s === n && (s = null, b = !0, T(t), y());
142
141
  }
143
142
  );
144
143
  }
145
144
  function D() {
146
- w == null || w(), w = null;
145
+ v == null || v(), v = null;
147
146
  const e = r.filterBy, n = () => {
148
147
  let t;
149
148
  try {
150
- t = e ? ee(e, s) : void 0;
149
+ t = e ? ne(e, i) : void 0;
151
150
  } catch (o) {
152
- S(o);
151
+ T(o);
153
152
  return;
154
153
  }
155
- le(t, N) || (N = t, P(), g());
154
+ ie(t, N) || (N = t, $(), y());
156
155
  };
157
- e && (e.addEventListener("value", n), w = () => e.removeEventListener("value", n)), n();
156
+ e && (e.addEventListener("value", n), v = () => e.removeEventListener("value", n)), n();
158
157
  }
159
- const M = {
158
+ const Q = {
160
159
  /**
161
160
  * The first subscriber starts listening to the crossfilter and the last one stops it and lets the
162
161
  * graph go — `QueryObserver`'s `onSubscribe`/`onUnsubscribe`, which is what survives StrictMode
163
162
  * mounting everything twice.
164
163
  */
165
164
  subscribe(e) {
166
- if (m.add(e), !E && (E = !0, D(), l && !h && y.length > 0 && (!c && (!f || !b) && J(), !i && N !== void 0 && !B && P()), z !== null)) {
167
- const n = z;
168
- z = null, r.onFailure(n);
165
+ if (m.add(e), !F && (F = !0, D(), u && !b && g.length > 0 && (!c && (!f || !h) && P(), !l && N !== void 0 && !B && $()), L !== null)) {
166
+ const { error: n } = L;
167
+ L = null, r.onFailure(n);
169
168
  }
170
169
  return () => {
171
- m.delete(e), m.size === 0 && M.destroy();
170
+ m.delete(e), m.size === 0 && Q.destroy();
172
171
  };
173
172
  },
174
173
  getSnapshot: () => d,
@@ -176,22 +175,22 @@ function de(a) {
176
175
  setOptions(e) {
177
176
  const n = r;
178
177
  r = e;
179
- const t = Q(e), o = t.category !== p.category || t.byTable !== p.byTable || t.size !== p.size || e.categories !== n.categories;
178
+ const t = R(e), o = t.category !== p.category || t.byTable !== p.byTable || t.size !== p.size || e.categories !== n.categories;
180
179
  if (p = t, e.corpus !== n.corpus) {
181
- I(e.corpus), E && e.filterBy !== n.filterBy && D();
180
+ M(e.corpus), F && e.filterBy !== n.filterBy && D();
182
181
  return;
183
182
  }
184
- E && e.filterBy !== n.filterBy && D(), o && J(), g();
183
+ F && e.filterBy !== n.filterBy && D(), o && P(), y();
185
184
  },
186
185
  destroy() {
187
- E = !1, w == null || w(), w = null, c == null || c.abort(), i == null || i.abort(), c = i = null, m.clear();
186
+ F = !1, v == null || v(), v = null, c == null || c.abort(), l == null || l.abort(), c = l = null, m.clear();
188
187
  },
189
188
  select(e, n = "node", t = "") {
190
- var k, F;
189
+ var k, z;
191
190
  const o = e && e.length > 0 ? { vertices: [...e], source: n, label: t } : null;
192
191
  O({ selection: o }), (k = r.onSelect) == null || k.call(r, o);
193
- const L = (F = y[0]) == null ? void 0 : F.key;
194
- r.filterBy && L && x(r.filterBy, s, L, o ? o.vertices : null);
192
+ const S = (z = g[0]) == null ? void 0 : z.key;
193
+ r.filterBy && S && ee(r.filterBy, i, S, o ? o.vertices : null);
195
194
  },
196
195
  focus(e) {
197
196
  var n;
@@ -212,17 +211,20 @@ function de(a) {
212
211
  reportProgress(e) {
213
212
  e !== d.progress && O({ progress: e });
214
213
  },
215
- setRenderable(e) {
216
- _ !== !e && (_ = !e, g());
214
+ renderable() {
215
+ E && (E = !1, y());
216
+ },
217
+ unrenderable(e) {
218
+ E = !0, T(e), y();
217
219
  },
218
220
  reportDrawn(e) {
219
221
  const n = [e.geometry, e.encoding, e.mask];
220
- n.every((t, o) => t === T[o]) || (T = n, g());
222
+ n.every((t, o) => t === G[o]) || (G = n, y());
221
223
  }
222
224
  };
223
- return I(a.corpus), R = !1, M;
225
+ return M(a.corpus), j = !1, Q;
224
226
  }
225
227
  export {
226
- de as createGraph
228
+ ye as createGraph
227
229
  };
228
230
  //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sources":["../../src/core/store.ts"],"sourcesContent":["import 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 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 vertices++;\n const rank = encoding.ranks[id] as number;\n tally[rank] = (tally[rank] ?? 0) + 1;\n }\n return { vertices, 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: string | null = null;\n const fail = (error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n if (building) held = message;\n else options.onFailure(message);\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 if (corpus.manifest.format !== \"fossil/1\") throw new Error(`the graph reads fossil/1, and this corpus is ${corpus.manifest.format}`);\n tables = drawnTables(corpus);\n if (tables.length === 0) throw new Error(\"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 message = held;\n held = null;\n options.onFailure(message);\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 setRenderable(renderable) {\n if (unrenderable === !renderable) return;\n unrenderable = !renderable;\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","b","_","v","isPromise","value","drawnOf","geometry","encoding","mask","tally","vertices","id","rank","createGraph","initial","options","listeners","self","graphClient","corpus","opening","failed","unrenderable","tables","binding","bindingOf","filter","loading","filtering","kept","uploaded","unlisten","active","building","held","fail","error","message","snapshot","domain","domainNow","key","part","i","domainOf","drawn","drawnNow","statusOf","shown","notify","fields","sum","table","emit","patch","listener","run","current","set","fatal","read","done","_a","aborter","asLoad","a","asFilter","load","open","seed","given","signal","loadEncoding","next","loadGraph","maskOf","refilter","readKept","reopen","cleared","drawnTables","adopt","promised","opened","listen","crossfilter","changed","filterFor","store","previous","nextBinding","rebound","source","label","selection","_b","publish","vertex","tool","motion","renderable","drawnSnapshot"],"mappings":"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"}
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 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 vertices++;\n const rank = encoding.ranks[id] as number;\n tally[rank] = (tally[rank] ?? 0) + 1;\n }\n return { vertices, 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","b","_","v","isPromise","value","drawnOf","geometry","encoding","mask","tally","vertices","id","rank","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","i","domainOf","drawn","drawnNow","statusOf","shown","notify","fields","sum","table","emit","patch","listener","run","current","set","fatal","read","done","_a","aborter","asLoad","a","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":"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"}
package/dist/index.d.ts CHANGED
@@ -35,4 +35,5 @@ export type { Channels } from './core/channels';
35
35
  export type { GraphCommands, Motion, Selection, SelectionSource, Tool, VertexId } from './core/types';
36
36
  export type { Drawn, GraphState, GraphStatus } from './core/state';
37
37
  export type { VertexDetail } from './core/detail';
38
+ export { GraphError } from './core/error';
38
39
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;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,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAIvE,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACvF,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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;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,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAIvE,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACvF,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
@@ -1,4 +1,4 @@
1
- import { GraphRoot as e, GraphRootProvider as p, useGraphContext as t } from "./react/graph-root.js";
1
+ import { GraphRoot as p, GraphRootProvider as e, useGraphContext as t } from "./react/graph-root.js";
2
2
  import { useGraph as m } from "./react/use-graph.js";
3
3
  import { useGraphState as x } from "./react/use-graph-state.js";
4
4
  import { useGraphPrefs as G } from "./react/use-graph-prefs.js";
@@ -10,12 +10,14 @@ import { ShapeGlyph as F } from "./parts/shape-glyph.js";
10
10
  import { lookFrom as R } from "./render/graph-looks.js";
11
11
  import { simFrom as b } from "./render/graph-sim.js";
12
12
  import { scaleOf as k } from "./render/graph-model.js";
13
+ import { GraphError as E } from "./core/error.js";
13
14
  export {
14
15
  l as GraphCanvas,
16
+ E as GraphError,
15
17
  v as GraphInspector,
16
18
  u as GraphLegend,
17
- e as GraphRoot,
18
- p as GraphRootProvider,
19
+ p as GraphRoot,
20
+ e as GraphRootProvider,
19
21
  d as GraphToolbar,
20
22
  F as ShapeGlyph,
21
23
  R as lookFrom,
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":";;;;;;;;;;;;;"}