@kanzo-tech/graph 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/categories.d.ts +1 -1
- package/dist/core/categories.d.ts.map +1 -1
- package/dist/core/categories.js.map +1 -1
- package/dist/core/channels.d.ts +12 -6
- package/dist/core/channels.d.ts.map +1 -1
- package/dist/core/channels.js +15 -12
- package/dist/core/channels.js.map +1 -1
- package/dist/core/client.d.ts +26 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/client.js +62 -0
- package/dist/core/client.js.map +1 -0
- 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/load.d.ts +30 -39
- package/dist/core/load.d.ts.map +1 -1
- package/dist/core/load.js +63 -117
- package/dist/core/load.js.map +1 -1
- package/dist/core/source.d.ts +90 -0
- package/dist/core/source.d.ts.map +1 -0
- package/dist/core/source.js +105 -0
- package/dist/core/source.js.map +1 -0
- package/dist/core/state.d.ts +19 -20
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +137 -157
- package/dist/core/store.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/parts/graph-canvas.d.ts.map +1 -1
- package/dist/parts/graph-canvas.js +49 -48
- package/dist/parts/graph-canvas.js.map +1 -1
- package/dist/parts/graph-counts.js +4 -4
- package/dist/parts/graph-counts.js.map +1 -1
- package/dist/parts/graph-inspector.d.ts +3 -3
- package/dist/parts/graph-inspector.d.ts.map +1 -1
- package/dist/parts/graph-inspector.js +45 -43
- package/dist/parts/graph-inspector.js.map +1 -1
- package/dist/parts/graph-search.d.ts +7 -7
- package/dist/parts/graph-search.d.ts.map +1 -1
- package/dist/parts/graph-search.js +60 -69
- package/dist/parts/graph-search.js.map +1 -1
- package/dist/parts/graph-toolbar.js +1 -1
- package/dist/parts/graph-toolbar.js.map +1 -1
- package/dist/react/use-graph.js +31 -31
- package/dist/react/use-graph.js.map +1 -1
- package/dist/render/graph-sim.d.ts +1 -1
- package/dist/render/graph-sim.d.ts.map +1 -1
- package/dist/render/graph-sim.js.map +1 -1
- package/dist/render/motion.d.ts +33 -0
- package/dist/render/motion.d.ts.map +1 -0
- package/dist/render/motion.js +19 -0
- package/dist/render/motion.js.map +1 -0
- package/dist/render/placement.d.ts +2 -4
- package/dist/render/placement.d.ts.map +1 -1
- package/dist/render/placement.js +12 -16
- package/dist/render/placement.js.map +1 -1
- package/dist/render/renderer.d.ts +6 -5
- package/dist/render/renderer.d.ts.map +1 -1
- package/dist/render/renderer.js +124 -113
- package/dist/render/renderer.js.map +1 -1
- package/dist/section.js +1 -1
- package/dist/section.js.map +1 -1
- package/package.json +8 -10
- package/dist/core/detail.d.ts +0 -26
- package/dist/core/detail.d.ts.map +0 -1
- package/dist/core/detail.js +0 -63
- package/dist/core/detail.js.map +0 -1
- package/dist/core/filter.d.ts +0 -23
- package/dist/core/filter.d.ts.map +0 -1
- package/dist/core/filter.js +0 -95
- package/dist/core/filter.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"detail.d.ts","sourceRoot":"","sources":["../../src/core/detail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,wGAAwG;AACxG,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,sCAAsC;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CAChF;AAKD;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,QAAQ,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAa9B;AAMD;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,SAAS,QAAQ,EAAE,EAC7B,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAqBhC;AAED,2GAA2G;AAC3G,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CAmBnB"}
|
package/dist/core/detail.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { together as h } from "./load.js";
|
|
2
|
-
const k = (o, e) => e < o.size ? o.tables[o.table[e]] : void 0;
|
|
3
|
-
async function C(o, e, r, y) {
|
|
4
|
-
var f, c;
|
|
5
|
-
const s = k(e, r);
|
|
6
|
-
if (!s) return null;
|
|
7
|
-
const u = /* @__PURE__ */ new Set([s.key, (f = s.position) == null ? void 0 : f.x, (c = s.position) == null ? void 0 : c.y]), a = s.properties.map((t) => t.name).filter((t) => !u.has(t)), i = o.scan({ table: s.name, filter: { column: s.key, op: "=", value: r }, select: [s.key, ...a], limit: 1 }), n = (await i.read(i.plan(), { signal: y })).find((t) => t.numRows > 0);
|
|
8
|
-
return n ? {
|
|
9
|
-
vertex: r,
|
|
10
|
-
table: s.name,
|
|
11
|
-
fields: a.map((t) => {
|
|
12
|
-
var m;
|
|
13
|
-
return { name: t, value: ((m = n.getChild(t)) == null ? void 0 : m.toArray()[0]) ?? null };
|
|
14
|
-
})
|
|
15
|
-
} : null;
|
|
16
|
-
}
|
|
17
|
-
const b = (o, e) => e !== void 0 && o.properties.some((r) => r.name === e) ? e : o.identity;
|
|
18
|
-
async function v(o, e, r, y, s) {
|
|
19
|
-
const u = /* @__PURE__ */ new Map();
|
|
20
|
-
for (const i of r) {
|
|
21
|
-
const n = k(e, i);
|
|
22
|
-
n && u.set(n, [...u.get(n) ?? [], i]);
|
|
23
|
-
}
|
|
24
|
-
const a = /* @__PURE__ */ new Map();
|
|
25
|
-
return await h(
|
|
26
|
-
s,
|
|
27
|
-
(i) => Promise.all(
|
|
28
|
-
[...u].map(async ([n, f]) => {
|
|
29
|
-
var m, d;
|
|
30
|
-
const c = b(n, y), t = o.scan({ table: n.name, filter: { column: n.key, op: "in", values: f }, select: [n.key, c] });
|
|
31
|
-
for (const l of await t.read(t.plan(), { signal: i })) {
|
|
32
|
-
const p = ((m = l.getChild(n.key)) == null ? void 0 : m.toArray()) ?? [], g = ((d = l.getChild(c)) == null ? void 0 : d.toArray()) ?? [];
|
|
33
|
-
for (let w = 0; w < l.numRows; w++) a.set(Number(p[w]), String(g[w] ?? ""));
|
|
34
|
-
}
|
|
35
|
-
})
|
|
36
|
-
)
|
|
37
|
-
), a;
|
|
38
|
-
}
|
|
39
|
-
async function x(o, e, r, y) {
|
|
40
|
-
const s = new Array(e.size).fill("");
|
|
41
|
-
return await h(
|
|
42
|
-
y,
|
|
43
|
-
(u) => Promise.all(
|
|
44
|
-
e.tables.map(async (a) => {
|
|
45
|
-
var f, c;
|
|
46
|
-
const i = b(a, r), n = o.scan({ table: a.name, select: [a.key, i] });
|
|
47
|
-
for (const t of await n.read(n.plan(), { signal: u })) {
|
|
48
|
-
const m = ((f = t.getChild(a.key)) == null ? void 0 : f.toArray()) ?? [], d = ((c = t.getChild(i)) == null ? void 0 : c.toArray()) ?? [];
|
|
49
|
-
for (let l = 0; l < t.numRows; l++) {
|
|
50
|
-
const p = Number(m[l]);
|
|
51
|
-
p < e.size && (s[p] = String(d[l] ?? ""));
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
})
|
|
55
|
-
)
|
|
56
|
-
), s;
|
|
57
|
-
}
|
|
58
|
-
export {
|
|
59
|
-
x as readEveryTitle,
|
|
60
|
-
v as readTitles,
|
|
61
|
-
C as readVertex
|
|
62
|
-
};
|
|
63
|
-
//# sourceMappingURL=detail.js.map
|
package/dist/core/detail.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"detail.js","sources":["../../src/core/detail.ts"],"sourcesContent":["import type { Corpus, VertexTable } from \"@fossil-lang/corpus\";\nimport { together, type Geometry } from \"./load\";\nimport type { VertexId } from \"./types\";\n\n/** One vertex's row, as its table's properties order it — every column but the key and the position. */\nexport interface VertexDetail {\n readonly vertex: VertexId;\n /** The vertex table it belongs to. */\n readonly table: string;\n readonly fields: readonly { readonly name: string; readonly value: unknown }[];\n}\n\nconst tableOf = (geometry: Geometry, vertex: VertexId): VertexTable | undefined =>\n vertex < geometry.size ? geometry.tables[geometry.table[vertex] as number] : undefined;\n\n/**\n * **Detail is fetched, not carried.** The loaded graph holds positions and channels; the rest of a\n * row is asked for when a reader focuses the vertex — a scan of its table, filtered to its key.\n */\nexport async function readVertex(\n corpus: Corpus,\n geometry: Geometry,\n vertex: VertexId,\n signal?: AbortSignal,\n): Promise<VertexDetail | null> {\n const table = tableOf(geometry, vertex);\n if (!table) return null;\n const hidden = new Set([table.key, table.position?.x, table.position?.y]);\n const names = table.properties.map((p) => p.name).filter((name) => !hidden.has(name));\n const scan = corpus.scan({ table: table.name, filter: { column: table.key, op: \"=\", value: vertex }, select: [table.key, ...names], limit: 1 });\n const rows = (await scan.read(scan.plan(), { signal })).find((batch) => batch.numRows > 0);\n if (!rows) return null;\n return {\n vertex,\n table: table.name,\n fields: names.map((name) => ({ name, value: rows.getChild(name)?.toArray()[0] ?? null })),\n };\n}\n\n/** The column a vertex's text is read from: `title` where its table has it, else the table's `identity`. */\nconst titleColumn = (table: VertexTable, title: string | undefined): string =>\n title !== undefined && table.properties.some((p) => p.name === title) ? title : table.identity;\n\n/**\n * **A label's text, for the few vertices that carry one** — `title` where the vertex's table has the\n * column, and the table's declared `identity` where it does not. One scan per table they fall in.\n */\nexport async function readTitles(\n corpus: Corpus,\n geometry: Geometry,\n vertices: readonly VertexId[],\n title: string | undefined,\n signal: AbortSignal,\n): Promise<Map<VertexId, string>> {\n const byTable = new Map<VertexTable, VertexId[]>();\n for (const vertex of vertices) {\n const table = tableOf(geometry, vertex);\n if (table) byTable.set(table, [...(byTable.get(table) ?? []), vertex]);\n }\n const found = new Map<VertexId, string>();\n await together(signal, (signal) =>\n Promise.all(\n [...byTable].map(async ([table, ids]) => {\n const column = titleColumn(table, title);\n const scan = corpus.scan({ table: table.name, filter: { column: table.key, op: \"in\", values: ids }, select: [table.key, column] });\n for (const batch of await scan.read(scan.plan(), { signal })) {\n const keys = batch.getChild(table.key)?.toArray() ?? [];\n const texts = batch.getChild(column)?.toArray() ?? [];\n for (let i = 0; i < batch.numRows; i++) found.set(Number(keys[i]), String(texts[i] ?? \"\"));\n }\n }),\n ),\n );\n return found;\n}\n\n/** **Every drawn vertex's text, by id** — what a search filters. One scan per drawn table, two columns. */\nexport async function readEveryTitle(\n corpus: Corpus,\n geometry: Geometry,\n title: string | undefined,\n signal: AbortSignal,\n): Promise<string[]> {\n const titles = new Array<string>(geometry.size).fill(\"\");\n await together(signal, (signal) =>\n Promise.all(\n geometry.tables.map(async (table) => {\n const column = titleColumn(table, title);\n const scan = corpus.scan({ table: table.name, select: [table.key, column] });\n for (const batch of await scan.read(scan.plan(), { signal })) {\n const keys = batch.getChild(table.key)?.toArray() ?? [];\n const texts = batch.getChild(column)?.toArray() ?? [];\n for (let i = 0; i < batch.numRows; i++) {\n const id = Number(keys[i]);\n if (id < geometry.size) titles[id] = String(texts[i] ?? \"\");\n }\n }\n }),\n ),\n );\n return titles;\n}\n"],"names":["tableOf","geometry","vertex","readVertex","corpus","signal","table","hidden","_a","_b","names","p","name","scan","rows","batch","titleColumn","title","readTitles","vertices","byTable","found","together","ids","column","keys","texts","i","readEveryTitle","titles","id"],"mappings":";AAYA,MAAMA,IAAU,CAACC,GAAoBC,MACnCA,IAASD,EAAS,OAAOA,EAAS,OAAOA,EAAS,MAAMC,CAAM,CAAW,IAAI;AAM/E,eAAsBC,EACpBC,GACAH,GACAC,GACAG,GAC8B;;AAC9B,QAAMC,IAAQN,EAAQC,GAAUC,CAAM;AACtC,MAAI,CAACI,EAAO,QAAO;AACnB,QAAMC,IAAS,oBAAI,IAAI,CAACD,EAAM,MAAKE,IAAAF,EAAM,aAAN,gBAAAE,EAAgB,IAAGC,IAAAH,EAAM,aAAN,gBAAAG,EAAgB,CAAC,CAAC,GAClEC,IAAQJ,EAAM,WAAW,IAAI,CAACK,MAAMA,EAAE,IAAI,EAAE,OAAO,CAACC,MAAS,CAACL,EAAO,IAAIK,CAAI,CAAC,GAC9EC,IAAOT,EAAO,KAAK,EAAE,OAAOE,EAAM,MAAM,QAAQ,EAAE,QAAQA,EAAM,KAAK,IAAI,KAAK,OAAOJ,EAAA,GAAU,QAAQ,CAACI,EAAM,KAAK,GAAGI,CAAK,GAAG,OAAO,EAAA,CAAG,GACxII,KAAQ,MAAMD,EAAK,KAAKA,EAAK,QAAQ,EAAE,QAAAR,EAAA,CAAQ,GAAG,KAAK,CAACU,MAAUA,EAAM,UAAU,CAAC;AACzF,SAAKD,IACE;AAAA,IACL,QAAAZ;AAAA,IACA,OAAOI,EAAM;AAAA,IACb,QAAQI,EAAM,IAAI,CAACE,MAAA;;AAAU,eAAE,MAAAA,GAAM,SAAOJ,IAAAM,EAAK,SAASF,CAAI,MAAlB,gBAAAJ,EAAqB,UAAU,OAAM;KAAO;AAAA,EAAA,IAJxE;AAMpB;AAGA,MAAMQ,IAAc,CAACV,GAAoBW,MACvCA,MAAU,UAAaX,EAAM,WAAW,KAAK,CAACK,MAAMA,EAAE,SAASM,CAAK,IAAIA,IAAQX,EAAM;AAMxF,eAAsBY,EACpBd,GACAH,GACAkB,GACAF,GACAZ,GACgC;AAChC,QAAMe,wBAAc,IAAA;AACpB,aAAWlB,KAAUiB,GAAU;AAC7B,UAAMb,IAAQN,EAAQC,GAAUC,CAAM;AACtC,IAAII,KAAOc,EAAQ,IAAId,GAAO,CAAC,GAAIc,EAAQ,IAAId,CAAK,KAAK,CAAA,GAAKJ,CAAM,CAAC;AAAA,EACvE;AACA,QAAMmB,wBAAY,IAAA;AAClB,eAAMC;AAAA,IAASjB;AAAA,IAAQ,CAACA,MACtB,QAAQ;AAAA,MACN,CAAC,GAAGe,CAAO,EAAE,IAAI,OAAO,CAACd,GAAOiB,CAAG,MAAM;;AACvC,cAAMC,IAASR,EAAYV,GAAOW,CAAK,GACjCJ,IAAOT,EAAO,KAAK,EAAE,OAAOE,EAAM,MAAM,QAAQ,EAAE,QAAQA,EAAM,KAAK,IAAI,MAAM,QAAQiB,EAAA,GAAO,QAAQ,CAACjB,EAAM,KAAKkB,CAAM,GAAG;AACjI,mBAAWT,KAAS,MAAMF,EAAK,KAAKA,EAAK,KAAA,GAAQ,EAAE,QAAAR,EAAAA,CAAQ,GAAG;AAC5D,gBAAMoB,MAAOjB,IAAAO,EAAM,SAAST,EAAM,GAAG,MAAxB,gBAAAE,EAA2B,cAAa,CAAA,GAC/CkB,MAAQjB,IAAAM,EAAM,SAASS,CAAM,MAArB,gBAAAf,EAAwB,cAAa,CAAA;AACnD,mBAASkB,IAAI,GAAGA,IAAIZ,EAAM,SAASY,OAAW,IAAI,OAAOF,EAAKE,CAAC,CAAC,GAAG,OAAOD,EAAMC,CAAC,KAAK,EAAE,CAAC;AAAA,QAC3F;AAAA,MACF,CAAC;AAAA,IAAA;AAAA,EACH,GAEKN;AACT;AAGA,eAAsBO,EACpBxB,GACAH,GACAgB,GACAZ,GACmB;AACnB,QAAMwB,IAAS,IAAI,MAAc5B,EAAS,IAAI,EAAE,KAAK,EAAE;AACvD,eAAMqB;AAAA,IAASjB;AAAA,IAAQ,CAACA,MACtB,QAAQ;AAAA,MACNJ,EAAS,OAAO,IAAI,OAAOK,MAAU;;AACnC,cAAMkB,IAASR,EAAYV,GAAOW,CAAK,GACjCJ,IAAOT,EAAO,KAAK,EAAE,OAAOE,EAAM,MAAM,QAAQ,CAACA,EAAM,KAAKkB,CAAM,GAAG;AAC3E,mBAAWT,KAAS,MAAMF,EAAK,KAAKA,EAAK,KAAA,GAAQ,EAAE,QAAAR,EAAAA,CAAQ,GAAG;AAC5D,gBAAMoB,MAAOjB,IAAAO,EAAM,SAAST,EAAM,GAAG,MAAxB,gBAAAE,EAA2B,cAAa,CAAA,GAC/CkB,MAAQjB,IAAAM,EAAM,SAASS,CAAM,MAArB,gBAAAf,EAAwB,cAAa,CAAA;AACnD,mBAASkB,IAAI,GAAGA,IAAIZ,EAAM,SAASY,KAAK;AACtC,kBAAMG,IAAK,OAAOL,EAAKE,CAAC,CAAC;AACzB,YAAIG,IAAK7B,EAAS,SAAM4B,EAAOC,CAAE,IAAI,OAAOJ,EAAMC,CAAC,KAAK,EAAE;AAAA,UAC5D;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IAAA;AAAA,EACH,GAEKE;AACT;"}
|
package/dist/core/filter.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Filter } from '@fossil-lang/corpus';
|
|
2
|
-
import { MosaicClient, Selection } from '@kanzo-tech/mosaic';
|
|
3
|
-
/** One mosaic-sql expression node → one `Filter`. */
|
|
4
|
-
export declare function translate(node: unknown): Filter;
|
|
5
|
-
/** Every column a filter names, once each. */
|
|
6
|
-
export declare function columnsOf(filter: Filter): string[];
|
|
7
|
-
/**
|
|
8
|
-
* The page's filter for the graph, or `undefined` for none. `selection.predicate` skips the clause
|
|
9
|
-
* the graph published itself, which is the exemption the next function takes back.
|
|
10
|
-
*/
|
|
11
|
-
export declare function filterFor(selection: Selection, self: MosaicClient): Filter | undefined;
|
|
12
|
-
/**
|
|
13
|
-
* An identity for `clients`, and nothing more: it is never connected, so the coordinator never
|
|
14
|
-
* queries on its behalf.
|
|
15
|
-
*/
|
|
16
|
-
export declare function graphClient(): MosaicClient;
|
|
17
|
-
/**
|
|
18
|
-
* **The reader's pick, published** — naming the graph in `clients`, so the crossfilter skips it for
|
|
19
|
-
* the graph and applies it to every chart. A canvas that draws only what survives would otherwise
|
|
20
|
-
* answer a lasso of thirteen by removing the other 1,530.
|
|
21
|
-
*/
|
|
22
|
-
export declare function publish(selection: Selection, self: MosaicClient, column: string, ids: readonly number[] | null): void;
|
|
23
|
-
//# sourceMappingURL=filter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/core/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAgB,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAiEhF,qDAAqD;AACrD,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAyC/C;AAID,8CAA8C;AAC9C,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAMlD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAItF;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,YAAY,CAE1C;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GAC5B,IAAI,CAON"}
|
package/dist/core/filter.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { MosaicClient as f, clausePoints as m } from "@kanzo-tech/mosaic";
|
|
2
|
-
import { GraphError as h } from "./error.js";
|
|
3
|
-
const O = {
|
|
4
|
-
"=": "=",
|
|
5
|
-
"==": "=",
|
|
6
|
-
"IS NOT DISTINCT FROM": "=",
|
|
7
|
-
"<>": "!=",
|
|
8
|
-
"!=": "!=",
|
|
9
|
-
"<": "<",
|
|
10
|
-
"<=": "<=",
|
|
11
|
-
">": ">",
|
|
12
|
-
">=": ">="
|
|
13
|
-
}, y = { "=": "=", "!=": "!=", "<": ">", "<=": ">=", ">": "<", ">=": "<=" }, o = (r) => {
|
|
14
|
-
throw new h(
|
|
15
|
-
"graph/untranslatable-filter",
|
|
16
|
-
`the graph cannot express this crossfilter clause as a filter on the corpus: ${String(r)}`
|
|
17
|
-
);
|
|
18
|
-
};
|
|
19
|
-
function a(r) {
|
|
20
|
-
const t = r;
|
|
21
|
-
return (t == null ? void 0 : t.type) === "COLUMN_REF" && typeof t.name == "string" ? t.name : null;
|
|
22
|
-
}
|
|
23
|
-
function s(r) {
|
|
24
|
-
const t = r, n = (t == null ? void 0 : t.type) === "LITERAL" || (t == null ? void 0 : t.type) === "PARAM" ? t.value : o(r);
|
|
25
|
-
if (typeof n == "number" || typeof n == "bigint" || typeof n == "string" || typeof n == "boolean")
|
|
26
|
-
return n;
|
|
27
|
-
if (n instanceof Date) {
|
|
28
|
-
const e = n.toISOString();
|
|
29
|
-
return e.endsWith("T00:00:00.000Z") ? e.slice(0, 10) : e.replace("T", " ").replace("Z", "");
|
|
30
|
-
}
|
|
31
|
-
return o(r);
|
|
32
|
-
}
|
|
33
|
-
function A(r) {
|
|
34
|
-
const t = r;
|
|
35
|
-
return (Array.isArray(r) ? r : Array.isArray(t == null ? void 0 : t.values) ? t.values : o(r)).map(s);
|
|
36
|
-
}
|
|
37
|
-
function c(r) {
|
|
38
|
-
const t = r;
|
|
39
|
-
if (Array.isArray(r)) return i(r.map(c));
|
|
40
|
-
switch (t == null ? void 0 : t.type) {
|
|
41
|
-
case "LOGICAL_OPERATOR": {
|
|
42
|
-
const n = (t.clauses ?? []).map(c);
|
|
43
|
-
return t.op === "OR" ? { or: n } : i(n);
|
|
44
|
-
}
|
|
45
|
-
case "UNARY":
|
|
46
|
-
return t.op === "NOT" ? { not: c(t.expr) } : o(r);
|
|
47
|
-
case "UNARY_POSTFIX": {
|
|
48
|
-
const n = a(t.expr) ?? o(r);
|
|
49
|
-
return t.op === "IS NULL" ? { column: n, op: "is null" } : t.op === "IS NOT NULL" ? { column: n, op: "not null" } : o(r);
|
|
50
|
-
}
|
|
51
|
-
case "BINARY": {
|
|
52
|
-
const n = O[String(t.op).toUpperCase()] ?? o(r), e = a(t.left);
|
|
53
|
-
return e !== null ? { column: e, op: n, value: s(t.right) } : { column: a(t.right) ?? o(r), op: y[n], value: s(t.left) };
|
|
54
|
-
}
|
|
55
|
-
case "BETWEEN":
|
|
56
|
-
case "NOT_BETWEEN": {
|
|
57
|
-
const n = a(t.expr) ?? o(r), [e, u] = t.extent ?? o(r), p = i([
|
|
58
|
-
{ column: n, op: ">=", value: s(e) },
|
|
59
|
-
{ column: n, op: "<=", value: s(u) }
|
|
60
|
-
]);
|
|
61
|
-
return t.type === "BETWEEN" ? p : { not: p };
|
|
62
|
-
}
|
|
63
|
-
case "IN":
|
|
64
|
-
return { column: a(t.expr) ?? o(r), op: "in", values: A(t.values) };
|
|
65
|
-
default:
|
|
66
|
-
return o(r);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
const i = (r) => r.length === 1 ? r[0] : { and: r };
|
|
70
|
-
function l(r) {
|
|
71
|
-
return "column" in r ? [r.column] : "and" in r ? [...new Set(r.and.flatMap(l))] : "or" in r ? [...new Set(r.or.flatMap(l))] : "not" in r ? l(r.not) : [];
|
|
72
|
-
}
|
|
73
|
-
function v(r, t) {
|
|
74
|
-
const n = r.predicate(t), e = (Array.isArray(n) ? n : [n]).filter((u) => u != null);
|
|
75
|
-
return e.length === 0 ? void 0 : c(e);
|
|
76
|
-
}
|
|
77
|
-
function E() {
|
|
78
|
-
return new f();
|
|
79
|
-
}
|
|
80
|
-
function R(r, t, n, e) {
|
|
81
|
-
r.update(
|
|
82
|
-
m([n], e && e.length > 0 ? e.map((u) => [u]) : void 0, {
|
|
83
|
-
source: t,
|
|
84
|
-
clients: /* @__PURE__ */ new Set([t])
|
|
85
|
-
})
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
export {
|
|
89
|
-
l as columnsOf,
|
|
90
|
-
v as filterFor,
|
|
91
|
-
E as graphClient,
|
|
92
|
-
R as publish,
|
|
93
|
-
c as translate
|
|
94
|
-
};
|
|
95
|
-
//# sourceMappingURL=filter.js.map
|
package/dist/core/filter.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","sources":["../../src/core/filter.ts"],"sourcesContent":["import type { Filter, Literal } from \"@fossil-lang/corpus\";\nimport { MosaicClient, clausePoints, type Selection } from \"@kanzo-tech/mosaic\";\nimport { GraphError } from \"./error\";\n\n/**\n * **The page's crossfilter, as scan's typed filter.** The graph listens to the `Selection` rather\n * than being a client of the coordinator: a client hands the coordinator SQL to run, and the graph\n * has none — it hands fossil a `Filter` and fossil binds it. So this takes the half of Mosaic's\n * protocol that is about filtering: the `value` event, and `selection.predicate(client)`.\n *\n * The nodes are read by their `type`, never by importing mosaic-sql's classes: what arrives is\n * whatever the page's copy of mosaic-sql built.\n */\n\ninterface Node {\n readonly type?: string;\n readonly op?: string;\n readonly [field: string]: unknown;\n}\n\nconst COMPARISONS: Record<string, \"=\" | \"!=\" | \"<\" | \"<=\" | \">\" | \">=\"> = {\n \"=\": \"=\",\n \"==\": \"=\",\n \"IS NOT DISTINCT FROM\": \"=\",\n \"<>\": \"!=\",\n \"!=\": \"!=\",\n \"<\": \"<\",\n \"<=\": \"<=\",\n \">\": \">\",\n \">=\": \">=\",\n};\nconst MIRRORED = { \"=\": \"=\", \"!=\": \"!=\", \"<\": \">\", \"<=\": \">=\", \">\": \"<\", \">=\": \"<=\" } as const;\n\n/** A predicate this cannot express as a `Filter` — reported, never dropped. */\nconst fail = (what: unknown): never => {\n throw new GraphError(\n \"graph/untranslatable-filter\",\n `the graph cannot express this crossfilter clause as a filter on the corpus: ${String(what)}`,\n );\n};\n\nfunction columnOf(node: unknown): string | null {\n const n = node as Node | null;\n if (n?.type === \"COLUMN_REF\" && typeof n.name === \"string\") return n.name;\n return null;\n}\n\nfunction literalOf(node: unknown): Literal {\n const n = node as Node | null;\n const value = n?.type === \"LITERAL\" || n?.type === \"PARAM\" ? n.value : fail(node);\n if (typeof value === \"number\" || typeof value === \"bigint\" || typeof value === \"string\" || typeof value === \"boolean\") {\n return value;\n }\n if (value instanceof Date) {\n const iso = value.toISOString();\n return iso.endsWith(\"T00:00:00.000Z\") ? iso.slice(0, 10) : iso.replace(\"T\", \" \").replace(\"Z\", \"\");\n }\n return fail(node);\n}\n\nfunction valuesOf(node: unknown): Literal[] {\n const n = node as Node | null;\n const list = Array.isArray(node) ? node : Array.isArray(n?.values) ? n.values : fail(node);\n return (list as unknown[]).map(literalOf);\n}\n\n/** One mosaic-sql expression node → one `Filter`. */\nexport function translate(node: unknown): Filter {\n const n = node as Node | null;\n if (Array.isArray(node)) return and(node.map(translate));\n switch (n?.type) {\n case \"LOGICAL_OPERATOR\": {\n const clauses = ((n.clauses as unknown[] | undefined) ?? []).map(translate);\n return n.op === \"OR\" ? { or: clauses } : and(clauses);\n }\n case \"UNARY\":\n if (n.op === \"NOT\") return { not: translate(n.expr) };\n return fail(node);\n case \"UNARY_POSTFIX\": {\n const column = columnOf(n.expr) ?? fail(node);\n if (n.op === \"IS NULL\") return { column, op: \"is null\" };\n if (n.op === \"IS NOT NULL\") return { column, op: \"not null\" };\n return fail(node);\n }\n case \"BINARY\": {\n const op = COMPARISONS[String(n.op).toUpperCase()] ?? fail(node);\n const left = columnOf(n.left);\n if (left !== null) return { column: left, op, value: literalOf(n.right) };\n const right = columnOf(n.right) ?? fail(node);\n return { column: right, op: MIRRORED[op], value: literalOf(n.left) };\n }\n case \"BETWEEN\":\n case \"NOT_BETWEEN\": {\n const column = columnOf(n.expr) ?? fail(node);\n const [lo, hi] = (n.extent as unknown[] | undefined) ?? fail(node);\n const within: Filter = and([\n { column, op: \">=\", value: literalOf(lo) },\n { column, op: \"<=\", value: literalOf(hi) },\n ]);\n return n.type === \"BETWEEN\" ? within : { not: within };\n }\n case \"IN\": {\n const column = columnOf(n.expr) ?? fail(node);\n return { column, op: \"in\", values: valuesOf(n.values) };\n }\n default:\n return fail(node);\n }\n}\n\nconst and = (clauses: Filter[]): Filter => (clauses.length === 1 ? (clauses[0] as Filter) : { and: clauses });\n\n/** Every column a filter names, once each. */\nexport function columnsOf(filter: Filter): string[] {\n if (\"column\" in filter) return [filter.column];\n if (\"and\" in filter) return [...new Set(filter.and.flatMap(columnsOf))];\n if (\"or\" in filter) return [...new Set(filter.or.flatMap(columnsOf))];\n if (\"not\" in filter) return columnsOf(filter.not);\n return [];\n}\n\n/**\n * The page's filter for the graph, or `undefined` for none. `selection.predicate` skips the clause\n * the graph published itself, which is the exemption the next function takes back.\n */\nexport function filterFor(selection: Selection, self: MosaicClient): Filter | undefined {\n const predicate = selection.predicate(self) as unknown;\n const clauses = (Array.isArray(predicate) ? predicate : [predicate]).filter((p) => p !== undefined && p !== null);\n return clauses.length === 0 ? undefined : translate(clauses);\n}\n\n/**\n * An identity for `clients`, and nothing more: it is never connected, so the coordinator never\n * queries on its behalf.\n */\nexport function graphClient(): MosaicClient {\n return new MosaicClient();\n}\n\n/**\n * **The reader's pick, published** — naming the graph in `clients`, so the crossfilter skips it for\n * the graph and applies it to every chart. A canvas that draws only what survives would otherwise\n * answer a lasso of thirteen by removing the other 1,530.\n */\nexport function publish(\n selection: Selection,\n self: MosaicClient,\n column: string,\n ids: readonly number[] | null,\n): void {\n selection.update(\n clausePoints([column], ids && ids.length > 0 ? ids.map((d) => [d]) : undefined, {\n source: self,\n clients: new Set([self]),\n }),\n );\n}\n"],"names":["COMPARISONS","MIRRORED","fail","what","GraphError","columnOf","node","n","literalOf","value","iso","valuesOf","translate","and","clauses","column","op","left","lo","hi","within","columnsOf","filter","filterFor","selection","self","predicate","p","graphClient","MosaicClient","publish","ids","clausePoints","d"],"mappings":"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"}
|