@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/memory-source.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { BOUNDED_DEFAULTS as U } from "./bounded.js";
|
|
2
|
-
function z(t) {
|
|
3
|
-
const u = t.positions.length / 2;
|
|
4
|
-
let x = null, d = null;
|
|
5
|
-
const I = (e) => {
|
|
6
|
-
if (!x) {
|
|
7
|
-
x = /* @__PURE__ */ new Map();
|
|
8
|
-
for (let i = 0; i < u; i++) x.set(t.vertices[i], i);
|
|
9
|
-
}
|
|
10
|
-
return x.get(e);
|
|
11
|
-
}, N = (e) => {
|
|
12
|
-
var i, r;
|
|
13
|
-
if (!d) {
|
|
14
|
-
d = Array.from({ length: u }, () => []);
|
|
15
|
-
for (let l = 0; l < t.links.length; l += 2) {
|
|
16
|
-
const f = t.links[l], o = t.links[l + 1];
|
|
17
|
-
(i = d[f]) == null || i.push(o), (r = d[o]) == null || r.push(f);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return d[e] ?? [];
|
|
21
|
-
};
|
|
22
|
-
return {
|
|
23
|
-
total: () => Promise.resolve(u),
|
|
24
|
-
// One pass over the array it is already holding, so the canvas frames the arrays rather than the
|
|
25
|
-
// renderer's default box.
|
|
26
|
-
extent: () => Promise.resolve(_(t.positions)),
|
|
27
|
-
slice(e) {
|
|
28
|
-
const { limit: i, perPixel: r, pinned: l, view: f } = e;
|
|
29
|
-
return Promise.resolve(S(t, s(t, f, l), i, r));
|
|
30
|
-
},
|
|
31
|
-
// The only source we ship that has this at all: a rectangle needs a spatial predicate, which
|
|
32
|
-
// every source has, and a neighbourhood needs adjacency, which only a host holding its own links
|
|
33
|
-
// does. So the bounded canvas is an explorer here while a SQL source leaves it a map.
|
|
34
|
-
explore(e) {
|
|
35
|
-
return Promise.resolve(
|
|
36
|
-
S(t, m(e.seeds, e.depth), e.limit, e.perPixel)
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
function m(e, i) {
|
|
41
|
-
const r = /* @__PURE__ */ new Set();
|
|
42
|
-
let l = [];
|
|
43
|
-
for (const f of e) {
|
|
44
|
-
const o = I(f);
|
|
45
|
-
o !== void 0 && !r.has(o) && (r.add(o), l.push(o));
|
|
46
|
-
}
|
|
47
|
-
for (let f = 0; f < i && l.length > 0; f++) {
|
|
48
|
-
const o = [];
|
|
49
|
-
for (const a of l)
|
|
50
|
-
for (const y of N(a))
|
|
51
|
-
r.has(y) || (r.add(y), o.push(y));
|
|
52
|
-
l = o;
|
|
53
|
-
}
|
|
54
|
-
return [...r];
|
|
55
|
-
}
|
|
56
|
-
function s(e, i, r) {
|
|
57
|
-
const l = [];
|
|
58
|
-
for (let o = 0; o < u; o++) {
|
|
59
|
-
const a = e.positions[o * 2], y = e.positions[o * 2 + 1];
|
|
60
|
-
a >= i.xMin && a <= i.xMax && y >= i.yMin && y <= i.yMax && l.push(o);
|
|
61
|
-
}
|
|
62
|
-
if (!(r != null && r.length)) return l;
|
|
63
|
-
const f = new Set(l);
|
|
64
|
-
for (const o of r) {
|
|
65
|
-
const a = I(o);
|
|
66
|
-
a !== void 0 && f.add(a);
|
|
67
|
-
}
|
|
68
|
-
return [...f];
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
function S(t, u, x, d) {
|
|
72
|
-
var F, T, E;
|
|
73
|
-
const I = u.length, N = Math.max(1, Math.ceil(I / x)), m = [];
|
|
74
|
-
for (let n = 0; n < u.length && m.length < x; n += N)
|
|
75
|
-
m.push(u[n]);
|
|
76
|
-
const s = m.length, e = new Int32Array(t.positions.length / 2).fill(-1), i = new BigUint64Array(s), r = new Float32Array(s * 2), l = new Uint16Array(s), f = t.sizes ? new Float32Array(s) : void 0, o = t.subjects ? new Array(s) : void 0;
|
|
77
|
-
for (let n = 0; n < s; n++) {
|
|
78
|
-
const c = m[n];
|
|
79
|
-
e[c] = n, i[n] = t.vertices[c], o && (o[n] = ((F = t.subjects) == null ? void 0 : F[c]) ?? ""), r[n * 2] = t.positions[c * 2], r[n * 2 + 1] = t.positions[c * 2 + 1], l[n] = ((T = t.categories) == null ? void 0 : T[c]) ?? 0, f && (f[n] = ((E = t.sizes) == null ? void 0 : E[c]) ?? 0);
|
|
80
|
-
}
|
|
81
|
-
const a = d !== void 0 && d > 0 ? U.minLinkPixels * d : 0, y = [], b = (n) => {
|
|
82
|
-
const c = e[n];
|
|
83
|
-
if (c >= 0) return c;
|
|
84
|
-
const w = s + y.length;
|
|
85
|
-
return e[n] = w, y.push(n), w;
|
|
86
|
-
}, h = [];
|
|
87
|
-
for (let n = 0; n < t.links.length; n += 2) {
|
|
88
|
-
const c = t.links[n], w = t.links[n + 1];
|
|
89
|
-
if (!(e[c] < 0 && e[w] < 0)) {
|
|
90
|
-
if (a > 0) {
|
|
91
|
-
const P = t.positions[c * 2] - t.positions[w * 2], O = t.positions[c * 2 + 1] - t.positions[w * 2 + 1];
|
|
92
|
-
if (P * P + O * O < a * a) continue;
|
|
93
|
-
}
|
|
94
|
-
h.push(b(c), b(w));
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const A = s + y.length, M = new Float32Array(A * 2);
|
|
98
|
-
M.set(r);
|
|
99
|
-
const v = new BigUint64Array(A);
|
|
100
|
-
v.set(i);
|
|
101
|
-
const k = new Uint16Array(A);
|
|
102
|
-
k.set(l);
|
|
103
|
-
for (let n = 0; n < y.length; n++) {
|
|
104
|
-
const c = y[n];
|
|
105
|
-
M[(s + n) * 2] = t.positions[c * 2], M[(s + n) * 2 + 1] = t.positions[c * 2 + 1], v[s + n] = t.vertices[c], o && (o[s + n] = "");
|
|
106
|
-
}
|
|
107
|
-
return {
|
|
108
|
-
n: I,
|
|
109
|
-
marks: s,
|
|
110
|
-
vertices: v,
|
|
111
|
-
subjects: o,
|
|
112
|
-
positions: M,
|
|
113
|
-
links: Float32Array.from(h),
|
|
114
|
-
categories: k,
|
|
115
|
-
sizes: f ? V(f, A) : void 0
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
function V(t, u) {
|
|
119
|
-
if (t.length === u) return t;
|
|
120
|
-
const x = new Float32Array(u);
|
|
121
|
-
return x.set(t), x;
|
|
122
|
-
}
|
|
123
|
-
function _(t) {
|
|
124
|
-
let u = Number.POSITIVE_INFINITY, x = Number.POSITIVE_INFINITY, d = Number.NEGATIVE_INFINITY, I = Number.NEGATIVE_INFINITY;
|
|
125
|
-
for (let N = 0; N < t.length; N += 2) {
|
|
126
|
-
const m = t[N], s = t[N + 1];
|
|
127
|
-
m < u && (u = m), m > d && (d = m), s < x && (x = s), s > I && (I = s);
|
|
128
|
-
}
|
|
129
|
-
return Number.isFinite(u) ? { xMin: u, yMin: x, xMax: d, yMax: I } : { xMin: 0, yMin: 0, xMax: 0, yMax: 0 };
|
|
130
|
-
}
|
|
131
|
-
export {
|
|
132
|
-
z as memorySource
|
|
133
|
-
};
|
|
134
|
-
//# sourceMappingURL=memory-source.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"memory-source.js","sources":["../src/memory-source.ts"],"sourcesContent":["import {\n BOUNDED_DEFAULTS,\n type ExploreRequest,\n type ExploringSource,\n type Slice,\n type SliceRequest,\n type Viewport,\n} from \"./bounded\";\nimport type { VertexId } from \"./resident\";\n\n/**\n * The trivial source: a host that already holds its arrays.\n *\n * ADR-0001 deletes `load()`, which means every consumer needs a source — including the ones for\n * which bounding buys nothing, because their graph fits. This is that source, and it exists so that\n * \"wrap your arrays\" is one import rather than a hundred lines each call site writes differently.\n *\n * It is also the only source we ship that is an [`ExploringSource`]. A rectangle is a map question\n * and any relation with a spatial predicate can answer it; a neighbourhood is the graph question,\n * and answering it needs adjacency. Having the links in hand, this one does.\n *\n * Everything derived is built on first use and kept: a graph small enough to hold is small enough\n * that an adjacency list is cheap, but a host that only ever pans should not pay to build one.\n */\n\nexport interface MemoryGraph {\n /** Who each point is, parallel to the position pairs — `vertexId(type, dense)` per point. */\n vertices: BigUint64Array;\n /** `[x0, y0, x1, y1, …]`. */\n positions: Float32Array;\n /** `[src, dst, …]` as indices into `positions`. */\n links: Float32Array;\n /**\n * The subject IRI of each vertex, parallel to `vertices` — optional, and the same opt-in the SQL\n * source makes for the same reason: a host that never names a vertex should not carry the names.\n */\n subjects?: string[];\n categories?: Uint16Array;\n sizes?: Float32Array;\n}\n\nexport function memorySource(graph: MemoryGraph): ExploringSource {\n const count = graph.positions.length / 2;\n\n /** Built on demand — a host that only pans never asks for either of these. */\n let byVertex: Map<bigint, number> | null = null;\n let adjacency: number[][] | null = null;\n\n const indexOf = (vertex: VertexId): number | undefined => {\n if (!byVertex) {\n byVertex = new Map();\n for (let i = 0; i < count; i++) byVertex.set(graph.vertices[i] as bigint, i);\n }\n return byVertex.get(vertex);\n };\n\n const neighbours = (index: number): number[] => {\n if (!adjacency) {\n adjacency = Array.from({ length: count }, () => [] as number[]);\n for (let e = 0; e < graph.links.length; e += 2) {\n const src = graph.links[e] as number;\n const dst = graph.links[e + 1] as number;\n adjacency[src]?.push(dst);\n adjacency[dst]?.push(src);\n }\n }\n return adjacency[index] ?? [];\n };\n\n return {\n total: () => Promise.resolve(count),\n // One pass over the array it is already holding, so the canvas frames the arrays rather than the\n // renderer's default box.\n extent: () => Promise.resolve(boundsOf(graph.positions)),\n slice(request: SliceRequest): Promise<Slice> {\n const { limit, perPixel, pinned, view } = request;\n return Promise.resolve(gather(graph, inside(graph, view, pinned), limit, perPixel));\n },\n // The only source we ship that has this at all: a rectangle needs a spatial predicate, which\n // every source has, and a neighbourhood needs adjacency, which only a host holding its own links\n // does. So the bounded canvas is an explorer here while a SQL source leaves it a map.\n explore(request: ExploreRequest): Promise<Slice> {\n return Promise.resolve(\n gather(graph, expand(request.seeds, request.depth), request.limit, request.perPixel),\n );\n },\n };\n\n /**\n * Breadth-first from the seeds, `depth` hops out. Seeds are identities; everything after is a\n * corpus index, which is this source's own numbering and not a slice's.\n */\n function expand(seeds: VertexId[], depth: number): number[] {\n const seen = new Set<number>();\n let frontier: number[] = [];\n for (const vertex of seeds) {\n const index = indexOf(vertex);\n if (index !== undefined && !seen.has(index)) {\n seen.add(index);\n frontier.push(index);\n }\n }\n for (let hop = 0; hop < depth && frontier.length > 0; hop++) {\n const next: number[] = [];\n for (const index of frontier) {\n for (const other of neighbours(index)) {\n if (seen.has(other)) continue;\n seen.add(other);\n next.push(other);\n }\n }\n frontier = next;\n }\n return [...seen];\n }\n\n /** Everything the rectangle holds, plus whatever the reader is holding on to. */\n function inside(data: MemoryGraph, view: Viewport, pinned: VertexId[] | undefined): number[] {\n const hit: number[] = [];\n for (let i = 0; i < count; i++) {\n const x = data.positions[i * 2] as number;\n const y = data.positions[i * 2 + 1] as number;\n if (x >= view.xMin && x <= view.xMax && y >= view.yMin && y <= view.yMax) hit.push(i);\n }\n if (!pinned?.length) return hit;\n const held = new Set(hit);\n for (const vertex of pinned) {\n const index = indexOf(vertex);\n if (index !== undefined) held.add(index);\n }\n return [...held];\n }\n}\n\n/**\n * Chosen indices to a slice: renumber, copy the geometry, keep the links both of whose ends survived.\n *\n * `n` is what matched before `limit` cut it, which is the one honest thing a bounded view owes its\n * reader — a truncated answer must not look like a complete one.\n *\n * **Over the limit it strides rather than taking the front**, which is the same rule the SQL sources\n * apply and for the same reason: the front of an ordering is a *region* of whatever that ordering\n * follows, so `chosen.slice(0, limit)` drew one corner of a window and called it the window.\n *\n * What this source cannot promise, and the SQL ones can: that the stride is **spatially**\n * stratified. A corpus numbers along the Morton curve so every `s`-th id is spread over the space;\n * here the order is whichever order the host built its arrays in, and nothing knows what that is. A\n * stride over an unknown order is at worst an arbitrary sample, where a prefix of an unknown order\n * is at worst an arbitrary *contiguous* sample — so this is never the worse of the two and is\n * sometimes much better.\n */\nfunction gather(\n graph: MemoryGraph,\n chosen: number[],\n limit: number,\n perPixel: number | undefined,\n): Slice {\n const matched = chosen.length;\n const stride = Math.max(1, Math.ceil(matched / limit));\n const kept: number[] = [];\n for (let i = 0; i < chosen.length && kept.length < limit; i += stride) {\n kept.push(chosen[i] as number);\n }\n const n = kept.length;\n\n // Global index → position in this slice, `-1` for everything not in it. One pass over the corpus\n // rather than a Map: the arrays are already dense and an Int32Array of N is cheaper than N boxed\n // entries, which is the whole argument of this branch in miniature.\n const local = new Int32Array(graph.positions.length / 2).fill(-1);\n const vertices = new BigUint64Array(n);\n const positions = new Float32Array(n * 2);\n const categories = new Uint16Array(n);\n const sizes = graph.sizes ? new Float32Array(n) : undefined;\n const subjects = graph.subjects ? new Array<string>(n) : undefined;\n for (let i = 0; i < n; i++) {\n const from = kept[i] as number;\n local[from] = i;\n vertices[i] = graph.vertices[from] as bigint;\n if (subjects) subjects[i] = graph.subjects?.[from] ?? \"\";\n positions[i * 2] = graph.positions[from * 2] as number;\n positions[i * 2 + 1] = graph.positions[from * 2 + 1] as number;\n categories[i] = graph.categories?.[from] ?? 0;\n if (sizes) sizes[i] = graph.sizes?.[from] ?? 0;\n }\n\n /**\n * The edges, and the far ends they need — **which this source has, because it holds everything.**\n *\n * A window that fits loses nothing here; a window over the limit is a sample, and an edge from a\n * sampled vertex to one the stride passed over used to be dropped. It is not a missing fact: the\n * arrays are in hand. So the far end is appended as an **anchor** — a point at its real\n * coordinates, past `marks`, never drawn. The SQL source reaches the same answer out of the tiles\n * it fetched; this one reaches it out of the arrays it was handed.\n *\n * `perPixel` given, an edge shorter than `minLinkPixels` on screen is not sent at all — it is a\n * dot on top of two dots the point layer has already drawn.\n */\n const floor = perPixel !== undefined && perPixel > 0 ? BOUNDED_DEFAULTS.minLinkPixels * perPixel : 0;\n const anchors: number[] = [];\n const anchorOf = (from: number): number => {\n const seen = local[from] as number;\n if (seen >= 0) return seen;\n const at = n + anchors.length;\n local[from] = at;\n anchors.push(from);\n return at;\n };\n\n const links: number[] = [];\n for (let e = 0; e < graph.links.length; e += 2) {\n const a = graph.links[e] as number;\n const b = graph.links[e + 1] as number;\n // At least one end drawn. Neither drawn is an edge somewhere else entirely, and drawing it would\n // put ink outside the window the caller asked about.\n if ((local[a] as number) < 0 && (local[b] as number) < 0) continue;\n if (floor > 0) {\n const dx = (graph.positions[a * 2] as number) - (graph.positions[b * 2] as number);\n const dy = (graph.positions[a * 2 + 1] as number) - (graph.positions[b * 2 + 1] as number);\n if (dx * dx + dy * dy < floor * floor) continue;\n }\n links.push(anchorOf(a), anchorOf(b));\n }\n\n const all = n + anchors.length;\n const whole = new Float32Array(all * 2);\n whole.set(positions);\n const who = new BigUint64Array(all);\n who.set(vertices);\n const ordinals = new Uint16Array(all);\n ordinals.set(categories);\n for (let i = 0; i < anchors.length; i++) {\n const from = anchors[i] as number;\n whole[(n + i) * 2] = graph.positions[from * 2] as number;\n whole[(n + i) * 2 + 1] = graph.positions[from * 2 + 1] as number;\n who[n + i] = graph.vertices[from] as bigint;\n // No category and no size: an anchor is not drawn, and giving it either would put it in the\n // colour scale's domain and the size ramp's range for a point nobody can see.\n if (subjects) subjects[n + i] = \"\";\n }\n\n return {\n n: matched,\n marks: n,\n vertices: who,\n subjects,\n positions: whole,\n links: Float32Array.from(links),\n categories: ordinals,\n sizes: sizes ? growTo(sizes, all) : undefined,\n };\n}\n\n/** A ramp column widened to cover the anchors, which contribute nothing to it. */\nfunction growTo(values: Float32Array, length: number): Float32Array {\n if (values.length === length) return values;\n const wider = new Float32Array(length);\n wider.set(values);\n return wider;\n}\n\n/**\n * The rectangle a set of interleaved positions occupies.\n *\n * Empty arrays answer a degenerate rectangle at the origin rather than `±Infinity`: a view framed on\n * nothing should sit somewhere, and the infinities would make the fit arithmetic produce `NaN`.\n */\nfunction boundsOf(positions: Float32Array): Viewport {\n let xMin = Number.POSITIVE_INFINITY;\n let yMin = Number.POSITIVE_INFINITY;\n let xMax = Number.NEGATIVE_INFINITY;\n let yMax = Number.NEGATIVE_INFINITY;\n for (let i = 0; i < positions.length; i += 2) {\n const x = positions[i] as number;\n const y = positions[i + 1] as number;\n if (x < xMin) xMin = x;\n if (x > xMax) xMax = x;\n if (y < yMin) yMin = y;\n if (y > yMax) yMax = y;\n }\n if (!Number.isFinite(xMin)) return { xMin: 0, yMin: 0, xMax: 0, yMax: 0 };\n return { xMin, yMin, xMax, yMax };\n}\n"],"names":["memorySource","graph","count","byVertex","adjacency","indexOf","vertex","neighbours","index","e","src","dst","_a","_b","boundsOf","request","limit","perPixel","pinned","view","gather","inside","expand","seeds","depth","seen","frontier","hop","next","other","data","hit","i","x","held","chosen","matched","stride","kept","n","local","vertices","positions","categories","sizes","subjects","from","_c","floor","BOUNDED_DEFAULTS","anchors","anchorOf","at","links","a","b","dx","dy","all","whole","who","ordinals","growTo","values","length","wider","xMin","yMin","xMax","yMax","y"],"mappings":"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"}
|