@kanzo-tech/graph 0.26.0 → 0.28.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 +7 -4
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +16 -16
- package/dist/core/client.js.map +1 -1
- package/dist/core/error.d.ts +3 -3
- package/dist/core/error.d.ts.map +1 -1
- package/dist/core/error.js.map +1 -1
- package/dist/core/state.d.ts +8 -3
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/store.d.ts +1 -1
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +84 -76
- package/dist/core/store.js.map +1 -1
- package/dist/core/types.d.ts +5 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -24
- package/dist/index.js.map +1 -1
- package/dist/parts/graph-counts.d.ts +9 -11
- package/dist/parts/graph-counts.d.ts.map +1 -1
- package/dist/parts/graph-counts.js +28 -27
- package/dist/parts/graph-counts.js.map +1 -1
- package/dist/parts/graph-select.d.ts +27 -0
- package/dist/parts/graph-select.d.ts.map +1 -0
- package/dist/parts/graph-select.js +53 -0
- package/dist/parts/graph-select.js.map +1 -0
- package/dist/parts/graph-status.d.ts +13 -0
- package/dist/parts/graph-status.d.ts.map +1 -0
- package/dist/parts/graph-status.js +28 -0
- package/dist/parts/graph-status.js.map +1 -0
- package/dist/react/use-graph-prefs.d.ts +1 -1
- package/dist/react/use-graph-prefs.js.map +1 -1
- package/dist/render/camera.d.ts +12 -1
- package/dist/render/camera.d.ts.map +1 -1
- package/dist/render/camera.js +33 -21
- package/dist/render/camera.js.map +1 -1
- package/dist/render/renderer.d.ts.map +1 -1
- package/dist/render/renderer.js +85 -84
- package/dist/render/renderer.js.map +1 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ DuckDB-WASM engine and its crossfilter, cosmos.gl draws, and the parts are built
|
|
|
19
19
|
```tsx
|
|
20
20
|
import { open } from "@fossil-lang/corpus";
|
|
21
21
|
import { engine } from "@kanzo-tech/mosaic";
|
|
22
|
-
import { GraphCanvas, GraphCounts, GraphInspector, GraphLegend, GraphRoot, GraphToolbar } from "@kanzo-tech/graph";
|
|
22
|
+
import { GraphCanvas, GraphCounts, GraphInspector, GraphLegend, GraphRoot, GraphStatus, GraphToolbar } from "@kanzo-tech/graph";
|
|
23
23
|
|
|
24
24
|
const corpus = engine().then((e) => open(url, { engine: e }));
|
|
25
25
|
|
|
@@ -28,6 +28,7 @@ const corpus = engine().then((e) => open(url, { engine: e }));
|
|
|
28
28
|
<GraphToolbar />
|
|
29
29
|
<GraphLegend />
|
|
30
30
|
</GraphCanvas>
|
|
31
|
+
<GraphStatus />
|
|
31
32
|
<GraphCounts />
|
|
32
33
|
<GraphInspector />
|
|
33
34
|
</GraphRoot>;
|
|
@@ -68,7 +69,9 @@ graph, a second main view and a dock of panels.
|
|
|
68
69
|
and lasso gesture. Children are chrome positioned over it.
|
|
69
70
|
- `GraphToolbar` — the selection tools, the selection, zoom and fit, and the layout's transport.
|
|
70
71
|
- `GraphLegend` — one row per category: glyph, name and how many are drawn.
|
|
71
|
-
- `
|
|
72
|
+
- `GraphStatus` — where the graph is, in one word: Loading, Laying out 42%, Ready or Failed.
|
|
73
|
+
- `GraphCounts` — the corpus and what the filter keeps of it: "5K nodes · 8K edges", or
|
|
74
|
+
"1.2K of 5K nodes match · 3K edges".
|
|
72
75
|
- `GraphSearch` — every drawn vertex's text, read once and filtered in the browser; picking reveals.
|
|
73
76
|
- `GraphInspector` — the focused vertex's row, with a render prop for a product's own fields.
|
|
74
77
|
- `GraphLooks` — Nebula, Atlas and Ink as presets over `GRAPH_SECTION`'s axes, with the axes under
|
|
@@ -77,8 +80,8 @@ graph, a second main view and a dock of panels.
|
|
|
77
80
|
|
|
78
81
|
No part takes a callback: what a click means is `onSelect`, `onFocus` and `onFailure` on the root.
|
|
79
82
|
`onFailure` is required and receives every failure as thrown — fossil's coded errors, and the graph's
|
|
80
|
-
own `GraphError` (`graph/no-webgl`, `graph/context-lost`, `graph/
|
|
81
|
-
`graph/
|
|
83
|
+
own `GraphError` (`graph/no-webgl`, `graph/context-lost`, `graph/no-positions`,
|
|
84
|
+
`graph/nothing-to-draw`, `graph/unfilterable`).
|
|
82
85
|
|
|
83
86
|
- `lookFrom`, `simFrom`, `useGraphPrefs` — the form and the forces from a preferences panel's
|
|
84
87
|
answers, and the look `preset` they are; `scaleOf` — what colour and shape a category wears.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAIZ,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAYxE,qBAAa,WAAY,SAAQ,YAAY;;gBAMzC,QAAQ,EAAE,SAAS,GAAG,SAAS,EAC/B,SAAS,EAAE,MAAM,SAAS,GAAG,IAAI,EACjC,IAAI,EAAE,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,KAAK,IAAI,EACxC,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI;IAQhC;;;OAGG;IACH,IAAa,YAAY,IAAI,OAAO,CAEnC;IAED;;;;OAIG;IACM,KAAK,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,GAAG,MAAM;IAwBzC,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAMhC,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CAIxC;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,CAOrG"}
|
package/dist/core/client.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var f = (
|
|
2
|
-
throw TypeError(
|
|
1
|
+
var f = (r) => {
|
|
2
|
+
throw TypeError(r);
|
|
3
3
|
};
|
|
4
|
-
var
|
|
5
|
-
var u = (
|
|
6
|
-
import { MosaicClient as g, collectColumns as A,
|
|
7
|
-
import { GraphError as
|
|
8
|
-
import { relation as
|
|
4
|
+
var y = (r, t, e) => t.has(r) || f("Cannot " + e);
|
|
5
|
+
var u = (r, t, e) => (y(r, t, "read from private field"), e ? e.call(r) : t.get(r)), h = (r, t, e) => t.has(r) ? f("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(r) : t.set(r, e), m = (r, t, e, n) => (y(r, t, "write to private field"), n ? n.call(r, e) : t.set(r, e), e);
|
|
6
|
+
import { MosaicClient as g, collectColumns as A, queryFailure as v, clausePoints as C } from "@kanzo-tech/mosaic";
|
|
7
|
+
import { GraphError as $ } from "./error.js";
|
|
8
|
+
import { relation as O, ident as L } from "./source.js";
|
|
9
9
|
const S = "SELECT NULL::DOUBLE AS id";
|
|
10
10
|
var a, c, l;
|
|
11
11
|
class N extends g {
|
|
@@ -32,9 +32,9 @@ class N extends g {
|
|
|
32
32
|
const n = (Array.isArray(e) ? e : [e]).filter((s) => s != null), i = u(this, a).call(this);
|
|
33
33
|
if (!i || n.length === 0) return S;
|
|
34
34
|
const d = n.map((s) => `(${String(s)})`).join(" AND "), p = [...new Set(n.flatMap((s) => A(s).map((o) => o.column)))], E = i.vertices.filter((s) => p.every((o) => s.columns.has(o)));
|
|
35
|
-
return E.length === 0 ? (u(this, l).call(this, new
|
|
36
|
-
const o =
|
|
37
|
-
return E.includes(s) ? `SELECT ${
|
|
35
|
+
return E.length === 0 ? (u(this, l).call(this, new $("graph/unfilterable", `no vertex type has every column this clause names: ${p.join(", ")}`)), S) : i.vertices.map((s) => {
|
|
36
|
+
const o = O(i.from, s.name);
|
|
37
|
+
return E.includes(s) ? `SELECT ${L("dense_id")}::DOUBLE AS id FROM ${o} WHERE ${d}` : `SELECT ${L("dense_id")}::DOUBLE AS id FROM ${o}`;
|
|
38
38
|
}).join(" UNION ALL ");
|
|
39
39
|
}
|
|
40
40
|
queryResult(e) {
|
|
@@ -43,15 +43,15 @@ class N extends g {
|
|
|
43
43
|
return u(this, c).call(this, n.length === 1 && n[0] === null ? null : Float64Array.from(n)), this;
|
|
44
44
|
}
|
|
45
45
|
queryError(e) {
|
|
46
|
-
return u(this, l).call(this, e), this;
|
|
46
|
+
return u(this, l).call(this, v(e)), this;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
a = new WeakMap(), c = new WeakMap(), l = new WeakMap();
|
|
50
|
-
function R(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
source:
|
|
54
|
-
clients: /* @__PURE__ */ new Set([
|
|
50
|
+
function R(r, t, e) {
|
|
51
|
+
r.update(
|
|
52
|
+
C(["dense_id"], e && e.length > 0 ? e.map((n) => [n]) : void 0, {
|
|
53
|
+
source: t,
|
|
54
|
+
clients: /* @__PURE__ */ new Set([t])
|
|
55
55
|
})
|
|
56
56
|
);
|
|
57
57
|
}
|
package/dist/core/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sources":["../../src/core/client.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"client.js","sources":["../../src/core/client.ts"],"sourcesContent":["import {\n MosaicClient,\n clausePoints,\n collectColumns,\n queryFailure,\n type FilterExpr,\n type Selection,\n} from \"@kanzo-tech/mosaic\";\nimport { GraphError } from \"./error\";\nimport { ident, relation, type Answer, type Structure } from \"./source\";\n\n/**\n * **The graph as a client of the page's coordinator** — one Mosaic client, like every chart beside\n * it. The coordinator hands it the crossfilter's predicate, minus the clause the graph published\n * itself; it answers with the `dense_id`s that survive, and the canvas greys out the rest on the GPU.\n * No predicate is translated, no position is uploaded again, and the query runs on the coordinator's\n * one connection, through its cache — Cosmograph's crossfilter, on our stack.\n */\n/** The answer that clears the filter. */\nconst UNFILTERED = \"SELECT NULL::DOUBLE AS id\";\n\nexport class GraphClient extends MosaicClient {\n #structure: () => Structure | null;\n #kept: (ids: Float64Array | null) => void;\n #fail: (error: unknown) => void;\n\n constructor(\n filterBy: Selection | undefined,\n structure: () => Structure | null,\n kept: (ids: Float64Array | null) => void,\n fail: (error: unknown) => void,\n ) {\n super(filterBy);\n this.#structure = structure;\n this.#kept = kept;\n this.#fail = fail;\n }\n\n /**\n * Not stable: the answer is a set of ids, not a group-by a pre-aggregate could stand in for. And\n * Mosaic's pre-aggregator calls `query()` with no filter to analyse a client — false keeps it away.\n */\n override get filterStable(): boolean {\n return false;\n }\n\n /**\n * The surviving ids — or, with nothing to filter by, {@link UNFILTERED}: one row whose id is\n * `NULL`, which no `dense_id` is. The answer says which it is, so two statements in flight can\n * never be read as each other's.\n */\n override query(filter?: FilterExpr | null): string {\n const clauses = (Array.isArray(filter) ? filter : [filter]).filter((c) => c !== undefined && c !== null);\n const structure = this.#structure();\n if (!structure || clauses.length === 0) return UNFILTERED;\n const where = clauses.map((c) => `(${String(c)})`).join(\" AND \");\n const named = [...new Set(clauses.flatMap((c) => collectColumns(c as never).map((ref: { column: string }) => ref.column)))];\n // A table that lacks a column the predicate names is not filtered by it — what a `WHERE` over a\n // union of the tables would do. A predicate no table can answer is refused rather than ignored,\n // so the unfiltered picture is never drawn as the filtered one.\n const answering = structure.vertices.filter((t) => named.every((c) => t.columns.has(c)));\n if (answering.length === 0) {\n this.#fail(new GraphError(\"graph/unfilterable\", `no vertex type has every column this clause names: ${named.join(\", \")}`));\n return UNFILTERED;\n }\n return structure.vertices\n .map((t) => {\n const from = relation(structure.from, t.name);\n return answering.includes(t)\n ? `SELECT ${ident(\"dense_id\")}::DOUBLE AS id FROM ${from} WHERE ${where}`\n : `SELECT ${ident(\"dense_id\")}::DOUBLE AS id FROM ${from}`;\n })\n .join(\" UNION ALL \");\n }\n\n override queryResult(data: unknown): this {\n const ids = ((data as Answer).getChild(\"id\")?.toArray() ?? []) as ArrayLike<number | null>;\n this.#kept(ids.length === 1 && ids[0] === null ? null : Float64Array.from(ids as ArrayLike<number>));\n return this;\n }\n\n override queryError(error: Error): this {\n this.#fail(queryFailure(error));\n return this;\n }\n}\n\n/**\n * **The reader's pick, published** — from the graph, so the crossfilter applies it to every chart and\n * skips it for the graph. A canvas that greyed out everything but a lasso of thirteen would hide the\n * neighbourhood the reader was looking at.\n */\nexport function publish(selection: Selection, self: MosaicClient, ids: readonly number[] | null): void {\n selection.update(\n clausePoints([\"dense_id\"], ids && ids.length > 0 ? ids.map((d) => [d]) : undefined, {\n source: self,\n clients: new Set([self]),\n }),\n );\n}\n"],"names":["UNFILTERED","GraphClient","MosaicClient","filterBy","structure","kept","fail","__privateAdd","_structure","_kept","_fail","__privateSet","filter","clauses","c","__privateGet","where","named","collectColumns","ref","answering","t","GraphError","from","relation","ident","data","ids","_a","error","queryFailure","publish","selection","self","clausePoints","d"],"mappings":";;;;;;;;AAmBA,MAAMA,IAAa;;AAEZ,MAAMC,UAAoBC,EAAa;AAAA,EAK5C,YACEC,GACAC,GACAC,GACAC,GACA;AACA,UAAMH,CAAQ;AAVhB,IAAAI,EAAA,MAAAC;AACA,IAAAD,EAAA,MAAAE;AACA,IAAAF,EAAA,MAAAG;AASE,IAAAC,EAAA,MAAKH,GAAaJ,IAClBO,EAAA,MAAKF,GAAQJ,IACbM,EAAA,MAAKD,GAAQJ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAa,eAAwB;AACnC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOS,MAAMM,GAAoC;AACjD,UAAMC,KAAW,MAAM,QAAQD,CAAM,IAAIA,IAAS,CAACA,CAAM,GAAG,OAAO,CAACE,MAAyBA,KAAM,IAAI,GACjGV,IAAYW,EAAA,MAAKP,GAAL;AAClB,QAAI,CAACJ,KAAaS,EAAQ,WAAW,EAAG,QAAOb;AAC/C,UAAMgB,IAAQH,EAAQ,IAAI,CAACC,MAAM,IAAI,OAAOA,CAAC,CAAC,GAAG,EAAE,KAAK,OAAO,GACzDG,IAAQ,CAAC,GAAG,IAAI,IAAIJ,EAAQ,QAAQ,CAACC,MAAMI,EAAeJ,CAAU,EAAE,IAAI,CAACK,MAA4BA,EAAI,MAAM,CAAC,CAAC,CAAC,GAIpHC,IAAYhB,EAAU,SAAS,OAAO,CAACiB,MAAMJ,EAAM,MAAM,CAACH,MAAMO,EAAE,QAAQ,IAAIP,CAAC,CAAC,CAAC;AACvF,WAAIM,EAAU,WAAW,KACvBL,EAAA,MAAKL,GAAL,WAAW,IAAIY,EAAW,sBAAsB,sDAAsDL,EAAM,KAAK,IAAI,CAAC,EAAE,IACjHjB,KAEFI,EAAU,SACd,IAAI,CAACiB,MAAM;AACV,YAAME,IAAOC,EAASpB,EAAU,MAAMiB,EAAE,IAAI;AAC5C,aAAOD,EAAU,SAASC,CAAC,IACvB,UAAUI,EAAM,UAAU,CAAC,uBAAuBF,CAAI,UAAUP,CAAK,KACrE,UAAUS,EAAM,UAAU,CAAC,uBAAuBF,CAAI;AAAA,IAC5D,CAAC,EACA,KAAK,aAAa;AAAA,EACvB;AAAA,EAES,YAAYG,GAAqB;;AACxC,UAAMC,MAAQC,IAAAF,EAAgB,SAAS,IAAI,MAA7B,gBAAAE,EAAgC,cAAa,CAAA;AAC3D,WAAAb,EAAA,MAAKN,GAAL,WAAWkB,EAAI,WAAW,KAAKA,EAAI,CAAC,MAAM,OAAO,OAAO,aAAa,KAAKA,CAAwB,IAC3F;AAAA,EACT;AAAA,EAES,WAAWE,GAAoB;AACtC,WAAAd,EAAA,MAAKL,GAAL,WAAWoB,EAAaD,CAAK,IACtB;AAAA,EACT;AACF;AA/DErB,IAAA,eACAC,IAAA,eACAC,IAAA;AAoEK,SAASqB,EAAQC,GAAsBC,GAAoBN,GAAqC;AACrG,EAAAK,EAAU;AAAA,IACRE,EAAa,CAAC,UAAU,GAAGP,KAAOA,EAAI,SAAS,IAAIA,EAAI,IAAI,CAACQ,MAAM,CAACA,CAAC,CAAC,IAAI,QAAW;AAAA,MAClF,QAAQF;AAAA,MACR,SAAS,oBAAI,IAAI,CAACA,CAAI,CAAC;AAAA,IAAA,CACxB;AAAA,EAAA;AAEL;"}
|
package/dist/core/error.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The failures the graph names itself: no GPU device to draw with, or the one it had was taken back;
|
|
3
|
-
* a corpus with no vertex to draw; a crossfilter clause no vertex type can answer. A
|
|
3
|
+
* a device that holds no positions for the points it was given; a corpus with no vertex to draw; a crossfilter clause no vertex type can answer. A
|
|
4
4
|
* corpus fossil will not read never gets here: `open` refuses it, coded. `data.after` is set when a deadline fired. Everything else reaches `onFailure` as thrown.
|
|
5
5
|
*/
|
|
6
6
|
export declare class GraphError extends Error {
|
|
7
|
-
readonly code: "graph/no-webgl" | "graph/context-lost" | "graph/nothing-to-draw" | "graph/unfilterable";
|
|
7
|
+
readonly code: "graph/no-webgl" | "graph/context-lost" | "graph/no-positions" | "graph/nothing-to-draw" | "graph/unfilterable";
|
|
8
8
|
readonly data: {
|
|
9
9
|
readonly after?: number;
|
|
10
10
|
};
|
|
11
11
|
readonly name = "GraphError";
|
|
12
|
-
constructor(code: "graph/no-webgl" | "graph/context-lost" | "graph/nothing-to-draw" | "graph/unfilterable", message: string, data?: {
|
|
12
|
+
constructor(code: "graph/no-webgl" | "graph/context-lost" | "graph/no-positions" | "graph/nothing-to-draw" | "graph/unfilterable", message: string, data?: {
|
|
13
13
|
readonly after?: number;
|
|
14
14
|
}, options?: ErrorOptions);
|
|
15
15
|
}
|
package/dist/core/error.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/core/error.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,UAAW,SAAQ,KAAK;IAGjC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,uBAAuB,GAAG,oBAAoB;
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/core/error.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,UAAW,SAAQ,KAAK;IAGjC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,oBAAoB,GAAG,uBAAuB,GAAG,oBAAoB;IAE9H,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAJ5C,SAAkB,IAAI,gBAAgB;gBAE3B,IAAI,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,oBAAoB,GAAG,uBAAuB,GAAG,oBAAoB,EAC9H,OAAO,EAAE,MAAM,EACN,IAAI,GAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,EAC/C,OAAO,CAAC,EAAE,YAAY;CAIzB"}
|
package/dist/core/error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sources":["../../src/core/error.ts"],"sourcesContent":["/**\n * The failures the graph names itself: no GPU device to draw with, or the one it had was taken back;\n * a corpus with no vertex to draw; a crossfilter clause no vertex type can answer. A\n * corpus fossil will not read never gets here: `open` refuses it, coded. `data.after` is set when a deadline fired. Everything else reaches `onFailure` as thrown.\n */\nexport class GraphError extends Error {\n override readonly name = \"GraphError\";\n constructor(\n readonly code: \"graph/no-webgl\" | \"graph/context-lost\" | \"graph/nothing-to-draw\" | \"graph/unfilterable\",\n message: string,\n readonly data: { readonly after?: number } = {},\n options?: ErrorOptions,\n ) {\n super(message, options);\n }\n}\n"],"names":["GraphError","code","message","data","options","__publicField"],"mappings":";;;AAKO,MAAMA,UAAmB,MAAM;AAAA,EAEpC,YACWC,GACTC,GACSC,IAAoC,CAAA,GAC7CC,GACA;AACA,UAAMF,GAASE,CAAO;AAPN,IAAAC,EAAA,cAAO;AAEd,SAAA,OAAAJ,GAEA,KAAA,OAAAE;AAAA,EAIX;AACF;"}
|
|
1
|
+
{"version":3,"file":"error.js","sources":["../../src/core/error.ts"],"sourcesContent":["/**\n * The failures the graph names itself: no GPU device to draw with, or the one it had was taken back;\n * a device that holds no positions for the points it was given; a corpus with no vertex to draw; a crossfilter clause no vertex type can answer. A\n * corpus fossil will not read never gets here: `open` refuses it, coded. `data.after` is set when a deadline fired. Everything else reaches `onFailure` as thrown.\n */\nexport class GraphError extends Error {\n override readonly name = \"GraphError\";\n constructor(\n readonly code: \"graph/no-webgl\" | \"graph/context-lost\" | \"graph/no-positions\" | \"graph/nothing-to-draw\" | \"graph/unfilterable\",\n message: string,\n readonly data: { readonly after?: number } = {},\n options?: ErrorOptions,\n ) {\n super(message, options);\n }\n}\n"],"names":["GraphError","code","message","data","options","__publicField"],"mappings":";;;AAKO,MAAMA,UAAmB,MAAM;AAAA,EAEpC,YACWC,GACTC,GACSC,IAAoC,CAAA,GAC7CC,GACA;AACA,UAAMF,GAASE,CAAO;AAPN,IAAAC,EAAA,cAAO;AAEd,SAAA,OAAAJ,GAEA,KAAA,OAAAE;AAAA,EAIX;AACF;"}
|
package/dist/core/state.d.ts
CHANGED
|
@@ -50,9 +50,12 @@ export interface GraphOptions extends Channels {
|
|
|
50
50
|
* **It is the data's life, not the layout's.** A layout running over a drawn graph is `idle` here and
|
|
51
51
|
* `running` in `motion`: two axes, because each can move without the other — a filter loads under a
|
|
52
52
|
* paused layout, and a layout runs over a graph with nothing left to read. A host that shows one word
|
|
53
|
-
* reads both,
|
|
53
|
+
* reads both, and the `GraphStatus` part is that word, so a host draws the part, not the two axes.
|
|
54
|
+
*
|
|
55
|
+
* Named for its axis rather than `GraphStatus` because the part holds that name: a consumer writes
|
|
56
|
+
* the part in every footer, and this union only where it reads `status` itself.
|
|
54
57
|
*/
|
|
55
|
-
export type
|
|
58
|
+
export type DataStatus = "none" | "loading" | "idle" | "failed";
|
|
56
59
|
/** What the loaded graph holds, under the page's filter. */
|
|
57
60
|
export interface Drawn {
|
|
58
61
|
/** Vertices in full colour: every one with a position that survives the filter. */
|
|
@@ -66,9 +69,11 @@ export interface Drawn {
|
|
|
66
69
|
}
|
|
67
70
|
/** What a host and the parts read, through `useGraphState`. */
|
|
68
71
|
export interface GraphState {
|
|
69
|
-
readonly status:
|
|
72
|
+
readonly status: DataStatus;
|
|
70
73
|
/** Every vertex of the corpus — it does not shrink with a filter. */
|
|
71
74
|
readonly total: number | undefined;
|
|
75
|
+
/** Vertices of the corpus the page's filter keeps, or `null` when nothing is filtered. */
|
|
76
|
+
readonly matching: number | null;
|
|
72
77
|
/** What is loaded, or `null` before the graph has loaded. */
|
|
73
78
|
readonly drawn: Drawn | null;
|
|
74
79
|
/** The categorical domain before anything is loaded: the drawn tables, or the host's names. */
|
package/dist/core/state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/core/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAElF,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC5C;;;OAGG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,gGAAgG;IAChG,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,2DAA2D;IAC3D,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,sGAAsG;IACtG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9C,4GAA4G;IAC5G,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,8FAA8F;IAC9F,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,kEAAkE;IAClE,GAAG,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;CAC7C;AAED
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/core/state.ts"],"names":[],"mappings":"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"}
|
package/dist/core/store.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { GraphOptions, GraphStore } from './state';
|
|
2
|
-
export type { Drawn, GraphOptions, GraphSnapshot, GraphState,
|
|
2
|
+
export type { Drawn, GraphOptions, GraphSnapshot, GraphState, DataStatus, GraphStore } from './state';
|
|
3
3
|
export declare function createGraph(initial: GraphOptions): GraphStore;
|
|
4
4
|
//# sourceMappingURL=store.d.ts.map
|
package/dist/core/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAS,YAAY,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAS,YAAY,EAA6B,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1F,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAmCtG,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,UAAU,CA8S7D"}
|
package/dist/core/store.js
CHANGED
|
@@ -4,38 +4,45 @@ import { GraphClient as M, publish as R } from "./client.js";
|
|
|
4
4
|
import { GraphError as V } from "./error.js";
|
|
5
5
|
import { loadGeometry as W, loadEncoding as X } from "./load.js";
|
|
6
6
|
import { readStructure as Y } from "./source.js";
|
|
7
|
-
function Z(
|
|
8
|
-
const
|
|
7
|
+
function Z(f, t, a) {
|
|
8
|
+
const d = t.domain.map(() => 0), p = new Uint8Array(f.size);
|
|
9
9
|
let l = 0;
|
|
10
|
-
for (let r = 0; r <
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
10
|
+
for (let r = 0; r < f.size; r++) {
|
|
11
|
+
if (a && !a[r] || Number.isNaN(f.positions[r * 2])) continue;
|
|
12
|
+
p[r] = 1, l++;
|
|
13
|
+
const h = t.ranks[r];
|
|
14
|
+
d[h] = (d[h] ?? 0) + 1;
|
|
15
15
|
}
|
|
16
|
-
let
|
|
17
|
-
const { links: i } =
|
|
16
|
+
let s = 0;
|
|
17
|
+
const { links: i } = f;
|
|
18
18
|
for (let r = 0; r < i.length; r += 2)
|
|
19
|
-
|
|
20
|
-
return { vertices: l, edges:
|
|
19
|
+
p[i[r]] && p[i[r + 1]] && s++;
|
|
20
|
+
return { vertices: l, edges: s, domain: t.domain, tally: d };
|
|
21
21
|
}
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
function _(f) {
|
|
23
|
+
if (f === null) return null;
|
|
24
|
+
let t = 0;
|
|
25
|
+
for (const a of f) t += a;
|
|
26
|
+
return t;
|
|
26
27
|
}
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
28
|
+
function H(f, t) {
|
|
29
|
+
const a = new Uint8Array(f);
|
|
30
|
+
for (const d of t) d < f && (a[d] = 1);
|
|
31
|
+
return a;
|
|
32
|
+
}
|
|
33
|
+
function le(f) {
|
|
34
|
+
let t = f;
|
|
35
|
+
const a = /* @__PURE__ */ new Set();
|
|
36
|
+
let d = !1, p = !1, l = $(f), s = null, i = null, r = null, h = null, g = null, z = [];
|
|
31
37
|
const k = { structure: 0, geometry: 0, encoding: 0 }, b = { structure: !1, geometry: !1, encoding: !1 };
|
|
32
|
-
let m = null, B = null,
|
|
38
|
+
let m = null, B = null, O = !1, C = !0, N = null;
|
|
33
39
|
const G = (e) => {
|
|
34
|
-
C ? N = { error: e } :
|
|
40
|
+
C ? N = { error: e } : t.onFailure(e);
|
|
35
41
|
};
|
|
36
42
|
let c = {
|
|
37
43
|
status: "none",
|
|
38
44
|
total: void 0,
|
|
45
|
+
matching: null,
|
|
39
46
|
drawn: null,
|
|
40
47
|
domain: [],
|
|
41
48
|
selection: null,
|
|
@@ -45,7 +52,7 @@ function re(d) {
|
|
|
45
52
|
tool: null,
|
|
46
53
|
motion: "settled",
|
|
47
54
|
progress: 1,
|
|
48
|
-
options:
|
|
55
|
+
options: t,
|
|
49
56
|
structure: null,
|
|
50
57
|
binding: l,
|
|
51
58
|
geometry: null,
|
|
@@ -53,32 +60,33 @@ function re(d) {
|
|
|
53
60
|
mask: null
|
|
54
61
|
}, T = { key: [], value: [] };
|
|
55
62
|
function E() {
|
|
56
|
-
const e = (
|
|
57
|
-
return n.some((
|
|
63
|
+
const e = (s == null ? void 0 : s.vertices) ?? [], n = [e, l.byTable, l.category, t.categories];
|
|
64
|
+
return n.some((o, u) => o !== T.key[u]) && (T = { key: n, value: L(e, l, t.categories) }), T.value;
|
|
58
65
|
}
|
|
59
66
|
let F = { key: [], value: null };
|
|
60
67
|
function I() {
|
|
61
|
-
const e = [i, r,
|
|
62
|
-
return e.some((n,
|
|
68
|
+
const e = [i, r, g];
|
|
69
|
+
return e.some((n, o) => n !== F.key[o]) && (F = { key: e, value: i && r ? Z(i, r, g) : null }), F.value;
|
|
63
70
|
}
|
|
64
71
|
function J() {
|
|
65
|
-
if (
|
|
66
|
-
if (
|
|
67
|
-
const n = i !== null && [i, r,
|
|
72
|
+
if (d || p) return "failed";
|
|
73
|
+
if (t.from === null || t.coordinator === null) return "none";
|
|
74
|
+
const n = i !== null && [i, r, g].every((o, u) => o === z[u]);
|
|
68
75
|
return b.structure || b.geometry || b.encoding || !n ? "loading" : "idle";
|
|
69
76
|
}
|
|
70
|
-
function
|
|
77
|
+
function y(e = {}) {
|
|
71
78
|
c = {
|
|
72
79
|
...c,
|
|
73
|
-
total:
|
|
80
|
+
total: s == null ? void 0 : s.size,
|
|
81
|
+
matching: g === c.mask ? c.matching : _(g),
|
|
74
82
|
drawn: I(),
|
|
75
83
|
domain: E(),
|
|
76
|
-
options:
|
|
77
|
-
structure:
|
|
84
|
+
options: t,
|
|
85
|
+
structure: s,
|
|
78
86
|
binding: l,
|
|
79
87
|
geometry: i,
|
|
80
88
|
encoding: r,
|
|
81
|
-
mask:
|
|
89
|
+
mask: g,
|
|
82
90
|
...e
|
|
83
91
|
}, c = { ...c, status: J() }, P();
|
|
84
92
|
}
|
|
@@ -86,58 +94,58 @@ function re(d) {
|
|
|
86
94
|
c = { ...c, ...e }, P();
|
|
87
95
|
}
|
|
88
96
|
function P() {
|
|
89
|
-
for (const e of
|
|
97
|
+
for (const e of a) e();
|
|
90
98
|
}
|
|
91
|
-
function S(e, n,
|
|
92
|
-
const
|
|
99
|
+
function S(e, n, o) {
|
|
100
|
+
const u = ++k[e];
|
|
93
101
|
b[e] = !0, n().then(
|
|
94
102
|
(w) => {
|
|
95
|
-
k[e] ===
|
|
103
|
+
k[e] === u && (b[e] = !1, o(w), y());
|
|
96
104
|
},
|
|
97
105
|
(w) => {
|
|
98
|
-
k[e] ===
|
|
106
|
+
k[e] === u && (b[e] = !1, d = !0, G(w), y());
|
|
99
107
|
}
|
|
100
108
|
);
|
|
101
109
|
}
|
|
102
110
|
function U() {
|
|
103
|
-
const { coordinator: e, from: n } =
|
|
104
|
-
e === null || n === null || S("structure", () => Y(e, n), (
|
|
105
|
-
if (
|
|
106
|
-
|
|
111
|
+
const { coordinator: e, from: n } = t;
|
|
112
|
+
e === null || n === null || S("structure", () => Y(e, n), (o) => {
|
|
113
|
+
if (o.size === 0) {
|
|
114
|
+
d = !0, G(new V("graph/nothing-to-draw", `the corpus attached as ${n} has no vertex`));
|
|
107
115
|
return;
|
|
108
116
|
}
|
|
109
|
-
|
|
117
|
+
s = o, j(), m == null || m.requestQuery();
|
|
110
118
|
});
|
|
111
119
|
}
|
|
112
120
|
function j() {
|
|
113
|
-
const { coordinator: e } =
|
|
114
|
-
e === null || n === null || S("geometry", () => W(e, n, l), (
|
|
115
|
-
i =
|
|
121
|
+
const { coordinator: e } = t, n = s;
|
|
122
|
+
e === null || n === null || S("geometry", () => W(e, n, l), (o) => {
|
|
123
|
+
i = o, g = h ? H(o.size, h) : null, q();
|
|
116
124
|
});
|
|
117
125
|
}
|
|
118
126
|
function q() {
|
|
119
|
-
const { coordinator: e } =
|
|
127
|
+
const { coordinator: e } = t, n = i;
|
|
120
128
|
if (e === null || n === null) return;
|
|
121
|
-
const
|
|
122
|
-
S("encoding", () => X(e, n, l,
|
|
123
|
-
r =
|
|
129
|
+
const o = E();
|
|
130
|
+
S("encoding", () => X(e, n, l, o), (u) => {
|
|
131
|
+
r = u;
|
|
124
132
|
});
|
|
125
133
|
}
|
|
126
134
|
function K() {
|
|
127
135
|
for (const e of Object.keys(k))
|
|
128
136
|
k[e]++, b[e] = !1;
|
|
129
|
-
|
|
137
|
+
d = !1, s = i = r = null, h = g = null, z = [], y({ selection: null, focus: null, hovered: null, pinned: [] }), U();
|
|
130
138
|
}
|
|
131
139
|
function A() {
|
|
132
140
|
D();
|
|
133
|
-
const { coordinator: e, filterBy: n } =
|
|
141
|
+
const { coordinator: e, filterBy: n } = t;
|
|
134
142
|
e !== null && (m = new M(
|
|
135
143
|
n,
|
|
136
|
-
() =>
|
|
137
|
-
(
|
|
138
|
-
|
|
144
|
+
() => s,
|
|
145
|
+
(o) => {
|
|
146
|
+
h = o, g = o && i ? H(i.size, o) : null, y();
|
|
139
147
|
},
|
|
140
|
-
(
|
|
148
|
+
(o) => G(o)
|
|
141
149
|
), e.connect(m), B = e);
|
|
142
150
|
}
|
|
143
151
|
function D() {
|
|
@@ -150,35 +158,35 @@ function re(d) {
|
|
|
150
158
|
* survives StrictMode mounting everything twice.
|
|
151
159
|
*/
|
|
152
160
|
subscribe(e) {
|
|
153
|
-
if (
|
|
161
|
+
if (a.add(e), !O && (O = !0, A(), N !== null)) {
|
|
154
162
|
const { error: n } = N;
|
|
155
|
-
N = null,
|
|
163
|
+
N = null, t.onFailure(n);
|
|
156
164
|
}
|
|
157
165
|
return () => {
|
|
158
|
-
|
|
166
|
+
a.delete(e), a.size === 0 && Q.destroy();
|
|
159
167
|
};
|
|
160
168
|
},
|
|
161
169
|
getSnapshot: () => c,
|
|
162
|
-
getOptions: () =>
|
|
170
|
+
getOptions: () => t,
|
|
163
171
|
setOptions(e) {
|
|
164
|
-
const n =
|
|
165
|
-
|
|
166
|
-
const
|
|
172
|
+
const n = t;
|
|
173
|
+
t = e;
|
|
174
|
+
const o = l;
|
|
167
175
|
if (l = $(e), e.from !== n.from || e.coordinator !== n.coordinator)
|
|
168
|
-
return
|
|
169
|
-
|
|
176
|
+
return O && e.coordinator !== n.coordinator && A(), K();
|
|
177
|
+
O && e.filterBy !== n.filterBy && A(), l.x !== o.x || l.y !== o.y ? j() : (l.category !== o.category || l.byTable !== o.byTable || l.size !== o.size || l.cluster !== o.cluster || e.categories !== n.categories) && q(), y();
|
|
170
178
|
},
|
|
171
179
|
destroy() {
|
|
172
|
-
|
|
180
|
+
O = !1, D(), a.clear();
|
|
173
181
|
},
|
|
174
|
-
select(e, n = "
|
|
182
|
+
select(e, n = "external", o = "") {
|
|
175
183
|
var w;
|
|
176
|
-
const
|
|
177
|
-
v({ selection:
|
|
184
|
+
const u = e && e.length > 0 ? { vertices: [...e], source: n, label: o } : null;
|
|
185
|
+
v({ selection: u }), (w = t.onSelect) == null || w.call(t, u), t.filterBy && m && R(t.filterBy, m, u ? u.vertices : null);
|
|
178
186
|
},
|
|
179
187
|
focus(e) {
|
|
180
188
|
var n;
|
|
181
|
-
e !== c.focus && (v({ focus: e }), (n =
|
|
189
|
+
e !== c.focus && (v({ focus: e }), (n = t.onFocus) == null || n.call(t, e));
|
|
182
190
|
},
|
|
183
191
|
hover(e) {
|
|
184
192
|
e !== c.hovered && v({ hovered: e });
|
|
@@ -196,19 +204,19 @@ function re(d) {
|
|
|
196
204
|
e !== c.progress && v({ progress: e });
|
|
197
205
|
},
|
|
198
206
|
renderable() {
|
|
199
|
-
|
|
207
|
+
p && (p = !1, y());
|
|
200
208
|
},
|
|
201
209
|
unrenderable(e) {
|
|
202
|
-
|
|
210
|
+
p = !0, G(e), y();
|
|
203
211
|
},
|
|
204
212
|
reportDrawn(e) {
|
|
205
213
|
const n = [e.geometry, e.encoding, e.mask];
|
|
206
|
-
n.every((
|
|
214
|
+
n.every((o, u) => o === z[u]) || (z = n, y());
|
|
207
215
|
}
|
|
208
216
|
};
|
|
209
|
-
return U(),
|
|
217
|
+
return U(), y(), C = !1, Q;
|
|
210
218
|
}
|
|
211
219
|
export {
|
|
212
|
-
|
|
220
|
+
le as createGraph
|
|
213
221
|
};
|
|
214
222
|
//# sourceMappingURL=store.js.map
|
package/dist/core/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sources":["../../src/core/store.ts"],"sourcesContent":["import type { Coordinator } from \"@kanzo-tech/mosaic\";\nimport { domainOf } from \"./categories\";\nimport { bindingOf } from \"./channels\";\nimport { GraphClient, publish } from \"./client\";\nimport { GraphError } from \"./error\";\nimport { loadEncoding, loadGeometry, type Encoding, type Geometry } from \"./load\";\nimport { readStructure, type Structure } from \"./source\";\nimport type { Drawn, GraphOptions, GraphSnapshot, GraphStatus, GraphStore } from \"./state\";\n\nexport type { Drawn, GraphOptions, GraphSnapshot, GraphState, GraphStatus, GraphStore } from \"./state\";\n\nfunction drawnOf(geometry: Geometry, encoding: Encoding, mask: Uint8Array | null): Drawn {\n const tally = encoding.domain.map(() => 0);\n const shown = new Uint8Array(geometry.size);\n let vertices = 0;\n for (let id = 0; id < geometry.size; id++) {\n if ((mask && !mask[id]) || Number.isNaN(geometry.positions[id * 2])) continue;\n shown[id] = 1;\n vertices++;\n const rank = encoding.ranks[id] as number;\n tally[rank] = (tally[rank] ?? 0) + 1;\n }\n let edges = 0;\n const { links } = geometry;\n for (let i = 0; i < links.length; i += 2) {\n if (shown[links[i] as number] && shown[links[i + 1] as number]) edges++;\n }\n return { vertices, edges, domain: encoding.domain, tally };\n}\n\n/** `1` where a vertex is among `ids`. */\nfunction maskOf(size: number, ids: Float64Array): Uint8Array {\n const mask = new Uint8Array(size);\n for (const id of ids) if (id < size) mask[id] = 1;\n return mask;\n}\n\nexport function createGraph(initial: GraphOptions): GraphStore {\n let options = initial;\n const listeners = new Set<() => void>();\n\n let failed = false;\n let unrenderable = false;\n let binding = bindingOf(initial);\n let structure: Structure | null = null;\n let geometry: Geometry | null = null;\n let encoding: Encoding | null = null;\n let kept: Float64Array | null = null;\n let mask: Uint8Array | null = null;\n let uploaded: readonly unknown[] = [];\n /** One read per kind in flight; a newer one makes an older one's answer stale. */\n const reading = { structure: 0, geometry: 0, encoding: 0 };\n const pending = { structure: false, geometry: false, encoding: false };\n let client: GraphClient | null = null;\n let connected: Coordinator | null = null;\n let active = false;\n\n // A failure found while the store is being built is found while React is still rendering —\n // `useGraph` builds it in `useState` — and a host's `onFailure` is usually a `setState`. It is held\n // and reported to the first subscriber, which arrives in the commit phase.\n let building = true;\n let held: { error: unknown } | null = null;\n const fail = (error: unknown) => {\n if (building) held = { error };\n else options.onFailure(error);\n };\n\n let snapshot: GraphSnapshot = {\n status: \"none\",\n total: undefined,\n drawn: null,\n domain: [],\n selection: null,\n focus: null,\n hovered: null,\n pinned: [],\n tool: null,\n motion: \"settled\",\n progress: 1,\n options,\n structure: null,\n binding,\n geometry: null,\n encoding: null,\n mask: null,\n };\n\n let domain: { key: unknown[]; value: readonly unknown[] } = { key: [], value: [] };\n function domainNow(): readonly unknown[] {\n const tables = structure?.vertices ?? [];\n const key = [tables, binding.byTable, binding.category, options.categories];\n if (key.some((part, i) => part !== domain.key[i])) domain = { key, value: domainOf(tables, binding, options.categories) };\n return domain.value;\n }\n\n let drawn: { key: unknown[]; value: Drawn | null } = { key: [], value: null };\n function drawnNow(): Drawn | null {\n const key = [geometry, encoding, mask];\n if (key.some((part, i) => part !== drawn.key[i])) {\n drawn = { key, value: geometry && encoding ? drawnOf(geometry, encoding, mask) : null };\n }\n return drawn.value;\n }\n\n function statusOf(): GraphStatus {\n if (failed || unrenderable) return \"failed\";\n if (options.from === null || options.coordinator === null) return \"none\";\n const current = [geometry, encoding, mask];\n const shown = geometry !== null && current.every((part, i) => part === uploaded[i]);\n return pending.structure || pending.geometry || pending.encoding || !shown ? \"loading\" : \"idle\";\n }\n\n function notify(fields: Partial<GraphSnapshot> = {}): void {\n snapshot = {\n ...snapshot,\n total: structure?.size,\n drawn: drawnNow(),\n domain: domainNow(),\n options,\n structure,\n binding,\n geometry,\n encoding,\n mask,\n ...fields,\n };\n snapshot = { ...snapshot, status: statusOf() };\n emit();\n }\n\n /** A change of state only — hover, focus, selection, tool, motion — derives nothing. */\n function patch(fields: Partial<GraphSnapshot>): void {\n snapshot = { ...snapshot, ...fields };\n emit();\n }\n\n function emit(): void {\n for (const listener of listeners) listener();\n }\n\n /**\n * Read `kind`, and keep the answer only if no newer read of the same kind started meanwhile. The\n * coordinator cannot be told to stop a statement, so a stale answer is dropped rather than aborted.\n */\n function read<T>(kind: keyof typeof reading, ask: () => Promise<T>, done: (value: T) => void): void {\n const ticket = ++reading[kind];\n pending[kind] = true;\n ask().then(\n (value) => {\n if (reading[kind] !== ticket) return;\n pending[kind] = false;\n done(value);\n notify();\n },\n (error: unknown) => {\n if (reading[kind] !== ticket) return;\n pending[kind] = false;\n failed = true;\n fail(error);\n notify();\n },\n );\n }\n\n function loadStructure(): void {\n const { coordinator, from } = options;\n if (coordinator === null || from === null) return;\n read(\"structure\", () => readStructure(coordinator, from), (next) => {\n if (next.size === 0) {\n failed = true;\n fail(new GraphError(\"graph/nothing-to-draw\", `the corpus attached as ${from} has no vertex`));\n return;\n }\n structure = next;\n loadPositions();\n client?.requestQuery();\n });\n }\n\n function loadPositions(): void {\n const { coordinator } = options;\n const given = structure;\n if (coordinator === null || given === null) return;\n read(\"geometry\", () => loadGeometry(coordinator, given, binding), (next) => {\n geometry = next;\n mask = kept ? maskOf(next.size, kept) : null;\n loadChannels();\n });\n }\n\n function loadChannels(): void {\n const { coordinator } = options;\n const given = geometry;\n if (coordinator === null || given === null) return;\n const seed = domainNow();\n read(\"encoding\", () => loadEncoding(coordinator, given, binding, seed), (next) => {\n encoding = next;\n });\n }\n\n function reset(): void {\n for (const kind of Object.keys(reading) as (keyof typeof reading)[]) {\n reading[kind]++;\n pending[kind] = false;\n }\n failed = false;\n structure = geometry = encoding = null;\n kept = mask = null;\n uploaded = [];\n notify({ selection: null, focus: null, hovered: null, pinned: [] });\n loadStructure();\n }\n\n /** The graph's Mosaic client, connected to the coordinator while anything is subscribed. */\n function connect(): void {\n disconnect();\n const { coordinator, filterBy } = options;\n if (coordinator === null) return;\n client = new GraphClient(\n filterBy,\n () => structure,\n (ids) => {\n kept = ids;\n mask = ids && geometry ? maskOf(geometry.size, ids) : null;\n notify();\n },\n (error) => fail(error),\n );\n coordinator.connect(client);\n connected = coordinator;\n }\n\n function disconnect(): void {\n if (client && connected) connected.disconnect(client);\n client = null;\n connected = null;\n }\n\n const store: GraphStore = {\n /**\n * The first subscriber connects the client to the coordinator, and the last one disconnects it\n * and lets the graph go — `QueryObserver`'s `onSubscribe`/`onUnsubscribe`, which is what\n * survives StrictMode mounting everything twice.\n */\n subscribe(listener) {\n listeners.add(listener);\n if (!active) {\n active = true;\n connect();\n if (held !== null) {\n const { error } = held;\n held = null;\n options.onFailure(error);\n }\n }\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0) store.destroy();\n };\n },\n getSnapshot: () => snapshot,\n getOptions: () => options,\n setOptions(next) {\n const previous = options;\n options = next;\n const before = binding;\n binding = bindingOf(next);\n if (next.from !== previous.from || next.coordinator !== previous.coordinator) {\n if (active && next.coordinator !== previous.coordinator) connect();\n return reset();\n }\n if (active && next.filterBy !== previous.filterBy) connect();\n if (binding.x !== before.x || binding.y !== before.y) loadPositions();\n else if (\n binding.category !== before.category ||\n binding.byTable !== before.byTable ||\n binding.size !== before.size ||\n binding.cluster !== before.cluster ||\n next.categories !== previous.categories\n ) {\n loadChannels();\n }\n notify();\n },\n destroy() {\n active = false;\n disconnect();\n listeners.clear();\n },\n select(vertices, source = \"node\", label = \"\") {\n const selection = vertices && vertices.length > 0 ? { vertices: [...vertices], source, label } : null;\n patch({ selection });\n options.onSelect?.(selection);\n if (options.filterBy && client) publish(options.filterBy, client, selection ? selection.vertices : null);\n },\n focus(vertex) {\n if (vertex === snapshot.focus) return;\n patch({ focus: vertex });\n options.onFocus?.(vertex);\n },\n hover(vertex) {\n if (vertex !== snapshot.hovered) patch({ hovered: vertex });\n },\n pin(vertices) {\n patch({ pinned: [...vertices] });\n },\n setTool(tool) {\n if (tool !== snapshot.tool) patch({ tool });\n },\n report(motion) {\n if (motion !== snapshot.motion) patch({ motion });\n },\n reportProgress(value) {\n if (value !== snapshot.progress) patch({ progress: value });\n },\n renderable() {\n if (!unrenderable) return;\n unrenderable = false;\n notify();\n },\n unrenderable(error) {\n unrenderable = true;\n fail(error);\n notify();\n },\n reportDrawn(drawnSnapshot) {\n const next = [drawnSnapshot.geometry, drawnSnapshot.encoding, drawnSnapshot.mask];\n if (next.every((part, i) => part === uploaded[i])) return;\n uploaded = next;\n notify();\n },\n };\n\n loadStructure();\n notify();\n building = false;\n return store;\n}\n"],"names":["drawnOf","geometry","encoding","mask","tally","shown","vertices","id","rank","edges","links","i","maskOf","size","ids","createGraph","initial","options","listeners","failed","unrenderable","binding","bindingOf","structure","kept","uploaded","reading","pending","client","connected","active","building","held","fail","error","snapshot","domain","domainNow","tables","key","part","domainOf","drawn","drawnNow","statusOf","notify","fields","emit","patch","listener","read","kind","ask","done","ticket","value","loadStructure","coordinator","from","readStructure","next","GraphError","loadPositions","given","loadGeometry","loadChannels","seed","loadEncoding","reset","connect","disconnect","filterBy","GraphClient","store","previous","before","source","label","selection","_a","publish","vertex","tool","motion","drawnSnapshot"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"store.js","sources":["../../src/core/store.ts"],"sourcesContent":["import type { Coordinator } from \"@kanzo-tech/mosaic\";\nimport { domainOf } from \"./categories\";\nimport { bindingOf } from \"./channels\";\nimport { GraphClient, publish } from \"./client\";\nimport { GraphError } from \"./error\";\nimport { loadEncoding, loadGeometry, type Encoding, type Geometry } from \"./load\";\nimport { readStructure, type Structure } from \"./source\";\nimport type { Drawn, GraphOptions, GraphSnapshot, DataStatus, GraphStore } from \"./state\";\n\nexport type { Drawn, GraphOptions, GraphSnapshot, GraphState, DataStatus, GraphStore } from \"./state\";\n\nfunction drawnOf(geometry: Geometry, encoding: Encoding, mask: Uint8Array | null): Drawn {\n const tally = encoding.domain.map(() => 0);\n const shown = new Uint8Array(geometry.size);\n let vertices = 0;\n for (let id = 0; id < geometry.size; id++) {\n if ((mask && !mask[id]) || Number.isNaN(geometry.positions[id * 2])) continue;\n shown[id] = 1;\n vertices++;\n const rank = encoding.ranks[id] as number;\n tally[rank] = (tally[rank] ?? 0) + 1;\n }\n let edges = 0;\n const { links } = geometry;\n for (let i = 0; i < links.length; i += 2) {\n if (shown[links[i] as number] && shown[links[i + 1] as number]) edges++;\n }\n return { vertices, edges, domain: encoding.domain, tally };\n}\n\nfunction matchingOf(mask: Uint8Array | null): number | null {\n if (mask === null) return null;\n let n = 0;\n for (const kept of mask) n += kept;\n return n;\n}\n\n/** `1` where a vertex is among `ids`. */\nfunction maskOf(size: number, ids: Float64Array): Uint8Array {\n const mask = new Uint8Array(size);\n for (const id of ids) if (id < size) mask[id] = 1;\n return mask;\n}\n\nexport function createGraph(initial: GraphOptions): GraphStore {\n let options = initial;\n const listeners = new Set<() => void>();\n\n let failed = false;\n let unrenderable = false;\n let binding = bindingOf(initial);\n let structure: Structure | null = null;\n let geometry: Geometry | null = null;\n let encoding: Encoding | null = null;\n let kept: Float64Array | null = null;\n let mask: Uint8Array | null = null;\n let uploaded: readonly unknown[] = [];\n /** One read per kind in flight; a newer one makes an older one's answer stale. */\n const reading = { structure: 0, geometry: 0, encoding: 0 };\n const pending = { structure: false, geometry: false, encoding: false };\n let client: GraphClient | null = null;\n let connected: Coordinator | null = null;\n let active = false;\n\n // A failure found while the store is being built is found while React is still rendering —\n // `useGraph` builds it in `useState` — and a host's `onFailure` is usually a `setState`. It is held\n // and reported to the first subscriber, which arrives in the commit phase.\n let building = true;\n let held: { error: unknown } | null = null;\n const fail = (error: unknown) => {\n if (building) held = { error };\n else options.onFailure(error);\n };\n\n let snapshot: GraphSnapshot = {\n status: \"none\",\n total: undefined,\n matching: null,\n drawn: null,\n domain: [],\n selection: null,\n focus: null,\n hovered: null,\n pinned: [],\n tool: null,\n motion: \"settled\",\n progress: 1,\n options,\n structure: null,\n binding,\n geometry: null,\n encoding: null,\n mask: null,\n };\n\n let domain: { key: unknown[]; value: readonly unknown[] } = { key: [], value: [] };\n function domainNow(): readonly unknown[] {\n const tables = structure?.vertices ?? [];\n const key = [tables, binding.byTable, binding.category, options.categories];\n if (key.some((part, i) => part !== domain.key[i])) domain = { key, value: domainOf(tables, binding, options.categories) };\n return domain.value;\n }\n\n let drawn: { key: unknown[]; value: Drawn | null } = { key: [], value: null };\n function drawnNow(): Drawn | null {\n const key = [geometry, encoding, mask];\n if (key.some((part, i) => part !== drawn.key[i])) {\n drawn = { key, value: geometry && encoding ? drawnOf(geometry, encoding, mask) : null };\n }\n return drawn.value;\n }\n\n function statusOf(): DataStatus {\n if (failed || unrenderable) return \"failed\";\n if (options.from === null || options.coordinator === null) return \"none\";\n const current = [geometry, encoding, mask];\n const shown = geometry !== null && current.every((part, i) => part === uploaded[i]);\n return pending.structure || pending.geometry || pending.encoding || !shown ? \"loading\" : \"idle\";\n }\n\n function notify(fields: Partial<GraphSnapshot> = {}): void {\n snapshot = {\n ...snapshot,\n total: structure?.size,\n matching: mask === snapshot.mask ? snapshot.matching : matchingOf(mask),\n drawn: drawnNow(),\n domain: domainNow(),\n options,\n structure,\n binding,\n geometry,\n encoding,\n mask,\n ...fields,\n };\n snapshot = { ...snapshot, status: statusOf() };\n emit();\n }\n\n /** A change of state only — hover, focus, selection, tool, motion — derives nothing. */\n function patch(fields: Partial<GraphSnapshot>): void {\n snapshot = { ...snapshot, ...fields };\n emit();\n }\n\n function emit(): void {\n for (const listener of listeners) listener();\n }\n\n /**\n * Read `kind`, and keep the answer only if no newer read of the same kind started meanwhile. The\n * coordinator cannot be told to stop a statement, so a stale answer is dropped rather than aborted.\n */\n function read<T>(kind: keyof typeof reading, ask: () => Promise<T>, done: (value: T) => void): void {\n const ticket = ++reading[kind];\n pending[kind] = true;\n ask().then(\n (value) => {\n if (reading[kind] !== ticket) return;\n pending[kind] = false;\n done(value);\n notify();\n },\n (error: unknown) => {\n if (reading[kind] !== ticket) return;\n pending[kind] = false;\n failed = true;\n fail(error);\n notify();\n },\n );\n }\n\n function loadStructure(): void {\n const { coordinator, from } = options;\n if (coordinator === null || from === null) return;\n read(\"structure\", () => readStructure(coordinator, from), (next) => {\n if (next.size === 0) {\n failed = true;\n fail(new GraphError(\"graph/nothing-to-draw\", `the corpus attached as ${from} has no vertex`));\n return;\n }\n structure = next;\n loadPositions();\n client?.requestQuery();\n });\n }\n\n function loadPositions(): void {\n const { coordinator } = options;\n const given = structure;\n if (coordinator === null || given === null) return;\n read(\"geometry\", () => loadGeometry(coordinator, given, binding), (next) => {\n geometry = next;\n mask = kept ? maskOf(next.size, kept) : null;\n loadChannels();\n });\n }\n\n function loadChannels(): void {\n const { coordinator } = options;\n const given = geometry;\n if (coordinator === null || given === null) return;\n const seed = domainNow();\n read(\"encoding\", () => loadEncoding(coordinator, given, binding, seed), (next) => {\n encoding = next;\n });\n }\n\n function reset(): void {\n for (const kind of Object.keys(reading) as (keyof typeof reading)[]) {\n reading[kind]++;\n pending[kind] = false;\n }\n failed = false;\n structure = geometry = encoding = null;\n kept = mask = null;\n uploaded = [];\n notify({ selection: null, focus: null, hovered: null, pinned: [] });\n loadStructure();\n }\n\n /** The graph's Mosaic client, connected to the coordinator while anything is subscribed. */\n function connect(): void {\n disconnect();\n const { coordinator, filterBy } = options;\n if (coordinator === null) return;\n client = new GraphClient(\n filterBy,\n () => structure,\n (ids) => {\n kept = ids;\n mask = ids && geometry ? maskOf(geometry.size, ids) : null;\n notify();\n },\n (error) => fail(error),\n );\n coordinator.connect(client);\n connected = coordinator;\n }\n\n function disconnect(): void {\n if (client && connected) connected.disconnect(client);\n client = null;\n connected = null;\n }\n\n const store: GraphStore = {\n /**\n * The first subscriber connects the client to the coordinator, and the last one disconnects it\n * and lets the graph go — `QueryObserver`'s `onSubscribe`/`onUnsubscribe`, which is what\n * survives StrictMode mounting everything twice.\n */\n subscribe(listener) {\n listeners.add(listener);\n if (!active) {\n active = true;\n connect();\n if (held !== null) {\n const { error } = held;\n held = null;\n options.onFailure(error);\n }\n }\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0) store.destroy();\n };\n },\n getSnapshot: () => snapshot,\n getOptions: () => options,\n setOptions(next) {\n const previous = options;\n options = next;\n const before = binding;\n binding = bindingOf(next);\n if (next.from !== previous.from || next.coordinator !== previous.coordinator) {\n if (active && next.coordinator !== previous.coordinator) connect();\n return reset();\n }\n if (active && next.filterBy !== previous.filterBy) connect();\n if (binding.x !== before.x || binding.y !== before.y) loadPositions();\n else if (\n binding.category !== before.category ||\n binding.byTable !== before.byTable ||\n binding.size !== before.size ||\n binding.cluster !== before.cluster ||\n next.categories !== previous.categories\n ) {\n loadChannels();\n }\n notify();\n },\n destroy() {\n active = false;\n disconnect();\n listeners.clear();\n },\n select(vertices, source = \"external\", label = \"\") {\n const selection = vertices && vertices.length > 0 ? { vertices: [...vertices], source, label } : null;\n patch({ selection });\n options.onSelect?.(selection);\n if (options.filterBy && client) publish(options.filterBy, client, selection ? selection.vertices : null);\n },\n focus(vertex) {\n if (vertex === snapshot.focus) return;\n patch({ focus: vertex });\n options.onFocus?.(vertex);\n },\n hover(vertex) {\n if (vertex !== snapshot.hovered) patch({ hovered: vertex });\n },\n pin(vertices) {\n patch({ pinned: [...vertices] });\n },\n setTool(tool) {\n if (tool !== snapshot.tool) patch({ tool });\n },\n report(motion) {\n if (motion !== snapshot.motion) patch({ motion });\n },\n reportProgress(value) {\n if (value !== snapshot.progress) patch({ progress: value });\n },\n renderable() {\n if (!unrenderable) return;\n unrenderable = false;\n notify();\n },\n unrenderable(error) {\n unrenderable = true;\n fail(error);\n notify();\n },\n reportDrawn(drawnSnapshot) {\n const next = [drawnSnapshot.geometry, drawnSnapshot.encoding, drawnSnapshot.mask];\n if (next.every((part, i) => part === uploaded[i])) return;\n uploaded = next;\n notify();\n },\n };\n\n loadStructure();\n notify();\n building = false;\n return store;\n}\n"],"names":["drawnOf","geometry","encoding","mask","tally","shown","vertices","id","rank","edges","links","i","matchingOf","n","kept","maskOf","size","ids","createGraph","initial","options","listeners","failed","unrenderable","binding","bindingOf","structure","uploaded","reading","pending","client","connected","active","building","held","fail","error","snapshot","domain","domainNow","tables","key","part","domainOf","drawn","drawnNow","statusOf","notify","fields","emit","patch","listener","read","kind","ask","done","ticket","value","loadStructure","coordinator","from","readStructure","next","GraphError","loadPositions","given","loadGeometry","loadChannels","seed","loadEncoding","reset","connect","disconnect","filterBy","GraphClient","store","previous","before","source","label","selection","_a","publish","vertex","tool","motion","drawnSnapshot"],"mappings":"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"}
|