@kanzo-tech/graph 0.13.1 → 0.15.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.
Files changed (121) hide show
  1. package/README.md +12 -15
  2. package/dist/core/categories.d.ts +18 -6
  3. package/dist/core/categories.d.ts.map +1 -1
  4. package/dist/core/categories.js +41 -10
  5. package/dist/core/categories.js.map +1 -1
  6. package/dist/core/channels.d.ts +10 -5
  7. package/dist/core/channels.d.ts.map +1 -1
  8. package/dist/core/channels.js +11 -13
  9. package/dist/core/channels.js.map +1 -1
  10. package/dist/core/detail.d.ts +14 -8
  11. package/dist/core/detail.d.ts.map +1 -1
  12. package/dist/core/detail.js +33 -15
  13. package/dist/core/detail.js.map +1 -1
  14. package/dist/core/filter.d.ts +3 -1
  15. package/dist/core/filter.d.ts.map +1 -1
  16. package/dist/core/filter.js +54 -50
  17. package/dist/core/filter.js.map +1 -1
  18. package/dist/core/load.d.ts +58 -0
  19. package/dist/core/load.d.ts.map +1 -0
  20. package/dist/core/load.js +115 -0
  21. package/dist/core/load.js.map +1 -0
  22. package/dist/core/state.d.ts +31 -56
  23. package/dist/core/state.d.ts.map +1 -1
  24. package/dist/core/store.d.ts +1 -3
  25. package/dist/core/store.d.ts.map +1 -1
  26. package/dist/core/store.js +162 -172
  27. package/dist/core/store.js.map +1 -1
  28. package/dist/core/types.d.ts +21 -17
  29. package/dist/core/types.d.ts.map +1 -1
  30. package/dist/index.d.ts +5 -7
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +19 -25
  33. package/dist/index.js.map +1 -1
  34. package/dist/parts/gesture.d.ts +1 -10
  35. package/dist/parts/gesture.d.ts.map +1 -1
  36. package/dist/parts/gesture.js +26 -28
  37. package/dist/parts/gesture.js.map +1 -1
  38. package/dist/parts/graph-canvas.d.ts.map +1 -1
  39. package/dist/parts/graph-canvas.js +128 -106
  40. package/dist/parts/graph-canvas.js.map +1 -1
  41. package/dist/parts/graph-inspector.d.ts +4 -4
  42. package/dist/parts/graph-inspector.d.ts.map +1 -1
  43. package/dist/parts/graph-inspector.js +55 -57
  44. package/dist/parts/graph-inspector.js.map +1 -1
  45. package/dist/parts/graph-legend.d.ts +4 -4
  46. package/dist/parts/graph-legend.d.ts.map +1 -1
  47. package/dist/parts/graph-legend.js +21 -21
  48. package/dist/parts/graph-legend.js.map +1 -1
  49. package/dist/parts/graph-toolbar.d.ts +1 -1
  50. package/dist/parts/graph-toolbar.d.ts.map +1 -1
  51. package/dist/parts/graph-toolbar.js +40 -40
  52. package/dist/parts/graph-toolbar.js.map +1 -1
  53. package/dist/parts/overlays.d.ts +6 -5
  54. package/dist/parts/overlays.d.ts.map +1 -1
  55. package/dist/parts/overlays.js +70 -68
  56. package/dist/parts/overlays.js.map +1 -1
  57. package/dist/react/use-graph-state.d.ts +4 -2
  58. package/dist/react/use-graph-state.d.ts.map +1 -1
  59. package/dist/react/use-graph-state.js +10 -6
  60. package/dist/react/use-graph-state.js.map +1 -1
  61. package/dist/react/use-graph.d.ts +1 -4
  62. package/dist/react/use-graph.d.ts.map +1 -1
  63. package/dist/react/use-graph.js +38 -49
  64. package/dist/react/use-graph.js.map +1 -1
  65. package/dist/render/graph-looks.d.ts.map +1 -1
  66. package/dist/render/graph-looks.js.map +1 -1
  67. package/dist/render/graph-model.d.ts +6 -8
  68. package/dist/render/graph-model.d.ts.map +1 -1
  69. package/dist/render/graph-model.js +51 -57
  70. package/dist/render/graph-model.js.map +1 -1
  71. package/dist/render/graph-sim.d.ts +2 -3
  72. package/dist/render/graph-sim.d.ts.map +1 -1
  73. package/dist/render/graph-sim.js.map +1 -1
  74. package/dist/render/renderer.d.ts +10 -10
  75. package/dist/render/renderer.d.ts.map +1 -1
  76. package/dist/render/renderer.js +121 -177
  77. package/dist/render/renderer.js.map +1 -1
  78. package/dist/section.d.ts.map +1 -1
  79. package/dist/section.js +3 -7
  80. package/dist/section.js.map +1 -1
  81. package/package.json +29 -10
  82. package/dist/core/refine.d.ts +0 -14
  83. package/dist/core/refine.d.ts.map +0 -1
  84. package/dist/core/refine.js +0 -20
  85. package/dist/core/refine.js.map +0 -1
  86. package/dist/core/resident.d.ts +0 -79
  87. package/dist/core/resident.d.ts.map +0 -1
  88. package/dist/core/resident.js +0 -44
  89. package/dist/core/resident.js.map +0 -1
  90. package/dist/core/scheduler.d.ts +0 -42
  91. package/dist/core/scheduler.d.ts.map +0 -1
  92. package/dist/core/scheduler.js +0 -77
  93. package/dist/core/scheduler.js.map +0 -1
  94. package/dist/core/tile-matrix.d.ts +0 -37
  95. package/dist/core/tile-matrix.d.ts.map +0 -1
  96. package/dist/core/tile-matrix.js +0 -49
  97. package/dist/core/tile-matrix.js.map +0 -1
  98. package/dist/core/tile.d.ts +0 -54
  99. package/dist/core/tile.d.ts.map +0 -1
  100. package/dist/core/tile.js +0 -76
  101. package/dist/core/tile.js.map +0 -1
  102. package/dist/core/tileset.d.ts +0 -59
  103. package/dist/core/tileset.d.ts.map +0 -1
  104. package/dist/core/tileset.js +0 -177
  105. package/dist/core/tileset.js.map +0 -1
  106. package/dist/render/adaptive.d.ts +0 -27
  107. package/dist/render/adaptive.d.ts.map +0 -1
  108. package/dist/render/adaptive.js +0 -25
  109. package/dist/render/adaptive.js.map +0 -1
  110. package/dist/render/compose.d.ts +0 -51
  111. package/dist/render/compose.d.ts.map +0 -1
  112. package/dist/render/compose.js +0 -107
  113. package/dist/render/compose.js.map +0 -1
  114. package/dist/render/encode.d.ts +0 -42
  115. package/dist/render/encode.d.ts.map +0 -1
  116. package/dist/render/encode.js +0 -68
  117. package/dist/render/encode.js.map +0 -1
  118. package/dist/render/when-ready.d.ts +0 -35
  119. package/dist/render/when-ready.d.ts.map +0 -1
  120. package/dist/render/when-ready.js +0 -17
  121. package/dist/render/when-ready.js.map +0 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The graph view over a [fossil](https://github.com/kanzo-tech/fossil) corpus, drawn with
4
4
  [cosmos.gl](https://cosmosgl.github.io/graph). fossil is the backend and this package is the view:
5
- the host opens the corpus, and `GraphRoot` draws it by tile — no SQL is written here.
5
+ the host opens the corpus, and `GraphRoot` draws the whole of it — no SQL is written here.
6
6
 
7
7
  ## Install
8
8
 
@@ -23,7 +23,7 @@ import { GraphCanvas, GraphInspector, GraphLegend, GraphRoot, GraphToolbar } fro
23
23
 
24
24
  const corpus = engine().then((e) => open(url, { engine: e }));
25
25
 
26
- <GraphRoot corpus={corpus} fill="kind" r="degree" title="label" filterBy={crossfilter} onFailure={setFailure}>
26
+ <GraphRoot corpus={corpus} r="degree" filterBy={crossfilter} onFailure={setFailure}>
27
27
  <GraphCanvas>
28
28
  <GraphToolbar />
29
29
  <GraphLegend />
@@ -36,18 +36,16 @@ const corpus = engine().then((e) => open(url, { engine: e }));
36
36
  corpus opens as `` open(`jobs/${id}`, { engine, host }) `` — and `GraphRoot` takes what came back,
37
37
  or the promise of it, which is what lets it say it is opening. Closing it is the host's too.
38
38
 
39
- **The channels are Plot's**: `fill`, `symbol`, `r`, `stroke` and `title`, where a CSS colour is a
40
- constant and anything else is a column. A column binding is a projection: changing one builds a new
41
- scan and reloads the tiles while keeping the picture.
39
+ **The whole corpus is drawn**: every vertex table with a position — fossil's layout or the
40
+ program's own columns — and every relation whose two ends are drawn, read once, one scan per table,
41
+ and uploaded once. A vertex's `dense_id` is its index in the buffers. The camera reads nothing.
42
42
 
43
- **The camera is addressed.** A tileset in deck.gl's `Tileset2D` shape culls the tile matrix fossil
44
- published, picks the finest zoom whose tiles in view hold at most `limit` rows (20,000 by default),
45
- reads one tile at a time nearest the centre first, cancels what the camera has left, and keeps five
46
- times what it selected. A far view is a coarser rung of fossil's cell pyramid; an edge is drawn when
47
- both of its ends are in tiles already read.
43
+ **The channels are Plot's**: `fill`, `symbol`, `r`, `stroke` and `title`, where a CSS colour is a
44
+ constant and anything else is a column. Unbound, colour is the vertex type and a label is the table's
45
+ `identity`. Changing a column binding re-reads that column and nothing else.
48
46
 
49
- **`filterBy` is the page's crossfilter.** Its clauses are translated into scan's filter, so the
50
- canvas draws what survives; a clause that cannot be translated reaches `onFailure` rather than being
47
+ **`filterBy` is the page's crossfilter.** Its clauses are translated into scan's filter, and what
48
+ does not survive is hidden; a clause that cannot be translated reaches `onFailure` rather than being
51
49
  dropped. A lasso or a click publishes the reader's pick back into it, exempting the graph itself.
52
50
 
53
51
  ## The pieces
@@ -61,9 +59,8 @@ dropped. A lasso or a click publishes the reader's pick back into it, exempting
61
59
  commands drawn, and the focused vertex's row with a render prop for a product's own fields. No
62
60
  part takes a callback: what a click means is `onSelect`, `onFocus` and `onFailure` on the root.
63
61
  - `lookFrom`, `simFrom`, `useGraphPrefs` — the form and the forces from a preferences panel's
64
- answers; `scaleOf` — what colour and shape a category wears; `adaptive` — simulation tuning by size.
65
- - `vertexId`, `typeOf`, `denseOf` — a vertex is `(type_idx, dense_id)` packed into a `bigint`, and
66
- everything that outlives one composition is held as one.
62
+ answers; `scaleOf` — what colour and shape a category wears.
63
+ - `VertexId` — a vertex is its `dense_id`, a `number`.
67
64
 
68
65
  ## Why a package, and not part of `@kanzo-tech/ui`
69
66
 
@@ -1,12 +1,24 @@
1
- import { Corpus } from '@fossil-lang/corpus';
2
1
  import { Binding } from './channels';
2
+ import { VertexTable } from '@fossil-lang/corpus';
3
3
  /**
4
- * **The categorical domain, fixed before a tile arrives.** A column the manifest's `channels:`
5
- * declares as categorical ranks by its own ordinal, `0` to `domain − 1`; otherwise the host's
6
- * `categories` keys are the order. Only a value neither names is ranked as it is seen, after them —
7
- * which is what a legend whose colours moved as tiles arrived was doing for every value.
4
+ * **The categorical domain, fixed before the graph loads.** Colour by vertex type ranks the drawn
5
+ * tables in the manifest's order; a column ranks by the keys of the host's `categories`. Only a value
6
+ * neither names is ranked as it is seen, after them.
8
7
  */
9
- export declare function domainOf(corpus: Corpus | null, typeIndex: number, binding: Binding, categories: Readonly<Record<string, string>> | undefined): readonly unknown[];
8
+ export declare function domainOf(tables: readonly VertexTable[], binding: Binding, categories: Readonly<Record<string, string>> | undefined): readonly unknown[];
10
9
  /** What a legend, a card or an inspector calls a category value. */
11
10
  export declare const nameOf: (value: unknown, categories: Readonly<Record<string, string>> | undefined) => string;
11
+ /**
12
+ * Values to codes, in the order first seen. **The seed ranks first, in its own order**, so a colour
13
+ * is decided before a row arrives; a value outside it is ranked after the seed, numbers before
14
+ * strings. Values meet by their text, so a column's `0` is the host's key `"0"`.
15
+ */
16
+ export declare class Dictionary {
17
+ #private;
18
+ readonly values: unknown[];
19
+ constructor(seed?: readonly unknown[]);
20
+ code(value: unknown): number;
21
+ /** Each code's rank: the seed's own order, then every other value seen. */
22
+ ranks(): Uint32Array;
23
+ }
12
24
  //# sourceMappingURL=categories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/core/categories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,GACvD,SAAS,OAAO,EAAE,CAOpB;AAED,oEAAoE;AACpE,eAAO,MAAM,MAAM,GAAI,OAAO,OAAO,EAAE,YAAY,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,KAAG,MAC7C,CAAC"}
1
+ {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/core/categories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,GACvD,SAAS,OAAO,EAAE,CAIpB;AAED,oEAAoE;AACpE,eAAO,MAAM,MAAM,GAAI,OAAO,OAAO,EAAE,YAAY,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,KAAG,MAC7C,CAAC;AAEtD;;;;GAIG;AACH,qBAAa,UAAU;;IACrB,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAM;gBAIpB,IAAI,GAAE,SAAS,OAAO,EAAO;IAKzC,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAW5B,2EAA2E;IAC3E,KAAK,IAAI,WAAW;CAUrB"}
@@ -1,14 +1,45 @@
1
- function a(n, t, i, r) {
2
- var o;
3
- if (i.category === void 0) return [];
4
- const f = (o = n == null ? void 0 : n.types.vertices[t]) == null ? void 0 : o.channels.find(
5
- (m) => m.column === i.category && m.scale === "categorical" && m.domain !== null
6
- );
7
- return f != null && f.domain ? Array.from({ length: f.domain }, (m, y) => y) : r ? Object.keys(r) : [];
1
+ var m = Object.defineProperty;
2
+ var l = (e) => {
3
+ throw TypeError(e);
4
+ };
5
+ var p = (e, t, n) => t in e ? m(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
6
+ var c = (e, t, n) => p(e, typeof t != "symbol" ? t + "" : t, n), h = (e, t, n) => t.has(e) || l("Cannot " + n);
7
+ var o = (e, t, n) => (h(e, t, "read from private field"), n ? n.call(e) : t.get(e)), f = (e, t, n) => t.has(e) ? l("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(e) : t.set(e, n), a = (e, t, n, r) => (h(e, t, "write to private field"), r ? r.call(e, n) : t.set(e, n), n);
8
+ function v(e, t, n) {
9
+ return t.byTable ? e.map((r) => r.name) : t.category === void 0 ? [] : n ? Object.keys(n) : [];
10
+ }
11
+ const b = (e, t) => (t == null ? void 0 : t[String(e)]) ?? String(e ?? "—");
12
+ var u, s;
13
+ class g {
14
+ constructor(t = []) {
15
+ c(this, "values", []);
16
+ f(this, u, /* @__PURE__ */ new Map());
17
+ f(this, s);
18
+ for (const n of t) this.code(n);
19
+ a(this, s, this.values.length);
20
+ }
21
+ code(t) {
22
+ const n = t == null ? null : String(t);
23
+ let r = o(this, u).get(n);
24
+ return r === void 0 && (r = this.values.length, this.values.push(typeof t == "bigint" ? Number(t) : t ?? null), o(this, u).set(n, r)), r;
25
+ }
26
+ /** Each code's rank: the seed's own order, then every other value seen. */
27
+ ranks() {
28
+ const t = new Uint32Array(this.values.length);
29
+ for (let r = 0; r < o(this, s); r++) t[r] = r;
30
+ const n = this.values.slice(o(this, s)).map((r, i) => ({ value: r, code: o(this, s) + i }));
31
+ return n.sort((r, i) => d(r.value, i.value)), n.forEach(({ code: r }, i) => {
32
+ t[r] = o(this, s) + i;
33
+ }), t;
34
+ }
35
+ }
36
+ u = new WeakMap(), s = new WeakMap();
37
+ function d(e, t) {
38
+ return typeof e == "number" && typeof t == "number" ? e - t : typeof e == "number" ? -1 : typeof t == "number" ? 1 : String(e ?? "").localeCompare(String(t ?? ""));
8
39
  }
9
- const d = (n, t) => (t == null ? void 0 : t[String(n)]) ?? String(n ?? "—");
10
40
  export {
11
- a as domainOf,
12
- d as nameOf
41
+ g as Dictionary,
42
+ v as domainOf,
43
+ b as nameOf
13
44
  };
14
45
  //# sourceMappingURL=categories.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"categories.js","sources":["../../src/core/categories.ts"],"sourcesContent":["import type { Corpus } from \"@fossil-lang/corpus\";\nimport type { Binding } from \"./channels\";\n\n/**\n * **The categorical domain, fixed before a tile arrives.** A column the manifest's `channels:`\n * declares as categorical ranks by its own ordinal, `0` to `domain − 1`; otherwise the host's\n * `categories` keys are the order. Only a value neither names is ranked as it is seen, after them —\n * which is what a legend whose colours moved as tiles arrived was doing for every value.\n */\nexport function domainOf(\n corpus: Corpus | null,\n typeIndex: number,\n binding: Binding,\n categories: Readonly<Record<string, string>> | undefined,\n): readonly unknown[] {\n if (binding.category === undefined) return [];\n const declared = corpus?.types.vertices[typeIndex]?.channels.find(\n (channel) => channel.column === binding.category && channel.scale === \"categorical\" && channel.domain !== null,\n );\n if (declared?.domain) return Array.from({ length: declared.domain }, (_, ordinal) => ordinal);\n return categories ? Object.keys(categories) : [];\n}\n\n/** What a legend, a card or an inspector calls a category value. */\nexport const nameOf = (value: unknown, categories: Readonly<Record<string, string>> | undefined): string =>\n categories?.[String(value)] ?? String(value ?? \"—\");\n"],"names":["domainOf","corpus","typeIndex","binding","categories","_a","declared","channel","_","ordinal","nameOf","value"],"mappings":"AASO,SAASA,EACdC,GACAC,GACAC,GACAC,GACoB;AALf,MAAAC;AAML,MAAIF,EAAQ,aAAa,OAAW,QAAO,CAAA;AAC3C,QAAMG,KAAWD,IAAAJ,KAAA,gBAAAA,EAAQ,MAAM,SAASC,OAAvB,gBAAAG,EAAmC,SAAS;AAAA,IAC3D,CAACE,MAAYA,EAAQ,WAAWJ,EAAQ,YAAYI,EAAQ,UAAU,iBAAiBA,EAAQ,WAAW;AAAA;AAE5G,SAAID,KAAA,QAAAA,EAAU,SAAe,MAAM,KAAK,EAAE,QAAQA,EAAS,OAAA,GAAU,CAACE,GAAGC,MAAYA,CAAO,IACrFL,IAAa,OAAO,KAAKA,CAAU,IAAI,CAAA;AAChD;AAGO,MAAMM,IAAS,CAACC,GAAgBP,OACrCA,KAAA,gBAAAA,EAAa,OAAOO,CAAK,OAAM,OAAOA,KAAS,GAAG;"}
1
+ {"version":3,"file":"categories.js","sources":["../../src/core/categories.ts"],"sourcesContent":["import type { Binding } from \"./channels\";\nimport type { VertexTable } from \"@fossil-lang/corpus\";\n\n/**\n * **The categorical domain, fixed before the graph loads.** Colour by vertex type ranks the drawn\n * tables in the manifest's order; a column ranks by the keys of the host's `categories`. Only a value\n * neither names is ranked as it is seen, after them.\n */\nexport function domainOf(\n tables: readonly VertexTable[],\n binding: Binding,\n categories: Readonly<Record<string, string>> | undefined,\n): readonly unknown[] {\n if (binding.byTable) return tables.map((table) => table.name);\n if (binding.category === undefined) return [];\n return categories ? Object.keys(categories) : [];\n}\n\n/** What a legend, a card or an inspector calls a category value. */\nexport const nameOf = (value: unknown, categories: Readonly<Record<string, string>> | undefined): string =>\n categories?.[String(value)] ?? String(value ?? \"—\");\n\n/**\n * Values to codes, in the order first seen. **The seed ranks first, in its own order**, so a colour\n * is decided before a row arrives; a value outside it is ranked after the seed, numbers before\n * strings. Values meet by their text, so a column's `0` is the host's key `\"0\"`.\n */\nexport class Dictionary {\n readonly values: unknown[] = [];\n readonly #codes = new Map<string | null, number>();\n readonly #seeded: number;\n\n constructor(seed: readonly unknown[] = []) {\n for (const value of seed) this.code(value);\n this.#seeded = this.values.length;\n }\n\n code(value: unknown): number {\n const key = value === null || value === undefined ? null : String(value);\n let code = this.#codes.get(key);\n if (code === undefined) {\n code = this.values.length;\n this.values.push(typeof value === \"bigint\" ? Number(value) : (value ?? null));\n this.#codes.set(key, code);\n }\n return code;\n }\n\n /** Each code's rank: the seed's own order, then every other value seen. */\n ranks(): Uint32Array {\n const ranks = new Uint32Array(this.values.length);\n for (let code = 0; code < this.#seeded; code++) ranks[code] = code;\n const rest = this.values.slice(this.#seeded).map((value, i) => ({ value, code: this.#seeded + i }));\n rest.sort((a, b) => compare(a.value, b.value));\n rest.forEach(({ code }, i) => {\n ranks[code] = this.#seeded + i;\n });\n return ranks;\n }\n}\n\nfunction compare(a: unknown, b: unknown): number {\n if (typeof a === \"number\" && typeof b === \"number\") return a - b;\n if (typeof a === \"number\") return -1;\n if (typeof b === \"number\") return 1;\n return String(a ?? \"\").localeCompare(String(b ?? \"\"));\n}\n"],"names":["domainOf","tables","binding","categories","table","nameOf","value","_codes","_seeded","Dictionary","seed","__publicField","__privateAdd","__privateSet","key","code","__privateGet","ranks","rest","a","b","compare"],"mappings":";;;;;;;AAQO,SAASA,EACdC,GACAC,GACAC,GACoB;AACpB,SAAID,EAAQ,UAAgBD,EAAO,IAAI,CAACG,MAAUA,EAAM,IAAI,IACxDF,EAAQ,aAAa,SAAkB,CAAA,IACpCC,IAAa,OAAO,KAAKA,CAAU,IAAI,CAAA;AAChD;AAGO,MAAME,IAAS,CAACC,GAAgBH,OACrCA,KAAA,gBAAAA,EAAa,OAAOG,CAAK,OAAM,OAAOA,KAAS,GAAG;AAZ7C,IAAAC,GAAAC;AAmBA,MAAMC,EAAW;AAAA,EAKtB,YAAYC,IAA2B,IAAI;AAJlC,IAAAC,EAAA,gBAAoB,CAAA;AACpB,IAAAC,EAAA,MAAAL,uBAAa,IAAA;AACb,IAAAK,EAAA,MAAAJ;AAGP,eAAWF,KAASI,EAAM,MAAK,KAAKJ,CAAK;AACzC,IAAAO,EAAA,MAAKL,GAAU,KAAK,OAAO;AAAA,EAC7B;AAAA,EAEA,KAAKF,GAAwB;AAC3B,UAAMQ,IAAMR,KAAU,OAA8B,OAAO,OAAOA,CAAK;AACvE,QAAIS,IAAOC,EAAA,MAAKT,GAAO,IAAIO,CAAG;AAC9B,WAAIC,MAAS,WACXA,IAAO,KAAK,OAAO,QACnB,KAAK,OAAO,KAAK,OAAOT,KAAU,WAAW,OAAOA,CAAK,IAAKA,KAAS,IAAK,GAC5EU,EAAA,MAAKT,GAAO,IAAIO,GAAKC,CAAI,IAEpBA;AAAA,EACT;AAAA;AAAA,EAGA,QAAqB;AACnB,UAAME,IAAQ,IAAI,YAAY,KAAK,OAAO,MAAM;AAChD,aAASF,IAAO,GAAGA,IAAOC,EAAA,MAAKR,IAASO,IAAQ,CAAAE,EAAMF,CAAI,IAAIA;AAC9D,UAAMG,IAAO,KAAK,OAAO,MAAMF,EAAA,MAAKR,EAAO,EAAE,IAAI,CAACF,GAAO,OAAO,EAAE,OAAAA,GAAO,MAAMU,EAAA,MAAKR,KAAU,IAAI;AAClG,WAAAU,EAAK,KAAK,CAACC,GAAGC,MAAMC,EAAQF,EAAE,OAAOC,EAAE,KAAK,CAAC,GAC7CF,EAAK,QAAQ,CAAC,EAAE,MAAAH,EAAA,GAAQ,MAAM;AAC5B,MAAAE,EAAMF,CAAI,IAAIC,EAAA,MAAKR,KAAU;AAAA,IAC/B,CAAC,GACMS;AAAA,EACT;AACF;AA9BWV,IAAA,eACAC,IAAA;AA+BX,SAASa,EAAQF,GAAYC,GAAoB;AAC/C,SAAI,OAAOD,KAAM,YAAY,OAAOC,KAAM,WAAiBD,IAAIC,IAC3D,OAAOD,KAAM,WAAiB,KAC9B,OAAOC,KAAM,WAAiB,IAC3B,OAAOD,KAAK,EAAE,EAAE,cAAc,OAAOC,KAAK,EAAE,CAAC;AACtD;"}
@@ -4,10 +4,10 @@
4
4
  * paints every point one ink and leaves colour free to mean the selection.
5
5
  */
6
6
  export interface Channels {
7
- /** Which column colours a point, or a CSS colour every point wears. */
7
+ /** Which column colours a point, or a CSS colour every point wears. Absent, colour is the vertex type. */
8
8
  fill?: string;
9
9
  /**
10
- * Which column a point's shape carries. A tile carries one categorical column, so bound beside a
10
+ * Which column a point's shape carries. The graph holds one categorical column, so bound beside a
11
11
  * `fill` column this reads the same one; a second would need a second array everywhere.
12
12
  */
13
13
  symbol?: string;
@@ -18,8 +18,10 @@ export interface Channels {
18
18
  export declare function isColour(value: string | undefined): value is string;
19
19
  /** The columns a binding reads, which is what a scan projects. */
20
20
  export interface Binding {
21
- /** The one categorical column: `fill` when it names one, `symbol` when `fill` is a constant. */
21
+ /** The one categorical column: `fill` when it names one, `symbol` when `fill` is a constant or absent. */
22
22
  readonly category: string | undefined;
23
+ /** No column and no constant: the category is the vertex type. */
24
+ readonly byTable: boolean;
23
25
  /** What the size ramp is spent on — Plot's `r`. */
24
26
  readonly size: string | undefined;
25
27
  /** The text a label and the hover card show — Plot's `title`. */
@@ -29,6 +31,9 @@ export declare function bindingOf(options: Channels & {
29
31
  r?: string;
30
32
  title?: string;
31
33
  }): Binding;
32
- /** A binding is a projection: `fill`, `r` and `title` as columns become the scan's `select`. */
33
- export declare function projectionOf(binding: Binding, fixed: readonly string[]): string[];
34
+ /**
35
+ * A binding is a projection: `fill` and `r` as columns become the scan's `select`, where the table
36
+ * has them. `title` is not: a label's text is read for the few vertices that carry one.
37
+ */
38
+ export declare function projectionOf(binding: Binding, fixed: readonly string[], has: (column: string) => boolean): string[];
34
39
  //# sourceMappingURL=channels.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../src/core/channels.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kGAAkG;AAClG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,MAAM,CAEnE;AAED,kEAAkE;AAClE,MAAM,WAAW,OAAO;IACtB,gGAAgG;IAChG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,QAAQ,GAAG;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAMrF;AAED,gGAAgG;AAChG,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAEjF"}
1
+ {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../src/core/channels.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,0GAA0G;IAC1G,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kGAAkG;AAClG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,MAAM,CAEnE;AAED,kEAAkE;AAClE,MAAM,WAAW,OAAO;IACtB,0GAA0G;IAC1G,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,QAAQ,GAAG;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAIrF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,EAAE,CAGnH"}
@@ -1,19 +1,17 @@
1
- function l(r) {
2
- return r !== void 0 && /^(var\(|#|rgb|hsl|oklch|oklab|lab|lch|color\()/i.test(r);
1
+ function c(t) {
2
+ return t !== void 0 && /^(var\(|#|rgb|hsl|oklch|oklab|lab|lch|color\()/i.test(t);
3
3
  }
4
- function i(r) {
5
- return {
6
- category: l(r.fill) ? r.symbol : r.fill,
7
- size: r.r,
8
- title: r.title
9
- };
4
+ function n(t) {
5
+ const l = c(t.fill), r = l ? t.symbol : t.fill ?? t.symbol;
6
+ return { category: r, byTable: !l && r === void 0, size: t.r, title: t.title };
10
7
  }
11
- function c(r, t) {
12
- return [...new Set([...t, r.category, r.size, r.title].filter((e) => e !== void 0))];
8
+ function i(t, l, r) {
9
+ const o = [t.category, t.size].filter((e) => e !== void 0 && r(e));
10
+ return [.../* @__PURE__ */ new Set([...l, ...o])];
13
11
  }
14
12
  export {
15
- i as bindingOf,
16
- l as isColour,
17
- c as projectionOf
13
+ n as bindingOf,
14
+ c as isColour,
15
+ i as projectionOf
18
16
  };
19
17
  //# sourceMappingURL=channels.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"channels.js","sources":["../../src/core/channels.ts"],"sourcesContent":["/**\n * What each channel is bound to — Plot's names, and Plot's rule that **a CSS colour is a constant\n * and anything else is a column.** `fill=\"kind\"` spends colour on a category; `fill=\"var(--foreground)\"`\n * paints every point one ink and leaves colour free to mean the selection.\n */\nexport interface Channels {\n /** Which column colours a point, or a CSS colour every point wears. */\n fill?: string;\n /**\n * Which column a point's shape carries. A tile carries one categorical column, so bound beside a\n * `fill` column this reads the same one; a second would need a second array everywhere.\n */\n symbol?: string;\n /** What tints a link. Absent, a link takes the colour of the vertex it leaves. */\n stroke?: string;\n}\n\n/** Narrow on purpose — `var(…)`, a hex, a colour function — so a bare word is always a column. */\nexport function isColour(value: string | undefined): value is string {\n return value !== undefined && /^(var\\(|#|rgb|hsl|oklch|oklab|lab|lch|color\\()/i.test(value);\n}\n\n/** The columns a binding reads, which is what a scan projects. */\nexport interface Binding {\n /** The one categorical column: `fill` when it names one, `symbol` when `fill` is a constant. */\n readonly category: string | undefined;\n /** What the size ramp is spent on — Plot's `r`. */\n readonly size: string | undefined;\n /** The text a label and the hover card show — Plot's `title`. */\n readonly title: string | undefined;\n}\n\nexport function bindingOf(options: Channels & { r?: string; title?: string }): Binding {\n return {\n category: isColour(options.fill) ? options.symbol : options.fill,\n size: options.r,\n title: options.title,\n };\n}\n\n/** A binding is a projection: `fill`, `r` and `title` as columns become the scan's `select`. */\nexport function projectionOf(binding: Binding, fixed: readonly string[]): string[] {\n return [...new Set([...fixed, binding.category, binding.size, binding.title].filter((c) => c !== undefined))];\n}\n"],"names":["isColour","value","bindingOf","options","projectionOf","binding","fixed","c"],"mappings":"AAkBO,SAASA,EAASC,GAA4C;AACnE,SAAOA,MAAU,UAAa,kDAAkD,KAAKA,CAAK;AAC5F;AAYO,SAASC,EAAUC,GAA6D;AACrF,SAAO;AAAA,IACL,UAAUH,EAASG,EAAQ,IAAI,IAAIA,EAAQ,SAASA,EAAQ;AAAA,IAC5D,MAAMA,EAAQ;AAAA,IACd,OAAOA,EAAQ;AAAA,EAAA;AAEnB;AAGO,SAASC,EAAaC,GAAkBC,GAAoC;AACjF,SAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAGA,GAAOD,EAAQ,UAAUA,EAAQ,MAAMA,EAAQ,KAAK,EAAE,OAAO,CAACE,MAAMA,MAAM,MAAS,CAAC,CAAC;AAC9G;"}
1
+ {"version":3,"file":"channels.js","sources":["../../src/core/channels.ts"],"sourcesContent":["/**\n * What each channel is bound to — Plot's names, and Plot's rule that **a CSS colour is a constant\n * and anything else is a column.** `fill=\"kind\"` spends colour on a category; `fill=\"var(--foreground)\"`\n * paints every point one ink and leaves colour free to mean the selection.\n */\nexport interface Channels {\n /** Which column colours a point, or a CSS colour every point wears. Absent, colour is the vertex type. */\n fill?: string;\n /**\n * Which column a point's shape carries. The graph holds one categorical column, so bound beside a\n * `fill` column this reads the same one; a second would need a second array everywhere.\n */\n symbol?: string;\n /** What tints a link. Absent, a link takes the colour of the vertex it leaves. */\n stroke?: string;\n}\n\n/** Narrow on purpose — `var(…)`, a hex, a colour function — so a bare word is always a column. */\nexport function isColour(value: string | undefined): value is string {\n return value !== undefined && /^(var\\(|#|rgb|hsl|oklch|oklab|lab|lch|color\\()/i.test(value);\n}\n\n/** The columns a binding reads, which is what a scan projects. */\nexport interface Binding {\n /** The one categorical column: `fill` when it names one, `symbol` when `fill` is a constant or absent. */\n readonly category: string | undefined;\n /** No column and no constant: the category is the vertex type. */\n readonly byTable: boolean;\n /** What the size ramp is spent on — Plot's `r`. */\n readonly size: string | undefined;\n /** The text a label and the hover card show — Plot's `title`. */\n readonly title: string | undefined;\n}\n\nexport function bindingOf(options: Channels & { r?: string; title?: string }): Binding {\n const constant = isColour(options.fill);\n const category = constant ? options.symbol : (options.fill ?? options.symbol);\n return { category, byTable: !constant && category === undefined, size: options.r, title: options.title };\n}\n\n/**\n * A binding is a projection: `fill` and `r` as columns become the scan's `select`, where the table\n * has them. `title` is not: a label's text is read for the few vertices that carry one.\n */\nexport function projectionOf(binding: Binding, fixed: readonly string[], has: (column: string) => boolean): string[] {\n const bound = [binding.category, binding.size].filter((c): c is string => c !== undefined && has(c));\n return [...new Set([...fixed, ...bound])];\n}\n"],"names":["isColour","value","bindingOf","options","constant","category","projectionOf","binding","fixed","has","bound","c"],"mappings":"AAkBO,SAASA,EAASC,GAA4C;AACnE,SAAOA,MAAU,UAAa,kDAAkD,KAAKA,CAAK;AAC5F;AAcO,SAASC,EAAUC,GAA6D;AACrF,QAAMC,IAAWJ,EAASG,EAAQ,IAAI,GAChCE,IAAWD,IAAWD,EAAQ,SAAUA,EAAQ,QAAQA,EAAQ;AACtE,SAAO,EAAE,UAAAE,GAAU,SAAS,CAACD,KAAYC,MAAa,QAAW,MAAMF,EAAQ,GAAG,OAAOA,EAAQ,MAAA;AACnG;AAMO,SAASG,EAAaC,GAAkBC,GAA0BC,GAA4C;AACnH,QAAMC,IAAQ,CAACH,EAAQ,UAAUA,EAAQ,IAAI,EAAE,OAAO,CAACI,MAAmBA,MAAM,UAAaF,EAAIE,CAAC,CAAC;AACnG,SAAO,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAGH,GAAO,GAAGE,CAAK,CAAC,CAAC;AAC1C;"}
@@ -1,18 +1,24 @@
1
- import { Corpus, TileMatrixSet } from '@fossil-lang/corpus';
2
- import { VertexId } from './resident';
3
- /** One vertex's row, as its type's fields order it — every column but the address and the position. */
1
+ import { Corpus } from '@fossil-lang/corpus';
2
+ import { Geometry } from './load';
3
+ import { VertexId } from './types';
4
+ /** One vertex's row, as its table's properties order it — every column but the key and the position. */
4
5
  export interface VertexDetail {
5
6
  readonly vertex: VertexId;
7
+ /** The vertex table it belongs to. */
8
+ readonly table: string;
6
9
  readonly fields: readonly {
7
10
  readonly name: string;
8
11
  readonly value: unknown;
9
12
  }[];
10
13
  }
11
14
  /**
12
- * **Detail is fetched, not carried** — ADR 0001. A tile holds what the channels project; the rest of a
13
- * row is asked for when a reader focuses the vertex, as a scan of the one payload tile its `dense_id`
14
- * falls in, filtered to it. `corpus.node` takes an identity, and a tile carries an address, so the
15
- * address is what asks.
15
+ * **Detail is fetched, not carried.** The loaded graph holds positions and channels; the rest of a
16
+ * row is asked for when a reader focuses the vertex — a scan of its table, filtered to its key.
16
17
  */
17
- export declare function readVertex(corpus: Corpus, matrix: TileMatrixSet, vertex: VertexId, signal?: AbortSignal): Promise<VertexDetail | null>;
18
+ export declare function readVertex(corpus: Corpus, geometry: Geometry, vertex: VertexId, signal?: AbortSignal): Promise<VertexDetail | null>;
19
+ /**
20
+ * **A label's text, for the few vertices that carry one** — `title` where the vertex's table has the
21
+ * column, and the table's declared `identity` where it does not. One scan per table they fall in.
22
+ */
23
+ export declare function readTitles(corpus: Corpus, geometry: Geometry, vertices: readonly VertexId[], title: string | undefined, signal?: AbortSignal): Promise<Map<VertexId, string>>;
18
24
  //# sourceMappingURL=detail.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"detail.d.ts","sourceRoot":"","sources":["../../src/core/detail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC5G,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGpD,uGAAuG;AACvG,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CAChF;AAKD;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,QAAQ,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAa9B"}
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,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACvC,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;AAED;;;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,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAmBhC"}
@@ -1,20 +1,38 @@
1
- import { PAYLOAD_ADDRESS as u, PAYLOAD_COORDINATES as m } from "@fossil-lang/corpus";
2
- import { denseOf as y } from "./resident.js";
3
- import { tileOfDense as D } from "./tile-matrix.js";
4
- const s = u[0], A = /* @__PURE__ */ new Set([s, ...m]);
5
- async function S(o, t, r, p) {
6
- const l = y(r), c = D(t, l), a = o.types.vertices.find((e) => e.type === t.type);
7
- if (!c || !a) return null;
8
- const f = a.fields.map((e) => e.name).filter((e) => !A.has(e)), d = o.scan({ type: t.type, filter: { column: s, op: "=", value: l }, select: [s, ...f] }), [n] = await d.read([c], { signal: p });
9
- return !n || n.numRows === 0 ? null : {
10
- vertex: r,
11
- fields: f.map((e) => {
12
- var i;
13
- return { name: e, value: ((i = n.getChild(e)) == null ? void 0 : i.toArray()[0]) ?? null };
1
+ const y = (o, a) => a < o.size ? o.tables[o.table[a]] : void 0;
2
+ async function k(o, a, i, c) {
3
+ var u, f;
4
+ const e = y(a, i);
5
+ if (!e) return null;
6
+ const l = /* @__PURE__ */ new Set([e.key, (u = e.position) == null ? void 0 : u.x, (f = e.position) == null ? void 0 : f.y]), r = e.properties.map((t) => t.name).filter((t) => !l.has(t)), n = o.scan({ table: e.name, filter: { column: e.key, op: "=", value: i }, select: [e.key, ...r], limit: 1 }), s = (await n.read(n.plan(), { signal: c })).find((t) => t.numRows > 0);
7
+ return s ? {
8
+ vertex: i,
9
+ table: e.name,
10
+ fields: r.map((t) => {
11
+ var p;
12
+ return { name: t, value: ((p = s.getChild(t)) == null ? void 0 : p.toArray()[0]) ?? null };
14
13
  })
15
- };
14
+ } : null;
15
+ }
16
+ async function h(o, a, i, c, e) {
17
+ const l = /* @__PURE__ */ new Map();
18
+ for (const n of i) {
19
+ const s = y(a, n);
20
+ s && l.set(s, [...l.get(s) ?? [], n]);
21
+ }
22
+ const r = /* @__PURE__ */ new Map();
23
+ return await Promise.all(
24
+ [...l].map(async ([n, s]) => {
25
+ var t, p;
26
+ const u = c !== void 0 && n.properties.some((d) => d.name === c) ? c : n.identity, f = o.scan({ table: n.name, filter: { column: n.key, op: "in", values: s }, select: [n.key, u] });
27
+ for (const d of await f.read(f.plan(), { signal: e })) {
28
+ const w = ((t = d.getChild(n.key)) == null ? void 0 : t.toArray()) ?? [], b = ((p = d.getChild(u)) == null ? void 0 : p.toArray()) ?? [];
29
+ for (let m = 0; m < d.numRows; m++) r.set(Number(w[m]), String(b[m] ?? ""));
30
+ }
31
+ })
32
+ ), r;
16
33
  }
17
34
  export {
18
- S as readVertex
35
+ h as readTitles,
36
+ k as readVertex
19
37
  };
20
38
  //# sourceMappingURL=detail.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"detail.js","sources":["../../src/core/detail.ts"],"sourcesContent":["import { PAYLOAD_ADDRESS, PAYLOAD_COORDINATES, type Corpus, type TileMatrixSet } from \"@fossil-lang/corpus\";\nimport { denseOf, type VertexId } from \"./resident\";\nimport { tileOfDense } from \"./tile-matrix\";\n\n/** One vertex's row, as its type's fields order it — every column but the address and the position. */\nexport interface VertexDetail {\n readonly vertex: VertexId;\n readonly fields: readonly { readonly name: string; readonly value: unknown }[];\n}\n\nconst KEY = PAYLOAD_ADDRESS[0] as string;\nconst HIDDEN = new Set<string>([KEY, ...PAYLOAD_COORDINATES]);\n\n/**\n * **Detail is fetched, not carried** — ADR 0001. A tile holds what the channels project; the rest of a\n * row is asked for when a reader focuses the vertex, as a scan of the one payload tile its `dense_id`\n * falls in, filtered to it. `corpus.node` takes an identity, and a tile carries an address, so the\n * address is what asks.\n */\nexport async function readVertex(\n corpus: Corpus,\n matrix: TileMatrixSet,\n vertex: VertexId,\n signal?: AbortSignal,\n): Promise<VertexDetail | null> {\n const dense = denseOf(vertex);\n const address = tileOfDense(matrix, dense);\n const type = corpus.types.vertices.find((t) => t.type === matrix.type);\n if (!address || !type) return null;\n const names = type.fields.map((field) => field.name).filter((name) => !HIDDEN.has(name));\n const scan = corpus.scan({ type: matrix.type, filter: { column: KEY, op: \"=\", value: dense }, select: [KEY, ...names] });\n const [rows] = await scan.read([address], { signal });\n if (!rows || rows.numRows === 0) return null;\n return {\n vertex,\n fields: names.map((name) => ({ name, value: rows.getChild(name)?.toArray()[0] ?? null })),\n };\n}\n"],"names":["KEY","PAYLOAD_ADDRESS","HIDDEN","PAYLOAD_COORDINATES","readVertex","corpus","matrix","vertex","signal","dense","denseOf","address","tileOfDense","type","t","names","field","name","scan","rows","_a"],"mappings":";;;AAUA,MAAMA,IAAMC,EAAgB,CAAC,GACvBC,IAAS,oBAAI,IAAY,CAACF,GAAK,GAAGG,CAAmB,CAAC;AAQ5D,eAAsBC,EACpBC,GACAC,GACAC,GACAC,GAC8B;AAC9B,QAAMC,IAAQC,EAAQH,CAAM,GACtBI,IAAUC,EAAYN,GAAQG,CAAK,GACnCI,IAAOR,EAAO,MAAM,SAAS,KAAK,CAACS,MAAMA,EAAE,SAASR,EAAO,IAAI;AACrE,MAAI,CAACK,KAAW,CAACE,EAAM,QAAO;AAC9B,QAAME,IAAQF,EAAK,OAAO,IAAI,CAACG,MAAUA,EAAM,IAAI,EAAE,OAAO,CAACC,MAAS,CAACf,EAAO,IAAIe,CAAI,CAAC,GACjFC,IAAOb,EAAO,KAAK,EAAE,MAAMC,EAAO,MAAM,QAAQ,EAAE,QAAQN,GAAK,IAAI,KAAK,OAAOS,KAAS,QAAQ,CAACT,GAAK,GAAGe,CAAK,GAAG,GACjH,CAACI,CAAI,IAAI,MAAMD,EAAK,KAAK,CAACP,CAAO,GAAG,EAAE,QAAAH,GAAQ;AACpD,SAAI,CAACW,KAAQA,EAAK,YAAY,IAAU,OACjC;AAAA,IACL,QAAAZ;AAAA,IACA,QAAQQ,EAAM,IAAI,CAACE,MAAA;;AAAU,eAAE,MAAAA,GAAM,SAAOG,IAAAD,EAAK,SAASF,CAAI,MAAlB,gBAAAG,EAAqB,UAAU,OAAM;KAAO;AAAA,EAAA;AAE5F;"}
1
+ {"version":3,"file":"detail.js","sources":["../../src/core/detail.ts"],"sourcesContent":["import type { Corpus, VertexTable } from \"@fossil-lang/corpus\";\nimport 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/**\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 Promise.all(\n [...byTable].map(async ([table, ids]) => {\n const column = title !== undefined && table.properties.some((p) => p.name === title) ? title : table.identity;\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 return found;\n}\n"],"names":["tableOf","geometry","vertex","readVertex","corpus","signal","_a","_b","table","hidden","names","p","name","scan","rows","batch","readTitles","vertices","title","byTable","found","ids","column","keys","texts","i"],"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;AAZhC,MAAAC,GAAAC;AAaE,QAAMC,IAAQR,EAAQC,GAAUC,CAAM;AACtC,MAAI,CAACM,EAAO,QAAO;AACnB,QAAMC,IAAS,oBAAI,IAAI,CAACD,EAAM,MAAKF,IAAAE,EAAM,aAAN,gBAAAF,EAAgB,IAAGC,IAAAC,EAAM,aAAN,gBAAAD,EAAgB,CAAC,CAAC,GAClEG,IAAQF,EAAM,WAAW,IAAI,CAACG,MAAMA,EAAE,IAAI,EAAE,OAAO,CAACC,MAAS,CAACH,EAAO,IAAIG,CAAI,CAAC,GAC9EC,IAAOT,EAAO,KAAK,EAAE,OAAOI,EAAM,MAAM,QAAQ,EAAE,QAAQA,EAAM,KAAK,IAAI,KAAK,OAAON,EAAA,GAAU,QAAQ,CAACM,EAAM,KAAK,GAAGE,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,OAAOM,EAAM;AAAA,IACb,QAAQE,EAAM,IAAI,CAACE,MAAA;AAvBvB,UAAAN;AAuBiC,eAAE,MAAAM,GAAM,SAAON,IAAAQ,EAAK,SAASF,CAAI,MAAlB,gBAAAN,EAAqB,UAAU,OAAM;KAAO;AAAA,EAAA,IAJxE;AAMpB;AAMA,eAAsBU,EACpBZ,GACAH,GACAgB,GACAC,GACAb,GACgC;AAChC,QAAMc,wBAAc,IAAA;AACpB,aAAWjB,KAAUe,GAAU;AAC7B,UAAMT,IAAQR,EAAQC,GAAUC,CAAM;AACtC,IAAIM,KAAOW,EAAQ,IAAIX,GAAO,CAAC,GAAIW,EAAQ,IAAIX,CAAK,KAAK,CAAA,GAAKN,CAAM,CAAC;AAAA,EACvE;AACA,QAAMkB,wBAAY,IAAA;AAClB,eAAM,QAAQ;AAAA,IACZ,CAAC,GAAGD,CAAO,EAAE,IAAI,OAAO,CAACX,GAAOa,CAAG,MAAM;AA7C7C,UAAAf,GAAAC;AA8CM,YAAMe,IAASJ,MAAU,UAAaV,EAAM,WAAW,KAAK,CAACG,MAAMA,EAAE,SAASO,CAAK,IAAIA,IAAQV,EAAM,UAC/FK,IAAOT,EAAO,KAAK,EAAE,OAAOI,EAAM,MAAM,QAAQ,EAAE,QAAQA,EAAM,KAAK,IAAI,MAAM,QAAQa,EAAA,GAAO,QAAQ,CAACb,EAAM,KAAKc,CAAM,GAAG;AACjI,iBAAWP,KAAS,MAAMF,EAAK,KAAKA,EAAK,QAAQ,EAAE,QAAAR,EAAA,CAAQ,GAAG;AAC5D,cAAMkB,MAAOjB,IAAAS,EAAM,SAASP,EAAM,GAAG,MAAxB,gBAAAF,EAA2B,cAAa,CAAA,GAC/CkB,MAAQjB,IAAAQ,EAAM,SAASO,CAAM,MAArB,gBAAAf,EAAwB,cAAa,CAAA;AACnD,iBAASkB,IAAI,GAAGA,IAAIV,EAAM,SAASU,OAAW,IAAI,OAAOF,EAAKE,CAAC,CAAC,GAAG,OAAOD,EAAMC,CAAC,KAAK,EAAE,CAAC;AAAA,MAC3F;AAAA,IACF,CAAC;AAAA,EAAA,GAEIL;AACT;"}
@@ -15,6 +15,8 @@ export declare class UntranslatableFilter extends Error {
15
15
  }
16
16
  /** One mosaic-sql expression node → one `Filter`. */
17
17
  export declare function translate(node: unknown): Filter;
18
+ /** Every column a filter names, once each. */
19
+ export declare function columnsOf(filter: Filter): string[];
18
20
  /**
19
21
  * The page's filter for the graph, or `undefined` for none. `selection.predicate` skips the clause
20
22
  * the graph published itself, which is the exemption the next function takes back.
@@ -30,5 +32,5 @@ export declare function graphClient(): MosaicClient;
30
32
  * the graph and applies it to every chart. A canvas that draws only what survives would otherwise
31
33
  * answer a lasso of thirteen by removing the other 1,530.
32
34
  */
33
- export declare function publish(selection: Selection, self: MosaicClient, column: string, dense: readonly number[] | null): void;
35
+ export declare function publish(selection: Selection, self: MosaicClient, column: string, ids: readonly number[] | null): void;
34
36
  //# sourceMappingURL=filter.d.ts.map
@@ -1 +1 @@
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;AAEhF;;;;;;;;GAQG;AAEH,+EAA+E;AAC/E,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,SAAkB,IAAI,0BAA0B;CACjD;AAoDD,qDAAqD;AACrD,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAyC/C;AAID;;;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,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GAC9B,IAAI,CAON"}
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;AAEhF;;;;;;;;GAQG;AAEH,+EAA+E;AAC/E,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,SAAkB,IAAI,0BAA0B;CACjD;AAoDD,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"}
@@ -1,14 +1,14 @@
1
- var f = Object.defineProperty;
2
- var h = (r, t, e) => t in r ? f(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
- var p = (r, t, e) => h(r, typeof t != "symbol" ? t + "" : t, e);
4
- import { MosaicClient as y, clausePoints as O } from "@kanzo-tech/mosaic";
5
- class m extends Error {
1
+ var m = Object.defineProperty;
2
+ var O = (n, t, r) => t in n ? m(n, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : n[t] = r;
3
+ var f = (n, t, r) => O(n, typeof t != "symbol" ? t + "" : t, r);
4
+ import { MosaicClient as h, clausePoints as y } from "@kanzo-tech/mosaic";
5
+ class A extends Error {
6
6
  constructor() {
7
7
  super(...arguments);
8
- p(this, "name", "UntranslatableFilter");
8
+ f(this, "name", "UntranslatableFilter");
9
9
  }
10
10
  }
11
- const A = {
11
+ const N = {
12
12
  "=": "=",
13
13
  "==": "=",
14
14
  "IS NOT DISTINCT FROM": "=",
@@ -18,82 +18,86 @@ const A = {
18
18
  "<=": "<=",
19
19
  ">": ">",
20
20
  ">=": ">="
21
- }, N = { "=": "=", "!=": "!=", "<": ">", "<=": ">=", ">": "<", ">=": "<=" }, s = (r) => {
22
- throw new m(
23
- `the graph cannot express this crossfilter clause as a filter on the corpus: ${String(r)}`
21
+ }, g = { "=": "=", "!=": "!=", "<": ">", "<=": ">=", ">": "<", ">=": "<=" }, o = (n) => {
22
+ throw new A(
23
+ `the graph cannot express this crossfilter clause as a filter on the corpus: ${String(n)}`
24
24
  );
25
25
  };
26
- function o(r) {
27
- const t = r;
26
+ function s(n) {
27
+ const t = n;
28
28
  return (t == null ? void 0 : t.type) === "COLUMN_REF" && typeof t.name == "string" ? t.name : null;
29
29
  }
30
- function i(r) {
31
- const t = r, e = (t == null ? void 0 : t.type) === "LITERAL" || (t == null ? void 0 : t.type) === "PARAM" ? t.value : s(r);
32
- if (typeof e == "number" || typeof e == "bigint" || typeof e == "string" || typeof e == "boolean")
33
- return e;
34
- if (e instanceof Date) {
35
- const n = e.toISOString();
36
- return n.endsWith("T00:00:00.000Z") ? n.slice(0, 10) : n.replace("T", " ").replace("Z", "");
30
+ function u(n) {
31
+ const t = n, r = (t == null ? void 0 : t.type) === "LITERAL" || (t == null ? void 0 : t.type) === "PARAM" ? t.value : o(n);
32
+ if (typeof r == "number" || typeof r == "bigint" || typeof r == "string" || typeof r == "boolean")
33
+ return r;
34
+ if (r instanceof Date) {
35
+ const e = r.toISOString();
36
+ return e.endsWith("T00:00:00.000Z") ? e.slice(0, 10) : e.replace("T", " ").replace("Z", "");
37
37
  }
38
- return s(r);
38
+ return o(n);
39
39
  }
40
- function g(r) {
41
- const t = r;
42
- return (Array.isArray(r) ? r : Array.isArray(t == null ? void 0 : t.values) ? t.values : s(r)).map(i);
40
+ function v(n) {
41
+ const t = n;
42
+ return (Array.isArray(n) ? n : Array.isArray(t == null ? void 0 : t.values) ? t.values : o(n)).map(u);
43
43
  }
44
- function l(r) {
45
- const t = r;
46
- if (Array.isArray(r)) return c(r.map(l));
44
+ function c(n) {
45
+ const t = n;
46
+ if (Array.isArray(n)) return i(n.map(c));
47
47
  switch (t == null ? void 0 : t.type) {
48
48
  case "LOGICAL_OPERATOR": {
49
- const e = (t.clauses ?? []).map(l);
50
- return t.op === "OR" ? { or: e } : c(e);
49
+ const r = (t.clauses ?? []).map(c);
50
+ return t.op === "OR" ? { or: r } : i(r);
51
51
  }
52
52
  case "UNARY":
53
- return t.op === "NOT" ? { not: l(t.expr) } : s(r);
53
+ return t.op === "NOT" ? { not: c(t.expr) } : o(n);
54
54
  case "UNARY_POSTFIX": {
55
- const e = o(t.expr) ?? s(r);
56
- return t.op === "IS NULL" ? { column: e, op: "is null" } : t.op === "IS NOT NULL" ? { column: e, op: "not null" } : s(r);
55
+ const r = s(t.expr) ?? o(n);
56
+ return t.op === "IS NULL" ? { column: r, op: "is null" } : t.op === "IS NOT NULL" ? { column: r, op: "not null" } : o(n);
57
57
  }
58
58
  case "BINARY": {
59
- const e = A[String(t.op).toUpperCase()] ?? s(r), n = o(t.left);
60
- return n !== null ? { column: n, op: e, value: i(t.right) } : { column: o(t.right) ?? s(r), op: N[e], value: i(t.left) };
59
+ const r = N[String(t.op).toUpperCase()] ?? o(n), e = s(t.left);
60
+ return e !== null ? { column: e, op: r, value: u(t.right) } : { column: s(t.right) ?? o(n), op: g[r], value: u(t.left) };
61
61
  }
62
62
  case "BETWEEN":
63
63
  case "NOT_BETWEEN": {
64
- const e = o(t.expr) ?? s(r), [n, a] = t.extent ?? s(r), u = c([
65
- { column: e, op: ">=", value: i(n) },
66
- { column: e, op: "<=", value: i(a) }
64
+ const r = s(t.expr) ?? o(n), [e, a] = t.extent ?? o(n), p = i([
65
+ { column: r, op: ">=", value: u(e) },
66
+ { column: r, op: "<=", value: u(a) }
67
67
  ]);
68
- return t.type === "BETWEEN" ? u : { not: u };
68
+ return t.type === "BETWEEN" ? p : { not: p };
69
69
  }
70
70
  case "IN":
71
- return { column: o(t.expr) ?? s(r), op: "in", values: g(t.values) };
71
+ return { column: s(t.expr) ?? o(n), op: "in", values: v(t.values) };
72
72
  default:
73
- return s(r);
73
+ return o(n);
74
74
  }
75
75
  }
76
- const c = (r) => r.length === 1 ? r[0] : { and: r };
77
- function R(r, t) {
78
- const e = r.predicate(t), n = (Array.isArray(e) ? e : [e]).filter((a) => a != null);
79
- return n.length === 0 ? void 0 : l(n);
76
+ const i = (n) => n.length === 1 ? n[0] : { and: n };
77
+ function l(n) {
78
+ return "column" in n ? [n.column] : "and" in n ? [...new Set(n.and.flatMap(l))] : "or" in n ? [...new Set(n.or.flatMap(l))] : "not" in n ? l(n.not) : [];
79
+ }
80
+ function S(n, t) {
81
+ const r = n.predicate(t), e = (Array.isArray(r) ? r : [r]).filter((a) => a != null);
82
+ return e.length === 0 ? void 0 : c(e);
80
83
  }
81
84
  function T() {
82
- return new y();
85
+ return new h();
83
86
  }
84
- function I(r, t, e, n) {
85
- r.update(
86
- O([e], n && n.length > 0 ? n.map((a) => [a]) : void 0, {
87
+ function I(n, t, r, e) {
88
+ n.update(
89
+ y([r], e && e.length > 0 ? e.map((a) => [a]) : void 0, {
87
90
  source: t,
88
91
  clients: /* @__PURE__ */ new Set([t])
89
92
  })
90
93
  );
91
94
  }
92
95
  export {
93
- m as UntranslatableFilter,
94
- R as filterFor,
96
+ A as UntranslatableFilter,
97
+ l as columnsOf,
98
+ S as filterFor,
95
99
  T as graphClient,
96
100
  I as publish,
97
- l as translate
101
+ c as translate
98
102
  };
99
103
  //# sourceMappingURL=filter.js.map