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