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