@kanzo-tech/graph 0.13.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.
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +108 -110
- package/dist/core/store.js.map +1 -1
- package/package.json +7 -7
package/dist/core/store.d.ts.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/core/store.js
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
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
|
|
3
|
+
import { bindingOf as Y, projectionOf as ie } from "./channels.js";
|
|
4
4
|
import { graphClient as se, publish as ce, filterFor as fe } from "./filter.js";
|
|
5
5
|
import { denseOf as ue } from "./resident.js";
|
|
6
6
|
import { Tileset2D as de } from "./tileset.js";
|
|
7
|
-
const
|
|
7
|
+
const R = 2e4, H = Y({}), Q = le[0];
|
|
8
8
|
function ae(i) {
|
|
9
|
-
var
|
|
9
|
+
var p;
|
|
10
10
|
let n = 0;
|
|
11
|
-
for (const s of i.edges) n += s.src.byteLength + s.dst.byteLength + (((
|
|
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 pe = (i, n) => JSON.stringify(i, (
|
|
15
|
-
function
|
|
16
|
-
return i.length !== n.length ? n : n.every((
|
|
17
|
-
var
|
|
18
|
-
return
|
|
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
|
|
21
|
+
function Le(i) {
|
|
22
22
|
let n = i;
|
|
23
|
-
const
|
|
24
|
-
let
|
|
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
26
|
const t = e instanceof Error ? e.message : String(e);
|
|
27
|
-
|
|
28
|
-
},
|
|
27
|
+
V ? I = t : n.onFailure(t);
|
|
28
|
+
}, d = new de({
|
|
29
29
|
debounceTime: 60,
|
|
30
30
|
load: async (e, t) => {
|
|
31
|
-
if (!
|
|
32
|
-
const l = (
|
|
33
|
-
var
|
|
34
|
-
return ((
|
|
35
|
-
},
|
|
36
|
-
return e.map((
|
|
37
|
-
const v =
|
|
38
|
-
return { ...
|
|
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) };
|
|
39
39
|
});
|
|
40
40
|
},
|
|
41
41
|
onTileLoad: (e) => {
|
|
42
42
|
var t;
|
|
43
43
|
for (const l of ((t = e.content) == null ? void 0 : t.declined) ?? [])
|
|
44
|
-
E.some((
|
|
45
|
-
|
|
44
|
+
E.some((o) => o.edgeType === l.edgeType && o.direction === l.direction) || (E = [...E, l]);
|
|
45
|
+
d.refresh(), u();
|
|
46
46
|
},
|
|
47
47
|
onTileError: (e) => {
|
|
48
|
-
|
|
48
|
+
d.refresh(), D(e), u();
|
|
49
49
|
}
|
|
50
50
|
});
|
|
51
|
-
let
|
|
51
|
+
let f = {
|
|
52
52
|
status: "none",
|
|
53
53
|
matrix: null,
|
|
54
54
|
typeIndex: 0,
|
|
55
55
|
modeColumn: null,
|
|
56
|
-
binding:
|
|
56
|
+
binding: H,
|
|
57
57
|
domain: [],
|
|
58
58
|
z: null,
|
|
59
59
|
visible: [],
|
|
@@ -72,169 +72,167 @@ function ve(i) {
|
|
|
72
72
|
options: n,
|
|
73
73
|
corpus: null
|
|
74
74
|
};
|
|
75
|
-
const
|
|
75
|
+
const $ = (e) => {
|
|
76
76
|
var t;
|
|
77
77
|
return {
|
|
78
78
|
address: e.address,
|
|
79
|
-
kind: ((t =
|
|
79
|
+
kind: ((t = c == null ? void 0 : c.tileMatrices[e.address.z]) == null ? void 0 : t.kind) ?? "rows",
|
|
80
80
|
content: e.content
|
|
81
81
|
};
|
|
82
82
|
};
|
|
83
83
|
let _ = { key: [], value: [] };
|
|
84
|
-
function
|
|
85
|
-
const e = [
|
|
86
|
-
return e.some((t, l) => t !== _.key[l]) && (_ = { key: e, value: re(
|
|
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;
|
|
87
87
|
}
|
|
88
|
-
function
|
|
89
|
-
return M ||
|
|
88
|
+
function Z(e, t) {
|
|
89
|
+
return M || F ? "failed" : h ? "opening" : r ? e || A !== t || f.drawn === null ? "reading" : "idle" : "none";
|
|
90
90
|
}
|
|
91
|
-
function
|
|
92
|
-
var
|
|
93
|
-
|
|
94
|
-
const t =
|
|
95
|
-
|
|
96
|
-
...
|
|
97
|
-
matrix:
|
|
98
|
-
typeIndex:
|
|
99
|
-
modeColumn:
|
|
100
|
-
binding:
|
|
101
|
-
domain:
|
|
102
|
-
z:
|
|
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,
|
|
99
|
+
modeColumn: G,
|
|
100
|
+
binding: y,
|
|
101
|
+
domain: X(),
|
|
102
|
+
z: d.z,
|
|
103
103
|
visible: l,
|
|
104
|
-
cached:
|
|
105
|
-
pending:
|
|
106
|
-
total:
|
|
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,
|
|
107
107
|
declined: E,
|
|
108
108
|
options: n,
|
|
109
|
-
corpus:
|
|
109
|
+
corpus: r,
|
|
110
110
|
...e
|
|
111
|
-
},
|
|
112
|
-
for (const
|
|
111
|
+
}, f = { ...f, status: Z(o, f.visible) };
|
|
112
|
+
for (const a of p) a();
|
|
113
113
|
}
|
|
114
|
-
function
|
|
115
|
-
if (!(!
|
|
114
|
+
function C() {
|
|
115
|
+
if (!(!r || !c)) {
|
|
116
116
|
try {
|
|
117
|
-
const e = [
|
|
118
|
-
|
|
117
|
+
const e = [Q, ...oe];
|
|
118
|
+
L = r.scan({ type: c.type, filter: P, select: ie(y, e) }), d.setPlan(L.plan());
|
|
119
119
|
} catch (e) {
|
|
120
|
-
|
|
120
|
+
L = null, d.setPlan([]), D(e);
|
|
121
121
|
}
|
|
122
|
-
|
|
122
|
+
d.reloadAll(), z && d.update(z, n.limit ?? R), u();
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
|
-
function
|
|
126
|
-
var
|
|
127
|
-
M = !1,
|
|
125
|
+
function N() {
|
|
126
|
+
var o, m, a;
|
|
127
|
+
M = !1, c = null, L = null, E = [], A = null, d.finalize();
|
|
128
128
|
const e = { selection: null, focus: null, hovered: null, pinned: [], drawn: null };
|
|
129
|
-
if (!
|
|
130
|
-
const t =
|
|
131
|
-
|
|
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));
|
|
132
132
|
try {
|
|
133
133
|
if (l === void 0) throw new Error("the corpus has no vertex type to draw");
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
} catch (u) {
|
|
138
|
-
M = !0, D(u);
|
|
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);
|
|
139
137
|
}
|
|
140
|
-
|
|
138
|
+
f = { ...f, ...e }, C();
|
|
141
139
|
}
|
|
142
|
-
function
|
|
143
|
-
if (
|
|
144
|
-
return
|
|
145
|
-
const t =
|
|
146
|
-
|
|
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(
|
|
147
145
|
(l) => {
|
|
148
|
-
|
|
146
|
+
h === t && (h = null, r = l, N());
|
|
149
147
|
},
|
|
150
148
|
(l) => {
|
|
151
|
-
|
|
149
|
+
h === t && (h = null, M = !0, D(l), u());
|
|
152
150
|
}
|
|
153
151
|
);
|
|
154
152
|
}
|
|
155
|
-
function
|
|
156
|
-
|
|
153
|
+
function k() {
|
|
154
|
+
g == null || g(), g = null;
|
|
157
155
|
const e = n.filterBy, t = () => {
|
|
158
156
|
let l;
|
|
159
157
|
try {
|
|
160
158
|
l = e ? fe(e, s) : void 0;
|
|
161
|
-
} catch (
|
|
162
|
-
D(
|
|
159
|
+
} catch (o) {
|
|
160
|
+
D(o);
|
|
163
161
|
return;
|
|
164
162
|
}
|
|
165
|
-
pe(l, P) || (P = l,
|
|
163
|
+
pe(l, P) || (P = l, C());
|
|
166
164
|
};
|
|
167
|
-
e && (e.addEventListener("value", t),
|
|
165
|
+
e && (e.addEventListener("value", t), g = () => e.removeEventListener("value", t)), t();
|
|
168
166
|
}
|
|
169
|
-
const
|
|
167
|
+
const K = {
|
|
170
168
|
/**
|
|
171
169
|
* The first subscriber starts listening to the crossfilter and the last one stops it and lets the
|
|
172
170
|
* tiles go — `QueryObserver`'s `onSubscribe`/`onUnsubscribe`, which is what survives StrictMode
|
|
173
171
|
* mounting everything twice.
|
|
174
172
|
*/
|
|
175
173
|
subscribe(e) {
|
|
176
|
-
if (
|
|
177
|
-
const t =
|
|
178
|
-
|
|
174
|
+
if (p.add(e), !B && (B = !0, k(), I !== null)) {
|
|
175
|
+
const t = I;
|
|
176
|
+
I = null, n.onFailure(t);
|
|
179
177
|
}
|
|
180
178
|
return () => {
|
|
181
|
-
|
|
179
|
+
p.delete(e), p.size === 0 && K.destroy();
|
|
182
180
|
};
|
|
183
181
|
},
|
|
184
|
-
getSnapshot: () =>
|
|
182
|
+
getSnapshot: () => f,
|
|
185
183
|
getOptions: () => n,
|
|
186
184
|
setOptions(e) {
|
|
187
185
|
const t = n;
|
|
188
186
|
n = e;
|
|
189
|
-
const l =
|
|
190
|
-
if (
|
|
191
|
-
e.corpus !== t.corpus ?
|
|
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();
|
|
192
190
|
return;
|
|
193
191
|
}
|
|
194
|
-
if (B && e.filterBy !== t.filterBy &&
|
|
195
|
-
e.limit !== t.limit && z &&
|
|
192
|
+
if (B && e.filterBy !== t.filterBy && k(), o) return C();
|
|
193
|
+
e.limit !== t.limit && z && d.update(z, e.limit ?? R), u();
|
|
196
194
|
},
|
|
197
195
|
destroy() {
|
|
198
|
-
B = !1,
|
|
196
|
+
B = !1, g == null || g(), g = null, d.finalize(), p.clear();
|
|
199
197
|
},
|
|
200
198
|
setViewport(e) {
|
|
201
|
-
z = e,
|
|
199
|
+
z = e, d.update(e, n.limit ?? R) !== J && u();
|
|
202
200
|
},
|
|
203
201
|
select(e, t = "node", l = "") {
|
|
204
|
-
var
|
|
205
|
-
const
|
|
206
|
-
|
|
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);
|
|
207
205
|
},
|
|
208
206
|
focus(e) {
|
|
209
207
|
var t;
|
|
210
|
-
e !==
|
|
208
|
+
e !== f.focus && (u({ focus: e }), (t = n.onFocus) == null || t.call(n, e));
|
|
211
209
|
},
|
|
212
210
|
hover(e) {
|
|
213
|
-
e !==
|
|
211
|
+
e !== f.hovered && u({ hovered: e });
|
|
214
212
|
},
|
|
215
213
|
pin(e) {
|
|
216
|
-
|
|
214
|
+
u({ pinned: [...e] });
|
|
217
215
|
},
|
|
218
216
|
setTool(e) {
|
|
219
|
-
e !==
|
|
217
|
+
e !== f.tool && u({ tool: e });
|
|
220
218
|
},
|
|
221
219
|
report(e) {
|
|
222
|
-
e !==
|
|
220
|
+
e !== f.motion && u({ motion: e });
|
|
223
221
|
},
|
|
224
222
|
reportProgress(e) {
|
|
225
|
-
e !==
|
|
223
|
+
e !== f.progress && u({ progress: e });
|
|
226
224
|
},
|
|
227
225
|
setRenderable(e) {
|
|
228
|
-
|
|
226
|
+
F !== !e && (F = !e, u());
|
|
229
227
|
},
|
|
230
228
|
reportDrawn(e, t) {
|
|
231
|
-
|
|
229
|
+
A === e && t === null || (A = e, u(t ? { drawn: t } : {}));
|
|
232
230
|
}
|
|
233
231
|
};
|
|
234
|
-
return
|
|
232
|
+
return y = Y(i), j(i.corpus), V = !1, K;
|
|
235
233
|
}
|
|
236
234
|
export {
|
|
237
|
-
|
|
238
|
-
|
|
235
|
+
R as DEFAULT_LIMIT,
|
|
236
|
+
Le as createGraph
|
|
239
237
|
};
|
|
240
238
|
//# 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 {\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 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 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","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.13.
|
|
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.
|
|
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.
|
|
29
|
+
"@fossil-lang/corpus": "^0.3.0-alpha.14",
|
|
30
30
|
"lucide-react": ">=1",
|
|
31
31
|
"react": "^19.0.0",
|
|
32
|
-
"@kanzo-tech/mosaic": "0.13.
|
|
33
|
-
"@kanzo-tech/ui": "0.13.
|
|
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.
|
|
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.13.
|
|
49
|
+
"@kanzo-tech/mosaic": "0.13.1"
|
|
50
50
|
},
|
|
51
51
|
"repository": {
|
|
52
52
|
"type": "git",
|