@kanzo-tech/graph 0.12.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAA8B,UAAU,EAAY,MAAM,SAAS,CAAC;AAK9F,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEjH,0FAA0F;AAC1F,eAAO,MAAM,aAAa,QAAS,CAAC;AAwBpC,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,UAAU,CA6T7D"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAA8B,UAAU,EAAY,MAAM,SAAS,CAAC;AAK9F,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEjH,0FAA0F;AAC1F,eAAO,MAAM,aAAa,QAAS,CAAC;AAwBpC,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,UAAU,CA0U7D"}
@@ -1,58 +1,59 @@
1
- import { PAYLOAD_ADDRESS as te, PAYLOAD_COORDINATES as ne } from "@fossil-lang/corpus";
1
+ import { PAYLOAD_ADDRESS as le, PAYLOAD_COORDINATES as oe } from "@fossil-lang/corpus";
2
2
  import { domainOf as re } from "./categories.js";
3
- import { bindingOf as Y, projectionOf as oe } from "./channels.js";
4
- import { graphClient as le, publish as ie, filterFor as se } from "./filter.js";
5
- import { denseOf as ce } from "./resident.js";
6
- import { Tileset2D as fe } from "./tileset.js";
7
- const R = 2e4, q = Y({}), H = te[0];
8
- function de(i) {
9
- var m;
3
+ import { bindingOf as Y, projectionOf as ie } from "./channels.js";
4
+ import { graphClient as se, publish as ce, filterFor as fe } from "./filter.js";
5
+ import { denseOf as ue } from "./resident.js";
6
+ import { Tileset2D as de } from "./tileset.js";
7
+ const R = 2e4, H = Y({}), Q = le[0];
8
+ function ae(i) {
9
+ var p;
10
10
  let n = 0;
11
- for (const s of i.edges) n += s.src.byteLength + s.dst.byteLength + (((m = s.weight) == null ? void 0 : m.byteLength) ?? 0);
11
+ for (const s of i.edges) n += s.src.byteLength + s.dst.byteLength + (((p = s.weight) == null ? void 0 : p.byteLength) ?? 0);
12
12
  return n + i.rows.numRows * 8 * 4;
13
13
  }
14
- const ue = (i, n) => JSON.stringify(i, (m, s) => typeof s == "bigint" ? `${s}n` : s) === JSON.stringify(n, (m, s) => typeof s == "bigint" ? `${s}n` : s), ae = (i) => typeof (i == null ? void 0 : i.then) == "function";
15
- function Q(i, n) {
16
- return i.length !== n.length ? n : n.every((m, s) => {
17
- var o;
18
- return m.content === ((o = i[s]) == null ? void 0 : o.content);
14
+ const pe = (i, n) => JSON.stringify(i, (p, s) => typeof s == "bigint" ? `${s}n` : s) === JSON.stringify(n, (p, s) => typeof s == "bigint" ? `${s}n` : s), me = (i) => typeof (i == null ? void 0 : i.then) == "function";
15
+ function W(i, n) {
16
+ return i.length !== n.length ? n : n.every((p, s) => {
17
+ var r;
18
+ return p.content === ((r = i[s]) == null ? void 0 : r.content);
19
19
  }) ? i : n;
20
20
  }
21
- function be(i) {
21
+ function Le(i) {
22
22
  let n = i;
23
- const m = /* @__PURE__ */ new Set(), s = le();
24
- let o = null, b = null, M = !1, C = !1, u = null, T = 0, G = null, O = null, g = q, F, z = null, E = [], S = null, h = null, B = !1, J = -1;
23
+ const p = /* @__PURE__ */ new Set(), s = se();
24
+ let r = null, h = null, M = !1, F = !1, c = null, S = 0, G = null, L = null, y = H, P, z = null, E = [], A = null, g = null, B = !1, J = -1, V = !0, I = null;
25
25
  const D = (e) => {
26
- n.onFailure(e instanceof Error ? e.message : String(e));
27
- }, a = new fe({
26
+ const t = e instanceof Error ? e.message : String(e);
27
+ V ? I = t : n.onFailure(t);
28
+ }, d = new de({
28
29
  debounceTime: 60,
29
30
  load: async (e, t) => {
30
- if (!o || !O) throw new Error("the graph has no scan to read with");
31
- const r = (d) => {
32
- var w;
33
- return ((w = u == null ? void 0 : u.tileMatrices[d.z]) == null ? void 0 : w.kind) === "cells";
34
- }, l = await O.read(e, { signal: t }), y = await o.edges({ from: e, direction: "src", signal: t }), p = e.filter((d) => !r(d)), I = p.length > 0 ? await o.edges({ from: p, direction: "dst", signal: t }) : [], N = new Map(p.map((d, w) => [d, I[w]]));
35
- return e.map((d, w) => {
36
- const v = y[w], L = N.get(d), Z = [...(v == null ? void 0 : v.batches) ?? [], ...(L == null ? void 0 : L.batches) ?? []], K = [...(v == null ? void 0 : v.declined) ?? [], ...(L == null ? void 0 : L.declined) ?? []], x = r(d) ? K.filter((ee) => ee.direction !== "dst") : K, U = { rows: l[w], edges: Z, declined: x };
37
- return { ...U, byteLength: de(U) };
31
+ if (!r || !L) throw new Error("the graph has no scan to read with");
32
+ const l = (w) => {
33
+ var O;
34
+ return ((O = c == null ? void 0 : c.tileMatrices[w.z]) == null ? void 0 : O.kind) === "cells";
35
+ }, o = await L.read(e, { signal: t }), m = await r.edges({ from: e, direction: "src", signal: t }), a = e.filter((w) => !l(w)), b = a.length > 0 ? await r.edges({ from: a, direction: "dst", signal: t }) : [], x = new Map(a.map((w, O) => [w, b[O]]));
36
+ return e.map((w, O) => {
37
+ const v = m[O], T = x.get(w), ee = [...(v == null ? void 0 : v.batches) ?? [], ...(T == null ? void 0 : T.batches) ?? []], U = [...(v == null ? void 0 : v.declined) ?? [], ...(T == null ? void 0 : T.declined) ?? []], te = l(w) ? U.filter((ne) => ne.direction !== "dst") : U, q = { rows: o[O], edges: ee, declined: te };
38
+ return { ...q, byteLength: ae(q) };
38
39
  });
39
40
  },
40
41
  onTileLoad: (e) => {
41
42
  var t;
42
- for (const r of ((t = e.content) == null ? void 0 : t.declined) ?? [])
43
- E.some((l) => l.edgeType === r.edgeType && l.direction === r.direction) || (E = [...E, r]);
44
- a.refresh(), f();
43
+ for (const l of ((t = e.content) == null ? void 0 : t.declined) ?? [])
44
+ E.some((o) => o.edgeType === l.edgeType && o.direction === l.direction) || (E = [...E, l]);
45
+ d.refresh(), u();
45
46
  },
46
47
  onTileError: (e) => {
47
- a.refresh(), D(e), f();
48
+ d.refresh(), D(e), u();
48
49
  }
49
50
  });
50
- let c = {
51
+ let f = {
51
52
  status: "none",
52
53
  matrix: null,
53
54
  typeIndex: 0,
54
55
  modeColumn: null,
55
- binding: q,
56
+ binding: H,
56
57
  domain: [],
57
58
  z: null,
58
59
  visible: [],
@@ -71,165 +72,167 @@ function be(i) {
71
72
  options: n,
72
73
  corpus: null
73
74
  };
74
- const V = (e) => {
75
+ const $ = (e) => {
75
76
  var t;
76
77
  return {
77
78
  address: e.address,
78
- kind: ((t = u == null ? void 0 : u.tileMatrices[e.address.z]) == null ? void 0 : t.kind) ?? "rows",
79
+ kind: ((t = c == null ? void 0 : c.tileMatrices[e.address.z]) == null ? void 0 : t.kind) ?? "rows",
79
80
  content: e.content
80
81
  };
81
82
  };
82
- let P = { key: [], value: [] };
83
- function W() {
84
- const e = [o, T, g.category, n.categories];
85
- return e.some((t, r) => t !== P.key[r]) && (P = { key: e, value: re(o, T, g, n.categories) }), P.value;
83
+ let _ = { key: [], value: [] };
84
+ function X() {
85
+ const e = [r, S, y.category, n.categories];
86
+ return e.some((t, l) => t !== _.key[l]) && (_ = { key: e, value: re(r, S, y, n.categories) }), _.value;
86
87
  }
87
- function X(e, t) {
88
- return M || C ? "failed" : b ? "opening" : o ? e || S !== t || c.drawn === null ? "reading" : "idle" : "none";
88
+ function Z(e, t) {
89
+ return M || F ? "failed" : h ? "opening" : r ? e || A !== t || f.drawn === null ? "reading" : "idle" : "none";
89
90
  }
90
- function f(e = {}) {
91
- var y;
92
- J = a.frame;
93
- const t = a.tiles.filter((p) => p.content !== null), r = Q(c.visible, t.filter((p) => p.isVisible).map(V)), l = a.selectedTiles.some((p) => p.isLoading);
94
- c = {
95
- ...c,
96
- matrix: u,
97
- typeIndex: T,
91
+ function u(e = {}) {
92
+ var m;
93
+ J = d.frame;
94
+ const t = d.tiles.filter((a) => a.content !== null), l = W(f.visible, t.filter((a) => a.isVisible).map($)), o = d.selectedTiles.some((a) => a.isLoading);
95
+ f = {
96
+ ...f,
97
+ matrix: c,
98
+ typeIndex: S,
98
99
  modeColumn: G,
99
- binding: g,
100
- domain: W(),
101
- z: a.z,
102
- visible: r,
103
- cached: Q(c.cached, t.map(V)),
104
- pending: l,
105
- total: u ? Number(((y = u.tileMatrices[u.tileMatrices.length - 1]) == null ? void 0 : y.count) ?? 0) : void 0,
100
+ binding: y,
101
+ domain: X(),
102
+ z: d.z,
103
+ visible: l,
104
+ cached: W(f.cached, t.map($)),
105
+ pending: o,
106
+ total: c ? Number(((m = c.tileMatrices[c.tileMatrices.length - 1]) == null ? void 0 : m.count) ?? 0) : void 0,
106
107
  declined: E,
107
108
  options: n,
108
- corpus: o,
109
+ corpus: r,
109
110
  ...e
110
- }, c = { ...c, status: X(l, c.visible) };
111
- for (const p of m) p();
111
+ }, f = { ...f, status: Z(o, f.visible) };
112
+ for (const a of p) a();
112
113
  }
113
- function _() {
114
- if (!(!o || !u)) {
114
+ function C() {
115
+ if (!(!r || !c)) {
115
116
  try {
116
- const e = [H, ...ne];
117
- O = o.scan({ type: u.type, filter: F, select: oe(g, e) }), a.setPlan(O.plan());
117
+ const e = [Q, ...oe];
118
+ L = r.scan({ type: c.type, filter: P, select: ie(y, e) }), d.setPlan(L.plan());
118
119
  } catch (e) {
119
- O = null, a.setPlan([]), D(e);
120
+ L = null, d.setPlan([]), D(e);
120
121
  }
121
- a.reloadAll(), z && a.update(z, n.limit ?? R), f();
122
+ d.reloadAll(), z && d.update(z, n.limit ?? R), u();
122
123
  }
123
124
  }
124
- function A() {
125
- var l, y, p, I, N;
126
- M = !1, u = null, O = null, E = [], S = null, a.finalize();
125
+ function N() {
126
+ var o, m, a;
127
+ M = !1, c = null, L = null, E = [], A = null, d.finalize();
127
128
  const e = { selection: null, focus: null, hovered: null, pinned: [], drawn: null };
128
- if (!o) return f(e);
129
- const t = o.types.vertices, r = n.type ?? ((l = t.find((d) => d.geometry)) == null ? void 0 : l.type) ?? ((y = t[0]) == null ? void 0 : y.type);
130
- T = Math.max(0, t.findIndex((d) => d.type === r));
129
+ if (!r) return u(e);
130
+ const t = r.types.vertices, l = n.type ?? ((o = t.find((b) => b.geometry)) == null ? void 0 : o.type) ?? ((m = t[0]) == null ? void 0 : m.type);
131
+ S = Math.max(0, t.findIndex((b) => b.type === l));
131
132
  try {
132
- if (r === void 0) throw new Error("the corpus has no vertex type to draw");
133
- u = o.tileMatrix(r);
134
- const d = ((p = o.addressing.vertexType(r).cells) == null ? void 0 : p.modeChannel) ?? null;
135
- G = ((N = (I = t[T]) == null ? void 0 : I.channels.find((w) => w.name === d)) == null ? void 0 : N.column) ?? null, a.setMatrix(u);
136
- } catch (d) {
137
- M = !0, D(d);
133
+ if (l === void 0) throw new Error("the corpus has no vertex type to draw");
134
+ c = r.tileMatrix(l), G = ((a = c.mode) == null ? void 0 : a.column) ?? null, d.setMatrix(c);
135
+ } catch (b) {
136
+ M = !0, D(b);
138
137
  }
139
- c = { ...c, ...e }, _();
138
+ f = { ...f, ...e }, C();
140
139
  }
141
- function $(e) {
142
- if (o = null, b = ae(e) ? e : null, !b)
143
- return o = e, A();
144
- const t = b;
145
- A(), t.then(
146
- (r) => {
147
- b === t && (b = null, o = r, A());
140
+ function j(e) {
141
+ if (r = null, h = me(e) ? e : null, !h)
142
+ return r = e, N();
143
+ const t = h;
144
+ N(), t.then(
145
+ (l) => {
146
+ h === t && (h = null, r = l, N());
148
147
  },
149
- (r) => {
150
- b === t && (b = null, M = !0, D(r), f());
148
+ (l) => {
149
+ h === t && (h = null, M = !0, D(l), u());
151
150
  }
152
151
  );
153
152
  }
154
153
  function k() {
155
- h == null || h(), h = null;
154
+ g == null || g(), g = null;
156
155
  const e = n.filterBy, t = () => {
157
- let r;
156
+ let l;
158
157
  try {
159
- r = e ? se(e, s) : void 0;
160
- } catch (l) {
161
- D(l);
158
+ l = e ? fe(e, s) : void 0;
159
+ } catch (o) {
160
+ D(o);
162
161
  return;
163
162
  }
164
- ue(r, F) || (F = r, _());
163
+ pe(l, P) || (P = l, C());
165
164
  };
166
- e && (e.addEventListener("value", t), h = () => e.removeEventListener("value", t)), t();
165
+ e && (e.addEventListener("value", t), g = () => e.removeEventListener("value", t)), t();
167
166
  }
168
- const j = {
167
+ const K = {
169
168
  /**
170
169
  * The first subscriber starts listening to the crossfilter and the last one stops it and lets the
171
170
  * tiles go — `QueryObserver`'s `onSubscribe`/`onUnsubscribe`, which is what survives StrictMode
172
171
  * mounting everything twice.
173
172
  */
174
173
  subscribe(e) {
175
- return m.add(e), B || (B = !0, k()), () => {
176
- m.delete(e), m.size === 0 && j.destroy();
174
+ if (p.add(e), !B && (B = !0, k(), I !== null)) {
175
+ const t = I;
176
+ I = null, n.onFailure(t);
177
+ }
178
+ return () => {
179
+ p.delete(e), p.size === 0 && K.destroy();
177
180
  };
178
181
  },
179
- getSnapshot: () => c,
182
+ getSnapshot: () => f,
180
183
  getOptions: () => n,
181
184
  setOptions(e) {
182
185
  const t = n;
183
186
  n = e;
184
- const r = Y(e), l = r.category !== g.category || r.size !== g.size || r.title !== g.title;
185
- if (g = r, e.corpus !== t.corpus || e.type !== t.type) {
186
- e.corpus !== t.corpus ? $(e.corpus) : A(), B && e.filterBy !== t.filterBy && k();
187
+ const l = Y(e), o = l.category !== y.category || l.size !== y.size || l.title !== y.title;
188
+ if (y = l, e.corpus !== t.corpus || e.type !== t.type) {
189
+ e.corpus !== t.corpus ? j(e.corpus) : N(), B && e.filterBy !== t.filterBy && k();
187
190
  return;
188
191
  }
189
- if (B && e.filterBy !== t.filterBy && k(), l) return _();
190
- e.limit !== t.limit && z && a.update(z, e.limit ?? R), f();
192
+ if (B && e.filterBy !== t.filterBy && k(), o) return C();
193
+ e.limit !== t.limit && z && d.update(z, e.limit ?? R), u();
191
194
  },
192
195
  destroy() {
193
- B = !1, h == null || h(), h = null, a.finalize(), m.clear();
196
+ B = !1, g == null || g(), g = null, d.finalize(), p.clear();
194
197
  },
195
198
  setViewport(e) {
196
- z = e, a.update(e, n.limit ?? R) !== J && f();
199
+ z = e, d.update(e, n.limit ?? R) !== J && u();
197
200
  },
198
- select(e, t = "node", r = "") {
199
- var y;
200
- const l = e && e.length > 0 ? { vertices: [...e], source: t, label: r } : null;
201
- f({ selection: l }), (y = n.onSelect) == null || y.call(n, l), n.filterBy && ie(n.filterBy, s, H, l ? l.vertices.map(ce) : null);
201
+ select(e, t = "node", l = "") {
202
+ var m;
203
+ const o = e && e.length > 0 ? { vertices: [...e], source: t, label: l } : null;
204
+ u({ selection: o }), (m = n.onSelect) == null || m.call(n, o), n.filterBy && ce(n.filterBy, s, Q, o ? o.vertices.map(ue) : null);
202
205
  },
203
206
  focus(e) {
204
207
  var t;
205
- e !== c.focus && (f({ focus: e }), (t = n.onFocus) == null || t.call(n, e));
208
+ e !== f.focus && (u({ focus: e }), (t = n.onFocus) == null || t.call(n, e));
206
209
  },
207
210
  hover(e) {
208
- e !== c.hovered && f({ hovered: e });
211
+ e !== f.hovered && u({ hovered: e });
209
212
  },
210
213
  pin(e) {
211
- f({ pinned: [...e] });
214
+ u({ pinned: [...e] });
212
215
  },
213
216
  setTool(e) {
214
- e !== c.tool && f({ tool: e });
217
+ e !== f.tool && u({ tool: e });
215
218
  },
216
219
  report(e) {
217
- e !== c.motion && f({ motion: e });
220
+ e !== f.motion && u({ motion: e });
218
221
  },
219
222
  reportProgress(e) {
220
- e !== c.progress && f({ progress: e });
223
+ e !== f.progress && u({ progress: e });
221
224
  },
222
225
  setRenderable(e) {
223
- C !== !e && (C = !e, f());
226
+ F !== !e && (F = !e, u());
224
227
  },
225
228
  reportDrawn(e, t) {
226
- S === e && t === null || (S = e, f(t ? { drawn: t } : {}));
229
+ A === e && t === null || (A = e, u(t ? { drawn: t } : {}));
227
230
  }
228
231
  };
229
- return g = Y(i), $(i.corpus), j;
232
+ return y = Y(i), j(i.corpus), V = !1, K;
230
233
  }
231
234
  export {
232
235
  R as DEFAULT_LIMIT,
233
- be as createGraph
236
+ Le as createGraph
234
237
  };
235
238
  //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sources":["../../src/core/store.ts"],"sourcesContent":["import {\n PAYLOAD_ADDRESS,\n PAYLOAD_COORDINATES,\n type Batch,\n type Corpus,\n type Filter,\n type Gap,\n type Scan,\n type TileAddress,\n type TileMatrixSet,\n} from \"@fossil-lang/corpus\";\nimport type { MosaicClient } from \"@kanzo-tech/mosaic\";\nimport { domainOf } from \"./categories\";\nimport { bindingOf, projectionOf, type Binding } from \"./channels\";\nimport { filterFor, graphClient, publish } from \"./filter\";\nimport { denseOf } from \"./resident\";\nimport type { GraphOptions, GraphSnapshot, GraphStatus, GraphStore, TileView } from \"./state\";\nimport type { TileContent } from \"./tile\";\nimport type { Viewport } from \"./tile-matrix\";\nimport { Tileset2D } from \"./tileset\";\n\nexport type { Drawn, GraphOptions, GraphSnapshot, GraphState, GraphStatus, GraphStore, TileView } from \"./state\";\n\n/** Twenty thousand marks: what a canvas draws at once before a coarser zoom is chosen. */\nexport const DEFAULT_LIMIT = 20_000;\n\nconst NO_BINDING: Binding = bindingOf({});\nconst KEY = PAYLOAD_ADDRESS[0] as string;\n\nfunction bytesOf(content: Omit<TileContent, \"byteLength\">): number {\n let bytes = 0;\n for (const edge of content.edges) bytes += edge.src.byteLength + edge.dst.byteLength + (edge.weight?.byteLength ?? 0);\n return bytes + content.rows.numRows * 8 * 4;\n}\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\n/** The same array while the set of tiles in it is the same, so a reader can compare by identity. */\nfunction keep(previous: readonly TileView[], next: TileView[]): readonly TileView[] {\n if (previous.length !== next.length) return next;\n return next.every((view, i) => view.content === previous[i]?.content) ? previous : next;\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 matrix: TileMatrixSet | null = null;\n let typeIndex = 0;\n let modeColumn: string | null = null;\n let scan: Scan | null = null;\n let binding = NO_BINDING;\n let filter: Filter | undefined;\n let viewport: Viewport | null = null;\n let declined: Gap[] = [];\n let composed: readonly TileView[] | null = null;\n let unlisten: (() => void) | null = null;\n let active = false;\n let lastFrame = -1;\n\n const fail = (error: unknown) => {\n options.onFailure(error instanceof Error ? error.message : String(error));\n };\n\n const tileset = new Tileset2D({\n debounceTime: 60,\n load: async (addresses, signal) => {\n if (!corpus || !scan) throw new Error(\"the graph has no scan to read with\");\n const isCells = (address: TileAddress) => matrix?.tileMatrices[address.z]?.kind === \"cells\";\n const rows = await scan.read(addresses, { signal });\n const src = await corpus.edges({ from: addresses, direction: \"src\", signal });\n const payload = addresses.filter((address) => !isCells(address));\n const dst = payload.length > 0 ? await corpus.edges({ from: payload, direction: \"dst\", signal }) : [];\n const dstOf = new Map(payload.map((address, i) => [address, dst[i]]));\n return addresses.map((address, i) => {\n const out = src[i];\n const back = dstOf.get(address);\n const edges = [...(out?.batches ?? []), ...(back?.batches ?? [])];\n const gaps = [...(out?.declined ?? []), ...(back?.declined ?? [])];\n const declined = isCells(address) ? gaps.filter((gap) => gap.direction !== \"dst\") : gaps;\n const content = { rows: rows[i] as Batch, edges, declined };\n return { ...content, byteLength: bytesOf(content) };\n });\n },\n onTileLoad: (tile) => {\n for (const gap of tile.content?.declined ?? []) {\n if (!declined.some((d) => d.edgeType === gap.edgeType && d.direction === gap.direction)) {\n declined = [...declined, gap];\n }\n }\n tileset.refresh();\n notify();\n },\n onTileError: (error) => {\n tileset.refresh();\n fail(error);\n notify();\n },\n });\n\n let snapshot: GraphSnapshot = {\n status: \"none\",\n matrix: null,\n typeIndex: 0,\n modeColumn: null,\n binding: NO_BINDING,\n domain: [],\n z: null,\n visible: [],\n cached: [],\n pending: false,\n total: undefined,\n declined: [],\n selection: null,\n focus: null,\n hovered: null,\n pinned: [],\n tool: null,\n motion: \"settled\",\n progress: 1,\n drawn: null,\n options,\n corpus: null,\n };\n\n const viewOf = (tile: { address: TileAddress; content: TileContent | null }): TileView => ({\n address: tile.address,\n kind: matrix?.tileMatrices[tile.address.z]?.kind ?? \"rows\",\n content: tile.content as TileContent,\n });\n\n let domain: { key: unknown[]; value: readonly unknown[] } = { key: [], value: [] };\n function domainNow(): readonly unknown[] {\n const key = [corpus, typeIndex, binding.category, options.categories];\n if (key.some((part, i) => part !== domain.key[i])) domain = { key, value: domainOf(corpus, typeIndex, binding, options.categories) };\n return domain.value;\n }\n\n function statusOf(pending: boolean, visible: readonly TileView[]): GraphStatus {\n if (failed || unrenderable) return \"failed\";\n if (opening) return \"opening\";\n if (!corpus) return \"none\";\n return pending || composed !== visible || snapshot.drawn === null ? \"reading\" : \"idle\";\n }\n\n function notify(patch: Partial<GraphSnapshot> = {}): void {\n lastFrame = tileset.frame;\n const tiles = tileset.tiles.filter((tile) => tile.content !== null);\n const visible = keep(snapshot.visible, tiles.filter((tile) => tile.isVisible).map(viewOf));\n const pending = tileset.selectedTiles.some((tile) => tile.isLoading);\n snapshot = {\n ...snapshot,\n matrix,\n typeIndex,\n modeColumn,\n binding,\n domain: domainNow(),\n z: tileset.z,\n visible,\n cached: keep(snapshot.cached, tiles.map(viewOf)),\n pending,\n total: matrix ? Number(matrix.tileMatrices[matrix.tileMatrices.length - 1]?.count ?? 0) : undefined,\n declined,\n options,\n corpus,\n ...patch,\n };\n snapshot = { ...snapshot, status: statusOf(pending, snapshot.visible) };\n for (const listener of listeners) listener();\n }\n\n /** A binding or a filter is a new scan, planned once and never per camera move. */\n function rescan(): void {\n if (!corpus || !matrix) return;\n try {\n const fixed = [KEY, ...PAYLOAD_COORDINATES];\n scan = corpus.scan({ type: matrix.type, filter, select: projectionOf(binding, fixed) });\n tileset.setPlan(scan.plan());\n } catch (error) {\n scan = null;\n tileset.setPlan([]);\n fail(error);\n }\n tileset.reloadAll();\n if (viewport) tileset.update(viewport, options.limit ?? DEFAULT_LIMIT);\n notify();\n }\n\n function reopen(): void {\n failed = false;\n matrix = null;\n scan = null;\n declined = [];\n composed = null;\n tileset.finalize();\n const cleared = { selection: null, focus: null, hovered: null, pinned: [], drawn: null };\n if (!corpus) return notify(cleared);\n const types = corpus.types.vertices;\n const type = options.type ?? types.find((t) => t.geometry)?.type ?? types[0]?.type;\n typeIndex = Math.max(0, types.findIndex((t) => t.type === type));\n try {\n if (type === undefined) throw new Error(\"the corpus has no vertex type to draw\");\n matrix = corpus.tileMatrix(type);\n const mode = corpus.addressing.vertexType(type).cells?.modeChannel ?? null;\n modeColumn = types[typeIndex]?.channels.find((channel) => channel.name === mode)?.column ?? null;\n tileset.setMatrix(matrix);\n } catch (error) {\n failed = true;\n fail(error);\n }\n snapshot = { ...snapshot, ...cleared };\n rescan();\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 refilter = () => {\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 rescan();\n };\n if (crossfilter) {\n crossfilter.addEventListener(\"value\", refilter);\n unlisten = () => crossfilter.removeEventListener(\"value\", refilter);\n }\n refilter();\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 * tiles 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 }\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.size !== binding.size ||\n nextBinding.title !== binding.title;\n binding = nextBinding;\n if (next.corpus !== previous.corpus || next.type !== previous.type) {\n if (next.corpus !== previous.corpus) adopt(next.corpus);\n else reopen();\n if (active && next.filterBy !== previous.filterBy) listen();\n return;\n }\n if (active && next.filterBy !== previous.filterBy) listen();\n if (rebound) return rescan();\n if (next.limit !== previous.limit && viewport) tileset.update(viewport, next.limit ?? DEFAULT_LIMIT);\n notify();\n },\n destroy() {\n active = false;\n unlisten?.();\n unlisten = null;\n tileset.finalize();\n listeners.clear();\n },\n setViewport(next) {\n viewport = next;\n if (tileset.update(next, options.limit ?? DEFAULT_LIMIT) !== lastFrame) notify();\n },\n select(vertices, source = \"node\", label = \"\") {\n const selection = vertices && vertices.length > 0 ? { vertices: [...vertices], source, label } : null;\n notify({ selection });\n options.onSelect?.(selection);\n if (options.filterBy) publish(options.filterBy, self, KEY, selection ? selection.vertices.map(denseOf) : null);\n },\n focus(vertex) {\n if (vertex === snapshot.focus) return;\n notify({ focus: vertex });\n options.onFocus?.(vertex);\n },\n hover(vertex) {\n if (vertex !== snapshot.hovered) notify({ hovered: vertex });\n },\n pin(vertices) {\n notify({ pinned: [...vertices] });\n },\n setTool(tool) {\n if (tool !== snapshot.tool) notify({ tool });\n },\n report(motion) {\n if (motion !== snapshot.motion) notify({ motion });\n },\n reportProgress(value) {\n if (value !== snapshot.progress) notify({ progress: value });\n },\n setRenderable(renderable) {\n if (unrenderable === !renderable) return;\n unrenderable = !renderable;\n notify();\n },\n reportDrawn(visible, drawn) {\n if (composed === visible && drawn === null) return;\n composed = visible;\n notify(drawn ? { drawn } : {});\n },\n };\n\n binding = bindingOf(initial);\n adopt(initial.corpus);\n return store;\n}\n"],"names":["DEFAULT_LIMIT","NO_BINDING","bindingOf","KEY","PAYLOAD_ADDRESS","bytesOf","content","bytes","edge","_a","sameFilter","a","b","_","v","isPromise","value","keep","previous","next","view","i","createGraph","initial","options","listeners","self","graphClient","corpus","opening","failed","unrenderable","matrix","typeIndex","modeColumn","scan","binding","filter","viewport","declined","composed","unlisten","active","lastFrame","fail","error","tileset","Tileset2D","addresses","signal","isCells","address","rows","src","payload","dst","dstOf","out","back","edges","gaps","gap","tile","d","notify","snapshot","viewOf","domain","domainNow","key","part","domainOf","statusOf","pending","visible","patch","tiles","listener","rescan","fixed","PAYLOAD_COORDINATES","projectionOf","reopen","cleared","types","type","t","_b","mode","_c","_e","_d","channel","adopt","given","promised","opened","listen","crossfilter","refilter","filterFor","store","nextBinding","rebound","vertices","source","label","selection","publish","denseOf","vertex","tool","motion","renderable","drawn"],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sources":["../../src/core/store.ts"],"sourcesContent":["import {\n PAYLOAD_ADDRESS,\n PAYLOAD_COORDINATES,\n type Batch,\n type Corpus,\n type Filter,\n type Gap,\n type Scan,\n type TileAddress,\n type TileMatrixSet,\n} from \"@fossil-lang/corpus\";\nimport type { MosaicClient } from \"@kanzo-tech/mosaic\";\nimport { domainOf } from \"./categories\";\nimport { bindingOf, projectionOf, type Binding } from \"./channels\";\nimport { filterFor, graphClient, publish } from \"./filter\";\nimport { denseOf } from \"./resident\";\nimport type { GraphOptions, GraphSnapshot, GraphStatus, GraphStore, TileView } from \"./state\";\nimport type { TileContent } from \"./tile\";\nimport type { Viewport } from \"./tile-matrix\";\nimport { Tileset2D } from \"./tileset\";\n\nexport type { Drawn, GraphOptions, GraphSnapshot, GraphState, GraphStatus, GraphStore, TileView } from \"./state\";\n\n/** Twenty thousand marks: what a canvas draws at once before a coarser zoom is chosen. */\nexport const DEFAULT_LIMIT = 20_000;\n\nconst NO_BINDING: Binding = bindingOf({});\nconst KEY = PAYLOAD_ADDRESS[0] as string;\n\nfunction bytesOf(content: Omit<TileContent, \"byteLength\">): number {\n let bytes = 0;\n for (const edge of content.edges) bytes += edge.src.byteLength + edge.dst.byteLength + (edge.weight?.byteLength ?? 0);\n return bytes + content.rows.numRows * 8 * 4;\n}\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\n/** The same array while the set of tiles in it is the same, so a reader can compare by identity. */\nfunction keep(previous: readonly TileView[], next: TileView[]): readonly TileView[] {\n if (previous.length !== next.length) return next;\n return next.every((view, i) => view.content === previous[i]?.content) ? previous : next;\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 matrix: TileMatrixSet | null = null;\n let typeIndex = 0;\n let modeColumn: string | null = null;\n let scan: Scan | null = null;\n let binding = NO_BINDING;\n let filter: Filter | undefined;\n let viewport: Viewport | null = null;\n let declined: Gap[] = [];\n let composed: readonly TileView[] | null = null;\n let unlisten: (() => void) | null = null;\n let active = false;\n let lastFrame = -1;\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. Anything later is\n // asynchronous or effect-driven and is reported as it happens.\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 const tileset = new Tileset2D({\n debounceTime: 60,\n load: async (addresses, signal) => {\n if (!corpus || !scan) throw new Error(\"the graph has no scan to read with\");\n const isCells = (address: TileAddress) => matrix?.tileMatrices[address.z]?.kind === \"cells\";\n const rows = await scan.read(addresses, { signal });\n const src = await corpus.edges({ from: addresses, direction: \"src\", signal });\n const payload = addresses.filter((address) => !isCells(address));\n const dst = payload.length > 0 ? await corpus.edges({ from: payload, direction: \"dst\", signal }) : [];\n const dstOf = new Map(payload.map((address, i) => [address, dst[i]]));\n return addresses.map((address, i) => {\n const out = src[i];\n const back = dstOf.get(address);\n const edges = [...(out?.batches ?? []), ...(back?.batches ?? [])];\n const gaps = [...(out?.declined ?? []), ...(back?.declined ?? [])];\n const declined = isCells(address) ? gaps.filter((gap) => gap.direction !== \"dst\") : gaps;\n const content = { rows: rows[i] as Batch, edges, declined };\n return { ...content, byteLength: bytesOf(content) };\n });\n },\n onTileLoad: (tile) => {\n for (const gap of tile.content?.declined ?? []) {\n if (!declined.some((d) => d.edgeType === gap.edgeType && d.direction === gap.direction)) {\n declined = [...declined, gap];\n }\n }\n tileset.refresh();\n notify();\n },\n onTileError: (error) => {\n tileset.refresh();\n fail(error);\n notify();\n },\n });\n\n let snapshot: GraphSnapshot = {\n status: \"none\",\n matrix: null,\n typeIndex: 0,\n modeColumn: null,\n binding: NO_BINDING,\n domain: [],\n z: null,\n visible: [],\n cached: [],\n pending: false,\n total: undefined,\n declined: [],\n selection: null,\n focus: null,\n hovered: null,\n pinned: [],\n tool: null,\n motion: \"settled\",\n progress: 1,\n drawn: null,\n options,\n corpus: null,\n };\n\n const viewOf = (tile: { address: TileAddress; content: TileContent | null }): TileView => ({\n address: tile.address,\n kind: matrix?.tileMatrices[tile.address.z]?.kind ?? \"rows\",\n content: tile.content as TileContent,\n });\n\n let domain: { key: unknown[]; value: readonly unknown[] } = { key: [], value: [] };\n function domainNow(): readonly unknown[] {\n const key = [corpus, typeIndex, binding.category, options.categories];\n if (key.some((part, i) => part !== domain.key[i])) domain = { key, value: domainOf(corpus, typeIndex, binding, options.categories) };\n return domain.value;\n }\n\n function statusOf(pending: boolean, visible: readonly TileView[]): GraphStatus {\n if (failed || unrenderable) return \"failed\";\n if (opening) return \"opening\";\n if (!corpus) return \"none\";\n return pending || composed !== visible || snapshot.drawn === null ? \"reading\" : \"idle\";\n }\n\n function notify(patch: Partial<GraphSnapshot> = {}): void {\n lastFrame = tileset.frame;\n const tiles = tileset.tiles.filter((tile) => tile.content !== null);\n const visible = keep(snapshot.visible, tiles.filter((tile) => tile.isVisible).map(viewOf));\n const pending = tileset.selectedTiles.some((tile) => tile.isLoading);\n snapshot = {\n ...snapshot,\n matrix,\n typeIndex,\n modeColumn,\n binding,\n domain: domainNow(),\n z: tileset.z,\n visible,\n cached: keep(snapshot.cached, tiles.map(viewOf)),\n pending,\n total: matrix ? Number(matrix.tileMatrices[matrix.tileMatrices.length - 1]?.count ?? 0) : undefined,\n declined,\n options,\n corpus,\n ...patch,\n };\n snapshot = { ...snapshot, status: statusOf(pending, snapshot.visible) };\n for (const listener of listeners) listener();\n }\n\n /** A binding or a filter is a new scan, planned once and never per camera move. */\n function rescan(): void {\n if (!corpus || !matrix) return;\n try {\n const fixed = [KEY, ...PAYLOAD_COORDINATES];\n scan = corpus.scan({ type: matrix.type, filter, select: projectionOf(binding, fixed) });\n tileset.setPlan(scan.plan());\n } catch (error) {\n scan = null;\n tileset.setPlan([]);\n fail(error);\n }\n tileset.reloadAll();\n if (viewport) tileset.update(viewport, options.limit ?? DEFAULT_LIMIT);\n notify();\n }\n\n function reopen(): void {\n failed = false;\n matrix = null;\n scan = null;\n declined = [];\n composed = null;\n tileset.finalize();\n const cleared = { selection: null, focus: null, hovered: null, pinned: [], drawn: null };\n if (!corpus) return notify(cleared);\n const types = corpus.types.vertices;\n const type = options.type ?? types.find((t) => t.geometry)?.type ?? types[0]?.type;\n typeIndex = Math.max(0, types.findIndex((t) => t.type === type));\n try {\n if (type === undefined) throw new Error(\"the corpus has no vertex type to draw\");\n matrix = corpus.tileMatrix(type);\n modeColumn = matrix.mode?.column ?? null;\n tileset.setMatrix(matrix);\n } catch (error) {\n failed = true;\n fail(error);\n }\n snapshot = { ...snapshot, ...cleared };\n rescan();\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 refilter = () => {\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 rescan();\n };\n if (crossfilter) {\n crossfilter.addEventListener(\"value\", refilter);\n unlisten = () => crossfilter.removeEventListener(\"value\", refilter);\n }\n refilter();\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 * tiles 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 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.size !== binding.size ||\n nextBinding.title !== binding.title;\n binding = nextBinding;\n if (next.corpus !== previous.corpus || next.type !== previous.type) {\n if (next.corpus !== previous.corpus) adopt(next.corpus);\n else reopen();\n if (active && next.filterBy !== previous.filterBy) listen();\n return;\n }\n if (active && next.filterBy !== previous.filterBy) listen();\n if (rebound) return rescan();\n if (next.limit !== previous.limit && viewport) tileset.update(viewport, next.limit ?? DEFAULT_LIMIT);\n notify();\n },\n destroy() {\n active = false;\n unlisten?.();\n unlisten = null;\n tileset.finalize();\n listeners.clear();\n },\n setViewport(next) {\n viewport = next;\n if (tileset.update(next, options.limit ?? DEFAULT_LIMIT) !== lastFrame) notify();\n },\n select(vertices, source = \"node\", label = \"\") {\n const selection = vertices && vertices.length > 0 ? { vertices: [...vertices], source, label } : null;\n notify({ selection });\n options.onSelect?.(selection);\n if (options.filterBy) publish(options.filterBy, self, KEY, selection ? selection.vertices.map(denseOf) : null);\n },\n focus(vertex) {\n if (vertex === snapshot.focus) return;\n notify({ focus: vertex });\n options.onFocus?.(vertex);\n },\n hover(vertex) {\n if (vertex !== snapshot.hovered) notify({ hovered: vertex });\n },\n pin(vertices) {\n notify({ pinned: [...vertices] });\n },\n setTool(tool) {\n if (tool !== snapshot.tool) notify({ tool });\n },\n report(motion) {\n if (motion !== snapshot.motion) notify({ motion });\n },\n reportProgress(value) {\n if (value !== snapshot.progress) notify({ progress: value });\n },\n setRenderable(renderable) {\n if (unrenderable === !renderable) return;\n unrenderable = !renderable;\n notify();\n },\n reportDrawn(visible, drawn) {\n if (composed === visible && drawn === null) return;\n composed = visible;\n notify(drawn ? { drawn } : {});\n },\n };\n\n binding = bindingOf(initial);\n adopt(initial.corpus);\n building = false;\n return store;\n}\n"],"names":["DEFAULT_LIMIT","NO_BINDING","bindingOf","KEY","PAYLOAD_ADDRESS","bytesOf","content","bytes","edge","_a","sameFilter","a","b","_","v","isPromise","value","keep","previous","next","view","i","createGraph","initial","options","listeners","self","graphClient","corpus","opening","failed","unrenderable","matrix","typeIndex","modeColumn","scan","binding","filter","viewport","declined","composed","unlisten","active","lastFrame","building","held","fail","error","message","tileset","Tileset2D","addresses","signal","isCells","address","rows","src","payload","dst","dstOf","out","back","edges","gaps","gap","tile","d","notify","snapshot","viewOf","domain","domainNow","key","part","domainOf","statusOf","pending","visible","patch","tiles","listener","rescan","fixed","PAYLOAD_COORDINATES","projectionOf","reopen","cleared","types","type","t","_b","_c","adopt","given","promised","opened","listen","crossfilter","refilter","filterFor","store","nextBinding","rebound","vertices","source","label","selection","publish","denseOf","vertex","tool","motion","renderable","drawn"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanzo-tech/graph",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "description": "Kanzo graph view — a tileset over a fossil corpus's scan, drawn with cosmos.gl, inside the page's Mosaic crossfilter. Sibling of @kanzo-tech/ui, not part of it: the admission rules exclude graphs from the generic vocabulary by name.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -23,18 +23,18 @@
23
23
  "./package.json": "./package.json"
24
24
  },
25
25
  "//peers": "All required. cosmos.gl draws; `lucide-react` is the icon set the parts draw their buttons with, `@kanzo-tech/ui`'s own peer; `@fossil-lang/corpus` is the backend — the host opens a corpus with its `open` on `@kanzo-tech/mosaic`'s `engine()` and this package draws it through `tileMatrix`, `scan` and `edges`, writing no SQL of its own; `@kanzo-tech/mosaic` carries the crossfilter the graph listens to and publishes into. They were optional while a root barrel with no source and a `./duckdb` entry with one existed side by side; there is one path now and nothing on it is optional (`/docs/design/graph`, *the one host path*). The Mosaic stack itself — mosaic-core, mosaic-sql — is `@kanzo-tech/mosaic`'s peer, declared once there.",
26
- "//fossil": "The floor is `0.3.0-alpha.13`, the release whose `scan(…).read` and `edges` take a list of addresses and answer one batch per tile, and an `Engine.query` that answers in columns and interrupts on abort, over corpora whose `dense_id` is the Hilbert rank. Only types and the writer's role table (`PAYLOAD_*`) are imported; `src/layers.test.ts` holds that.",
26
+ "//fossil": "The floor is `0.3.0-alpha.14`, the release whose `scan(…).read` and `edges` take a list of addresses and answer one batch per tile, and an `Engine.query` that answers in columns and interrupts on abort, over corpora whose `dense_id` is the Hilbert rank. Only types and the writer's role table (`PAYLOAD_*`) are imported; `src/layers.test.ts` holds that.",
27
27
  "peerDependencies": {
28
28
  "@cosmos.gl/graph": "^3.4.0",
29
- "@fossil-lang/corpus": "^0.3.0-alpha.13",
29
+ "@fossil-lang/corpus": "^0.3.0-alpha.14",
30
30
  "lucide-react": ">=1",
31
31
  "react": "^19.0.0",
32
- "@kanzo-tech/mosaic": "0.12.0",
33
- "@kanzo-tech/ui": "0.12.0"
32
+ "@kanzo-tech/mosaic": "0.13.1",
33
+ "@kanzo-tech/ui": "0.13.1"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@cosmos.gl/graph": "^3.4.0",
37
- "@fossil-lang/corpus": "^0.3.0-alpha.13",
37
+ "@fossil-lang/corpus": "^0.3.0-alpha.14",
38
38
  "@testing-library/dom": "^10.4.1",
39
39
  "@testing-library/react": "^16.3.2",
40
40
  "@types/react": "^19.0.0",
@@ -46,7 +46,7 @@
46
46
  "react": "^19.0.0",
47
47
  "react-dom": "^19.0.0",
48
48
  "rollup-plugin-preserve-directives": "^0.4.0",
49
- "@kanzo-tech/mosaic": "0.12.0"
49
+ "@kanzo-tech/mosaic": "0.13.1"
50
50
  },
51
51
  "repository": {
52
52
  "type": "git",