@kanzo-tech/graph 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bounded.d.ts +115 -40
- package/dist/bounded.d.ts.map +1 -1
- package/dist/bounded.js +13 -34
- package/dist/bounded.js.map +1 -1
- package/dist/duck-source.d.ts.map +1 -1
- package/dist/duck-source.js +165 -166
- package/dist/duck-source.js.map +1 -1
- package/dist/graph-canvas.d.ts +1 -1
- package/dist/graph-canvas.js.map +1 -1
- package/dist/graph-looks.d.ts +63 -18
- package/dist/graph-looks.d.ts.map +1 -1
- package/dist/graph-looks.js +37 -26
- package/dist/graph-looks.js.map +1 -1
- package/dist/graph-model.d.ts +2 -2
- package/dist/graph-model.d.ts.map +1 -1
- package/dist/graph-model.js +19 -14
- package/dist/graph-model.js.map +1 -1
- package/dist/graph-sim.d.ts +15 -1
- package/dist/graph-sim.d.ts.map +1 -1
- package/dist/graph-sim.js +17 -13
- package/dist/graph-sim.js.map +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -49
- package/dist/index.js.map +1 -1
- package/dist/memory-source.d.ts.map +1 -1
- package/dist/memory-source.js +99 -92
- package/dist/memory-source.js.map +1 -1
- package/dist/obligations.d.ts +1 -3
- package/dist/obligations.d.ts.map +1 -1
- package/dist/shape-glyph.d.ts +30 -0
- package/dist/shape-glyph.d.ts.map +1 -0
- package/dist/shape-glyph.js +15 -0
- package/dist/shape-glyph.js.map +1 -0
- package/dist/slice-client.d.ts.map +1 -1
- package/dist/slice-client.js +36 -36
- package/dist/slice-client.js.map +1 -1
- package/dist/use-graph-overlays.d.ts +21 -30
- package/dist/use-graph-overlays.d.ts.map +1 -1
- package/dist/use-graph-overlays.js +39 -37
- package/dist/use-graph-overlays.js.map +1 -1
- package/dist/use-graph.d.ts +38 -10
- package/dist/use-graph.d.ts.map +1 -1
- package/dist/use-graph.js +66 -65
- package/dist/use-graph.js.map +1 -1
- package/dist/use-query-loop.d.ts +6 -0
- package/dist/use-query-loop.d.ts.map +1 -1
- package/dist/use-query-loop.js +88 -70
- package/dist/use-query-loop.js.map +1 -1
- package/dist/use-renderer.d.ts.map +1 -1
- package/dist/use-renderer.js +69 -66
- package/dist/use-renderer.js.map +1 -1
- package/package.json +4 -4
package/dist/duck-source.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { numbers as k, clausePoints as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
function tt(t, e) {
|
|
2
|
+
import { numbers as k, clausePoints as $t, fillColumn as M, column as pt } from "@kanzo-tech/mosaic";
|
|
3
|
+
import { SliceRead as W } from "./slice-client.js";
|
|
4
|
+
import { typeOf as xt, denseOf as tt, vertexId as At } from "./resident.js";
|
|
5
|
+
function et(t, e) {
|
|
7
6
|
return {
|
|
8
|
-
points: new
|
|
9
|
-
links: new
|
|
10
|
-
meta: new
|
|
7
|
+
points: new W(t, e),
|
|
8
|
+
links: new W(t, e),
|
|
9
|
+
meta: new W(t)
|
|
11
10
|
};
|
|
12
11
|
}
|
|
13
|
-
function
|
|
12
|
+
function nt(t) {
|
|
14
13
|
let e = Promise.resolve();
|
|
15
14
|
return (n) => {
|
|
16
15
|
const s = e.then(() => t.ask(() => n));
|
|
@@ -18,31 +17,31 @@ function et(t) {
|
|
|
18
17
|
}), s;
|
|
19
18
|
};
|
|
20
19
|
}
|
|
21
|
-
function
|
|
20
|
+
function Q(t) {
|
|
22
21
|
if (t == null) return "";
|
|
23
22
|
const n = (Array.isArray(t) ? t : [t]).filter((s) => s != null).map((s) => String(s));
|
|
24
23
|
return n.length > 0 ? n.map((s) => `(${s})`).join(" AND ") : "";
|
|
25
24
|
}
|
|
26
|
-
function
|
|
25
|
+
function st(t, e) {
|
|
27
26
|
return t ? e ? `(${t}) AND (${e})` : t : e || "TRUE";
|
|
28
27
|
}
|
|
29
|
-
function
|
|
30
|
-
const { coordinator: e, edges: n, filterBy: s, nodes:
|
|
28
|
+
function wt(t) {
|
|
29
|
+
const { coordinator: e, edges: n, filterBy: s, nodes: r, typeIndex: i } = t, c = {
|
|
31
30
|
id: t.idField ?? "id",
|
|
32
31
|
subject: t.subjectField,
|
|
33
32
|
x: t.xField ?? "x",
|
|
34
33
|
y: t.yField ?? "y",
|
|
35
34
|
source: t.sourceField ?? "source",
|
|
36
35
|
target: t.targetField ?? "target"
|
|
37
|
-
}, l =
|
|
36
|
+
}, l = et(e, s), E = nt(l.meta), y = it(l);
|
|
38
37
|
return {
|
|
39
|
-
...
|
|
40
|
-
publish(
|
|
41
|
-
|
|
38
|
+
...y.api,
|
|
39
|
+
publish(p) {
|
|
40
|
+
ot(l, s, c.id, p);
|
|
42
41
|
},
|
|
43
42
|
async total() {
|
|
44
|
-
const
|
|
45
|
-
return Number(k(
|
|
43
|
+
const p = await E(`SELECT count(*) AS n FROM ${r}`);
|
|
44
|
+
return Number(k(p, "n")[0] ?? 0);
|
|
46
45
|
},
|
|
47
46
|
/**
|
|
48
47
|
* Four aggregates, so the canvas can frame what is actually there.
|
|
@@ -51,12 +50,12 @@ function _t(t) {
|
|
|
51
50
|
* default box and finds the corpus occupying a corner of it.
|
|
52
51
|
*/
|
|
53
52
|
async extent() {
|
|
54
|
-
const
|
|
53
|
+
const p = await E(
|
|
55
54
|
`SELECT min(${c.x}) AS x0, max(${c.x}) AS x1,
|
|
56
55
|
min(${c.y}) AS y0, max(${c.y}) AS y1
|
|
57
|
-
FROM ${
|
|
58
|
-
),
|
|
59
|
-
return { xMin:
|
|
56
|
+
FROM ${r}`
|
|
57
|
+
), x = (f) => Number(k(p, f)[0] ?? 0);
|
|
58
|
+
return { xMin: x("x0"), yMin: x("y0"), xMax: x("x1"), yMax: x("y1") };
|
|
60
59
|
},
|
|
61
60
|
/**
|
|
62
61
|
* Regions only, and it says so by **not having** `explore`.
|
|
@@ -66,49 +65,49 @@ function _t(t) {
|
|
|
66
65
|
* unbounded pattern wearing a bounded interface. It used to say that with a predicate and a
|
|
67
66
|
* throw; now the absence is the statement, and asking is a compile error.
|
|
68
67
|
*/
|
|
69
|
-
async slice(
|
|
70
|
-
const { fill:
|
|
71
|
-
return
|
|
72
|
-
|
|
68
|
+
async slice(p) {
|
|
69
|
+
const { fill: x, limit: f, minLinkPixels: N, perPixel: $, pinned: O, r: g, view: F } = p, A = { ...c, category: x, size: g };
|
|
70
|
+
return y.run(
|
|
71
|
+
rt(r, n, A, F, f, i, O, $, N, void 0)
|
|
73
72
|
);
|
|
74
73
|
}
|
|
75
74
|
};
|
|
76
75
|
}
|
|
77
|
-
function
|
|
76
|
+
function St(t, e) {
|
|
78
77
|
const s = [
|
|
79
78
|
[t.x, e.xMin, ">="],
|
|
80
79
|
[t.x, e.xMax, "<="],
|
|
81
80
|
[t.y, e.yMin, ">="],
|
|
82
81
|
[t.y, e.yMax, "<="]
|
|
83
|
-
].filter(([,
|
|
82
|
+
].filter(([, r]) => Number.isFinite(r)).map(([r, i, c]) => `${r} ${c} ${i}`);
|
|
84
83
|
return s.length > 0 ? s.join(" AND ") : "TRUE";
|
|
85
84
|
}
|
|
86
|
-
const
|
|
87
|
-
function
|
|
88
|
-
const
|
|
85
|
+
const ht = (t) => `greatest(1, CAST(ceil(matched / ${t}.0) AS BIGINT))`;
|
|
86
|
+
function q(t, e, n, s, r = !0) {
|
|
87
|
+
const i = e.size ? `, ${e.size} AS size` : "", c = e.subject ? `, ${e.subject} AS subject` : "", l = e.category ? "(dense_rank() OVER (ORDER BY cat) - 1)::INTEGER AS category" : "0::INTEGER AS category";
|
|
89
88
|
return `WITH pool AS (
|
|
90
|
-
SELECT ${e.id} AS id, ${e.x} AS x, ${e.y} AS y${
|
|
89
|
+
SELECT ${e.id} AS id, ${e.x} AS x, ${e.y} AS y${i}${c}${e.category ? `, ${e.category} AS cat` : ""},
|
|
91
90
|
count(*) OVER () AS matched
|
|
92
91
|
FROM ${t}
|
|
93
92
|
WHERE ${n}
|
|
94
93
|
), vis AS (
|
|
95
|
-
SELECT id, x, y${e.size ? ", size" : ""}${e.subject ? ", subject" : ""}${
|
|
94
|
+
SELECT id, x, y${e.size ? ", size" : ""}${e.subject ? ", subject" : ""}${r ? ", matched" : ""},
|
|
96
95
|
${l},
|
|
97
96
|
(row_number() OVER (ORDER BY id) - 1)::INTEGER AS local
|
|
98
97
|
FROM pool
|
|
99
|
-
WHERE id % ${
|
|
98
|
+
WHERE id % ${ht(s)} = 0
|
|
100
99
|
LIMIT ${s}
|
|
101
100
|
)`;
|
|
102
101
|
}
|
|
103
|
-
function
|
|
102
|
+
function at(t, e, n, s) {
|
|
104
103
|
if (n === void 0 || !Number.isFinite(n) || n <= 0) return "";
|
|
105
|
-
const
|
|
106
|
-
return `(${t}.x - ${e}.x) * (${t}.x - ${e}.x) + (${t}.y - ${e}.y) * (${t}.y - ${e}.y) >= ${
|
|
104
|
+
const r = s * n;
|
|
105
|
+
return `(${t}.x - ${e}.x) * (${t}.x - ${e}.x) + (${t}.y - ${e}.y) * (${t}.y - ${e}.y) >= ${r * r}`;
|
|
107
106
|
}
|
|
108
|
-
function
|
|
109
|
-
const
|
|
107
|
+
function ft(t, e, n, s, r, i, c) {
|
|
108
|
+
const l = st(`NOT (${s})`, r), E = at("a", "b", i, c);
|
|
110
109
|
return `, out AS (
|
|
111
|
-
SELECT ${n.id} AS id, ${n.x} AS x, ${n.y} AS y FROM ${t} WHERE ${
|
|
110
|
+
SELECT ${n.id} AS id, ${n.x} AS x, ${n.y} AS y FROM ${t} WHERE ${l}
|
|
112
111
|
), reach AS (
|
|
113
112
|
SELECT id, x, y FROM vis UNION ALL SELECT id, x, y FROM out
|
|
114
113
|
), span AS (
|
|
@@ -118,7 +117,7 @@ function Nt(t, e, n, s, i, r) {
|
|
|
118
117
|
JOIN reach b ON e.${n.target} = b.id
|
|
119
118
|
LEFT JOIN vis sv ON sv.id = a.id
|
|
120
119
|
LEFT JOIN vis tv ON tv.id = b.id
|
|
121
|
-
WHERE (sv.id IS NOT NULL OR tv.id IS NOT NULL)${
|
|
120
|
+
WHERE (sv.id IS NOT NULL OR tv.id IS NOT NULL)${E ? ` AND ${E}` : ""}
|
|
122
121
|
), anchor AS (
|
|
123
122
|
SELECT o.id, o.x, o.y,
|
|
124
123
|
((SELECT count(*) FROM vis) + row_number() OVER (ORDER BY o.id) - 1)::INTEGER AS local
|
|
@@ -127,8 +126,8 @@ function Nt(t, e, n, s, i, r) {
|
|
|
127
126
|
UNION SELECT dst_id FROM span WHERE dst IS NULL)
|
|
128
127
|
)`;
|
|
129
128
|
}
|
|
130
|
-
function
|
|
131
|
-
const
|
|
129
|
+
function rt(t, e, n, s, r, i, c, l, E, y) {
|
|
130
|
+
const p = St(n, s), x = (c ?? []).filter((u) => xt(u) === i).map(tt), f = x.length > 0 ? ` OR ${n.id} IN (${x.join(",")})` : "", N = `(${p})${f}`, $ = (u) => st(N, Q(u)), O = n.size ? ", size" : "", g = n.subject ? ", subject" : "", F = at("s", "t", l, E), A = (u) => y ? ft(y, e, n, N, Q(u), l, E) : "";
|
|
132
131
|
return {
|
|
133
132
|
/**
|
|
134
133
|
* The marks, then the anchors, in one answer — because they are one buffer.
|
|
@@ -137,8 +136,8 @@ function at(t, e, n, s, i, r, c, l, m) {
|
|
|
137
136
|
* and continues past it over the anchors, so ordering by it puts every mark before every anchor
|
|
138
137
|
* and makes `marks` a prefix length. `matched` is then still read off row zero.
|
|
139
138
|
*/
|
|
140
|
-
points: (u) => `${
|
|
141
|
-
SELECT local, id, x, y, category, matched, TRUE AS mark${
|
|
139
|
+
points: (u) => `${q(t, n, $(u), r)}${A(u)}
|
|
140
|
+
SELECT local, id, x, y, category, matched, TRUE AS mark${O}${g} FROM vis${y ? `
|
|
142
141
|
UNION ALL
|
|
143
142
|
SELECT local, id, x, y, 0::INTEGER, NULL::BIGINT, FALSE AS mark${n.size ? ", CAST(NULL AS DOUBLE)" : ""}${n.subject ? ", CAST(NULL AS VARCHAR)" : ""} FROM anchor` : ""}
|
|
144
143
|
ORDER BY local`,
|
|
@@ -150,17 +149,17 @@ function at(t, e, n, s, i, r, c, l, m) {
|
|
|
150
149
|
* exact rather than a limitation of the reader: no bytes beyond the rectangle were fetched, so
|
|
151
150
|
* there is no position to draw the far end at. A corpus fetches tiles and therefore has some.
|
|
152
151
|
*/
|
|
153
|
-
links: (u) =>
|
|
152
|
+
links: (u) => y ? `${q(t, n, $(u), r, !1)}${A(u)}
|
|
154
153
|
SELECT coalesce(sp.src, sa.local) AS src, coalesce(sp.dst, da.local) AS dst
|
|
155
154
|
FROM span sp
|
|
156
155
|
LEFT JOIN anchor sa ON sa.id = sp.src_id
|
|
157
|
-
LEFT JOIN anchor da ON da.id = sp.dst_id` : `${
|
|
156
|
+
LEFT JOIN anchor da ON da.id = sp.dst_id` : `${q(t, n, $(u), r, !1)}
|
|
158
157
|
SELECT s.local AS src, t.local AS dst
|
|
159
158
|
FROM ${e} e
|
|
160
159
|
JOIN vis s ON e.${n.source} = s.id
|
|
161
|
-
JOIN vis t ON e.${n.target} = t.id${
|
|
162
|
-
WHERE ${
|
|
163
|
-
assemble: (u,
|
|
160
|
+
JOIN vis t ON e.${n.target} = t.id${F ? `
|
|
161
|
+
WHERE ${F}` : ""}`,
|
|
162
|
+
assemble: (u, D) => ({
|
|
164
163
|
/**
|
|
165
164
|
* How many matched, separately from how many came back.
|
|
166
165
|
*
|
|
@@ -170,16 +169,16 @@ function at(t, e, n, s, i, r, c, l, m) {
|
|
|
170
169
|
* column, and an empty answer has no row and no matches, which agree.
|
|
171
170
|
*/
|
|
172
171
|
n: Number(k(u, "matched")[0] ?? 0),
|
|
173
|
-
...
|
|
172
|
+
...Nt(u, D, i, n.size ? "size" : void 0, n.subject !== void 0)
|
|
174
173
|
})
|
|
175
174
|
};
|
|
176
175
|
}
|
|
177
|
-
function
|
|
176
|
+
function it(t) {
|
|
178
177
|
let e = null, n = null;
|
|
179
|
-
const s = /* @__PURE__ */ new Map(),
|
|
180
|
-
if (!e || !n || (s.set(
|
|
181
|
-
const l = s.get("points"),
|
|
182
|
-
s.clear(), n(e.assemble(l,
|
|
178
|
+
const s = /* @__PURE__ */ new Map(), r = (i) => (c) => {
|
|
179
|
+
if (!e || !n || (s.set(i, c), s.size < 2)) return;
|
|
180
|
+
const l = s.get("points"), E = s.get("links");
|
|
181
|
+
s.clear(), n(e.assemble(l, E));
|
|
183
182
|
};
|
|
184
183
|
return {
|
|
185
184
|
api: {
|
|
@@ -190,62 +189,62 @@ function rt(t) {
|
|
|
190
189
|
* has *already* re-run both reads with the new predicate by the time we hear about it. Asking
|
|
191
190
|
* again would run the same two queries a second time to learn what is in hand.
|
|
192
191
|
*/
|
|
193
|
-
watch(
|
|
194
|
-
return n =
|
|
192
|
+
watch(i) {
|
|
193
|
+
return n = i, t.points.onAnswer = r("points"), t.links.onAnswer = r("links"), () => {
|
|
195
194
|
n = null, s.clear(), e = null, t.points.release(), t.links.release(), t.meta.release();
|
|
196
195
|
};
|
|
197
196
|
}
|
|
198
197
|
},
|
|
199
|
-
async run(
|
|
200
|
-
e =
|
|
198
|
+
async run(i) {
|
|
199
|
+
e = i, s.clear();
|
|
201
200
|
const [c, l] = await Promise.all([
|
|
202
|
-
t.points.ask(
|
|
203
|
-
t.links.ask(
|
|
201
|
+
t.points.ask(i.points),
|
|
202
|
+
t.links.ask(i.links)
|
|
204
203
|
]);
|
|
205
|
-
return
|
|
204
|
+
return i.assemble(c, l);
|
|
206
205
|
}
|
|
207
206
|
};
|
|
208
207
|
}
|
|
209
|
-
function
|
|
208
|
+
function ot(t, e, n, s) {
|
|
210
209
|
e && e.update(
|
|
211
|
-
|
|
210
|
+
$t([n], s == null ? void 0 : s.map((r) => [tt(r)]), {
|
|
212
211
|
source: t.points,
|
|
213
212
|
clients: /* @__PURE__ */ new Set([t.points, t.links])
|
|
214
213
|
})
|
|
215
214
|
);
|
|
216
215
|
}
|
|
217
|
-
function
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
let
|
|
223
|
-
for (;
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
const
|
|
227
|
-
for (let
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
const
|
|
231
|
-
let
|
|
232
|
-
s && (
|
|
233
|
-
const
|
|
234
|
-
return
|
|
235
|
-
marks:
|
|
236
|
-
vertices:
|
|
237
|
-
subjects:
|
|
216
|
+
function Nt(t, e, n, s, r = !1) {
|
|
217
|
+
const i = X(t, "x"), c = new Float32Array(i * 2), l = M(t, "x", c, 0, 2);
|
|
218
|
+
M(t, "y", c, 1, 2);
|
|
219
|
+
const E = new Int32Array(i);
|
|
220
|
+
M(t, "mark", E);
|
|
221
|
+
let y = 0;
|
|
222
|
+
for (; y < l && E[y] !== 0; ) y++;
|
|
223
|
+
const p = new Float64Array(l);
|
|
224
|
+
M(t, "id", p);
|
|
225
|
+
const x = new BigUint64Array(l);
|
|
226
|
+
for (let A = 0; A < l; A++) x[A] = At(n, p[A]);
|
|
227
|
+
const f = new Uint16Array(l);
|
|
228
|
+
M(t, "category", f);
|
|
229
|
+
const N = r ? pt(t, "subject") : void 0;
|
|
230
|
+
let $;
|
|
231
|
+
s && ($ = new Float32Array(l), M(t, s, $));
|
|
232
|
+
const O = X(e, "src"), g = new Float32Array(O * 2), F = M(e, "src", g, 0, 2);
|
|
233
|
+
return M(e, "dst", g, 1, 2), {
|
|
234
|
+
marks: y,
|
|
235
|
+
vertices: x,
|
|
236
|
+
subjects: N,
|
|
238
237
|
positions: c.subarray(0, l * 2),
|
|
239
|
-
links:
|
|
240
|
-
categories:
|
|
241
|
-
sizes:
|
|
238
|
+
links: g.subarray(0, F * 2),
|
|
239
|
+
categories: f,
|
|
240
|
+
sizes: $
|
|
242
241
|
};
|
|
243
242
|
}
|
|
244
|
-
function
|
|
245
|
-
var
|
|
243
|
+
function X(t, e) {
|
|
244
|
+
var r;
|
|
246
245
|
const n = t == null ? void 0 : t.numRows;
|
|
247
246
|
if (typeof n == "number") return n;
|
|
248
|
-
const s = (
|
|
247
|
+
const s = (r = t == null ? void 0 : t.getChild) == null ? void 0 : r.call(t, e);
|
|
249
248
|
return s ? s.length : Array.from(t).length;
|
|
250
249
|
}
|
|
251
250
|
function I(t, e) {
|
|
@@ -253,34 +252,34 @@ function I(t, e) {
|
|
|
253
252
|
`).find((s) => s.startsWith(`${e}:`));
|
|
254
253
|
return n == null ? void 0 : n.slice(e.length + 1).trim().replace(/^['"]|['"]$/g, "");
|
|
255
254
|
}
|
|
256
|
-
function
|
|
255
|
+
function Z(t, e) {
|
|
257
256
|
const n = t.split(`
|
|
258
|
-
`), s = n.findIndex((
|
|
257
|
+
`), s = n.findIndex((i) => i.startsWith(`${e}:`));
|
|
259
258
|
if (s < 0) return [];
|
|
260
|
-
const
|
|
261
|
-
for (const
|
|
262
|
-
if (!
|
|
263
|
-
|
|
259
|
+
const r = [];
|
|
260
|
+
for (const i of n.slice(s + 1)) {
|
|
261
|
+
if (!i.startsWith("- ")) break;
|
|
262
|
+
r.push(i.slice(2).trim());
|
|
264
263
|
}
|
|
265
|
-
return
|
|
264
|
+
return r;
|
|
266
265
|
}
|
|
267
|
-
async function
|
|
266
|
+
async function P(t, e) {
|
|
268
267
|
const n = await fetch(`${t}/${e}`);
|
|
269
268
|
if (!n.ok) throw new Error(`corpus: ${e} is not readable (${n.status})`);
|
|
270
269
|
return n.text();
|
|
271
270
|
}
|
|
272
|
-
async function
|
|
273
|
-
const { coordinator: e, dest: n, filterBy: s, subjects:
|
|
274
|
-
if (!
|
|
271
|
+
async function Tt(t) {
|
|
272
|
+
const { coordinator: e, dest: n, filterBy: s, subjects: r = !1, vertexType: i } = t, c = et(e, s), l = nt(c.meta), E = it(c), y = await P(n, "graph.graph.yml"), p = Z(y, "vertices"), x = Z(y, "edges"), f = await Promise.all(p.map((a) => P(n, a))), N = i === void 0 ? f[0] : f.find((a) => I(a, "type") === i);
|
|
273
|
+
if (!N)
|
|
275
274
|
throw new Error(
|
|
276
|
-
`corpus: no vertex type ${
|
|
275
|
+
`corpus: no vertex type ${i ?? "(none declared)"} in ${n}/graph.graph.yml`
|
|
277
276
|
);
|
|
278
|
-
const
|
|
279
|
-
if (
|
|
277
|
+
const $ = I(N, "type"), O = I(N, "prefix"), g = Number(I(N, "chunk_size"));
|
|
278
|
+
if (!$ || !O || !Number.isFinite(g) || g <= 0)
|
|
280
279
|
throw new Error(`corpus: ${n} declares no usable type, prefix and chunk_size`);
|
|
281
|
-
const
|
|
282
|
-
let
|
|
283
|
-
const
|
|
280
|
+
const A = (await Promise.all(x.map((a) => P(n, a)))).find((a) => I(a, "src_type") === $), u = A ? I(A, "prefix") : void 0;
|
|
281
|
+
let D = null, G;
|
|
282
|
+
const j = (a) => `'${n}/${O}chunk${a}.parquet'`, ct = (a) => `'${n}/${u}by_source/tile${a}.parquet'`, lt = async () => {
|
|
284
283
|
var o;
|
|
285
284
|
const a = (o = e.databaseConnector) == null ? void 0 : o.call(e);
|
|
286
285
|
if (!(a != null && a.getDuckDB)) return null;
|
|
@@ -289,90 +288,90 @@ async function Lt(t) {
|
|
|
289
288
|
} catch {
|
|
290
289
|
return null;
|
|
291
290
|
}
|
|
292
|
-
},
|
|
293
|
-
let
|
|
294
|
-
const
|
|
291
|
+
}, U = /* @__PURE__ */ new Map();
|
|
292
|
+
let z = 0;
|
|
293
|
+
const ut = 64 * 1024 * 1024, dt = 256 * 1024;
|
|
295
294
|
async function V(a, o) {
|
|
296
|
-
const d = a === "vertex" ?
|
|
297
|
-
if (!
|
|
295
|
+
const d = a === "vertex" ? j : ct, C = await lt();
|
|
296
|
+
if (!C) return o.map(d);
|
|
298
297
|
const v = await Promise.all(
|
|
299
|
-
o.map(async (
|
|
300
|
-
const
|
|
301
|
-
if (
|
|
302
|
-
const
|
|
303
|
-
if (!w.ok || !Number.isFinite(T) || T >
|
|
304
|
-
const
|
|
305
|
-
if (!
|
|
306
|
-
const
|
|
307
|
-
return await
|
|
298
|
+
o.map(async (m) => {
|
|
299
|
+
const S = `corpus_${$}_${a}_${m}.parquet`;
|
|
300
|
+
if (U.has(S)) return S;
|
|
301
|
+
const b = d(m).slice(1, -1), w = await fetch(b, { method: "HEAD" }), T = Number(w.headers.get("content-length"));
|
|
302
|
+
if (!w.ok || !Number.isFinite(T) || T > dt) return d(m);
|
|
303
|
+
const _ = await fetch(b);
|
|
304
|
+
if (!_.ok) return d(m);
|
|
305
|
+
const R = new Uint8Array(await _.arrayBuffer());
|
|
306
|
+
return await C.registerFileBuffer(S, R), U.set(S, R.byteLength), z += R.byteLength, S;
|
|
308
307
|
})
|
|
309
308
|
);
|
|
310
|
-
for (;
|
|
311
|
-
const [
|
|
312
|
-
if (v.includes(
|
|
313
|
-
|
|
309
|
+
for (; z > ut && U.size > 0; ) {
|
|
310
|
+
const [m, S] = U.entries().next().value;
|
|
311
|
+
if (v.includes(m)) break;
|
|
312
|
+
U.delete(m), z -= S, await C.dropFile(m);
|
|
314
313
|
}
|
|
315
|
-
return v.map((
|
|
314
|
+
return v.map((m) => m.startsWith("'") ? m : `'${m}'`);
|
|
316
315
|
}
|
|
317
|
-
function
|
|
318
|
-
return
|
|
319
|
-
const a = async (
|
|
320
|
-
if (!await a(0)) throw new Error(`corpus: ${n}/${
|
|
316
|
+
function H() {
|
|
317
|
+
return D ?? (D = (async () => {
|
|
318
|
+
const a = async (h) => (await fetch(`${n}/${O}chunk${h}.parquet`, { method: "HEAD" })).ok;
|
|
319
|
+
if (!await a(0)) throw new Error(`corpus: ${n}/${O} holds no chunk0`);
|
|
321
320
|
let o = 0, d = 1;
|
|
322
321
|
for (; await a(d); )
|
|
323
322
|
o = d, d *= 2;
|
|
324
323
|
for (; d - o > 1; ) {
|
|
325
|
-
const
|
|
326
|
-
await a(
|
|
324
|
+
const h = Math.floor((o + d) / 2);
|
|
325
|
+
await a(h) ? o = h : d = h;
|
|
327
326
|
}
|
|
328
|
-
const
|
|
329
|
-
`SELECT num_rows AS n FROM parquet_file_metadata('${
|
|
327
|
+
const C = o + 1, v = await l(
|
|
328
|
+
`SELECT num_rows AS n FROM parquet_file_metadata('${j(o).slice(1, -1)}')`
|
|
330
329
|
);
|
|
331
|
-
G = o *
|
|
332
|
-
const
|
|
330
|
+
G = o * g + Number(k(v, "n")[0] ?? 0);
|
|
331
|
+
const m = Array.from({ length: C }, (h, L) => j(L)).join(", "), S = await l(
|
|
333
332
|
`SELECT CAST(regexp_extract(file_name, 'chunk(\\d+)', 1) AS INTEGER) AS tile,
|
|
334
333
|
min(CASE WHEN path_in_schema = 'x' THEN coalesce(stats_min_value, stats_min)::DOUBLE END) AS x0,
|
|
335
334
|
max(CASE WHEN path_in_schema = 'x' THEN coalesce(stats_max_value, stats_max)::DOUBLE END) AS x1,
|
|
336
335
|
min(CASE WHEN path_in_schema = 'y' THEN coalesce(stats_min_value, stats_min)::DOUBLE END) AS y0,
|
|
337
336
|
max(CASE WHEN path_in_schema = 'y' THEN coalesce(stats_max_value, stats_max)::DOUBLE END) AS y1
|
|
338
|
-
FROM parquet_metadata([${
|
|
337
|
+
FROM parquet_metadata([${m}])
|
|
339
338
|
WHERE path_in_schema IN ('x', 'y') GROUP BY 1 ORDER BY 1`
|
|
340
|
-
),
|
|
341
|
-
return
|
|
342
|
-
tile:
|
|
343
|
-
x0: w == null ? void 0 : w[
|
|
344
|
-
x1: T == null ? void 0 : T[
|
|
345
|
-
y0:
|
|
346
|
-
y1:
|
|
339
|
+
), b = k(S, "tile"), [w, T, _, R] = ["x0", "x1", "y0", "y1"].map((h) => k(S, h));
|
|
340
|
+
return b.map((h, L) => ({
|
|
341
|
+
tile: h,
|
|
342
|
+
x0: w == null ? void 0 : w[L],
|
|
343
|
+
x1: T == null ? void 0 : T[L],
|
|
344
|
+
y0: _ == null ? void 0 : _[L],
|
|
345
|
+
y1: R == null ? void 0 : R[L]
|
|
347
346
|
}));
|
|
348
|
-
})()),
|
|
347
|
+
})()), D;
|
|
349
348
|
}
|
|
350
|
-
function
|
|
349
|
+
function Et(a, o) {
|
|
351
350
|
return a.filter((d) => d.x1 >= o.xMin && d.x0 <= o.xMax && d.y1 >= o.yMin && d.y0 <= o.yMax).map((d) => d.tile);
|
|
352
351
|
}
|
|
353
352
|
const J = {
|
|
354
353
|
id: "dense_id",
|
|
355
|
-
subject:
|
|
354
|
+
subject: r ? "subject" : void 0,
|
|
356
355
|
x: "x",
|
|
357
356
|
y: "y",
|
|
358
357
|
source: "src_dense",
|
|
359
358
|
target: "dst_dense"
|
|
360
|
-
}, Y = `corpus_${
|
|
359
|
+
}, Y = `corpus_${$}`, B = u ? `corpus_${$}_edges` : void 0, mt = async () => (await H()).map((o) => j(o.tile)).join(", ");
|
|
361
360
|
return await e.exec(
|
|
362
|
-
`CREATE OR REPLACE VIEW ${Y} AS SELECT * FROM read_parquet([${await
|
|
361
|
+
`CREATE OR REPLACE VIEW ${Y} AS SELECT * FROM read_parquet([${await mt()}])`
|
|
363
362
|
), B && await e.exec(
|
|
364
363
|
`CREATE OR REPLACE VIEW ${B} AS
|
|
365
|
-
SELECT * FROM read_parquet('${n}/${
|
|
364
|
+
SELECT * FROM read_parquet('${n}/${u}by_source.parquet')`
|
|
366
365
|
), { source: {
|
|
367
|
-
...
|
|
366
|
+
...E.api,
|
|
368
367
|
publish(a) {
|
|
369
|
-
|
|
368
|
+
ot(c, s, J.id, a);
|
|
370
369
|
},
|
|
371
370
|
async total() {
|
|
372
|
-
return await
|
|
371
|
+
return await H(), G ?? 0;
|
|
373
372
|
},
|
|
374
373
|
async extent() {
|
|
375
|
-
const a = await
|
|
374
|
+
const a = await H();
|
|
376
375
|
return {
|
|
377
376
|
xMin: Math.min(...a.map((o) => o.x0)),
|
|
378
377
|
yMin: Math.min(...a.map((o) => o.y0)),
|
|
@@ -384,7 +383,7 @@ async function Lt(t) {
|
|
|
384
383
|
// needs adjacency this source does not index, and fossil's `expand` is what answers it —
|
|
385
384
|
// `ExploringSource` is the shape waiting for whoever writes that one.
|
|
386
385
|
async slice(a) {
|
|
387
|
-
const { fill: o, limit: d, perPixel:
|
|
386
|
+
const { fill: o, limit: d, minLinkPixels: C, perPixel: v, pinned: m, r: S, signal: b, view: w } = a, T = { ...J, category: o, size: S }, _ = await H(), R = Et(_, w);
|
|
388
387
|
if (R.length === 0)
|
|
389
388
|
return {
|
|
390
389
|
n: 0,
|
|
@@ -394,20 +393,20 @@ async function Lt(t) {
|
|
|
394
393
|
links: new Float32Array(0),
|
|
395
394
|
categories: new Uint16Array(0)
|
|
396
395
|
};
|
|
397
|
-
const [
|
|
396
|
+
const [h, L] = await Promise.all([
|
|
398
397
|
V("vertex", R),
|
|
399
|
-
V("edge",
|
|
398
|
+
V("edge", u ? R : [])
|
|
400
399
|
]);
|
|
401
|
-
if (
|
|
402
|
-
const
|
|
403
|
-
return
|
|
404
|
-
|
|
400
|
+
if (b != null && b.aborted) throw b.reason;
|
|
401
|
+
const K = `read_parquet([${h.join(", ")}])`, yt = `read_parquet([${L.join(", ")}])`;
|
|
402
|
+
return E.run(
|
|
403
|
+
rt(K, yt, T, w, d, 0, m, v, C, K)
|
|
405
404
|
);
|
|
406
405
|
}
|
|
407
406
|
}, nodes: Y, edges: B };
|
|
408
407
|
}
|
|
409
408
|
export {
|
|
410
|
-
|
|
411
|
-
|
|
409
|
+
wt as duckBoundedSource,
|
|
410
|
+
Tt as openCorpus
|
|
412
411
|
};
|
|
413
412
|
//# sourceMappingURL=duck-source.js.map
|