@toclocoinc/lattice-grid 1.15.0 → 1.17.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 +1 -1
- package/docs/API.html +473 -14
- package/docs/api-detail.html +334 -5
- package/lattice-grid.d.ts +402 -6
- package/lattice-grid.esm.min.js +4080 -890
- package/lattice-grid.min.cjs +4080 -890
- package/lattice-grid.min.css +1 -1
- package/lattice-grid.min.js +4080 -890
- package/modules/charts.esm.min.js +89 -4
- package/modules/devtools.esm.min.js +2 -2
- package/modules/dhtmlx-compat.esm.min.js +46 -4
- package/modules/htmx.esm.min.js +4080 -890
- package/modules/htmx.min.cjs +4080 -890
- package/modules/htmx.min.js +4080 -890
- package/modules/react.esm.min.js +2 -2
- package/modules/svelte.esm.min.js +2 -2
- package/modules/vue.esm.min.js +2 -2
- package/modules/webcomponent.esm.min.js +4080 -890
- package/package.json +1 -1
package/lattice-grid.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.
|
|
2
|
+
* Lattice Grid 1.17.0, type declarations
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
@@ -341,6 +341,22 @@ export interface LookupSpec {
|
|
|
341
341
|
export type DecorationName = 'plain' | 'fill' | 'pill' | 'dot' | 'bar' | 'heat' | 'icon';
|
|
342
342
|
export type VariantName = 'neutral' | 'info' | 'success' | 'warning' | 'danger' | 'accent' | 'none' | (string & {});
|
|
343
343
|
|
|
344
|
+
/** A built-in threshold icon set, mapping value bands to built-in glyphs. */
|
|
345
|
+
export type IconSetName = 'trafficLights' | 'arrows' | 'trafficArrows' | 'ratings' | (string & {});
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* One band of a threshold icon set. A value clears a band when it is at least
|
|
349
|
+
* `min`; the highest band it clears wins. Omit `min` on the last band to make
|
|
350
|
+
* it the catch-all. `label` is what assistive technology announces for the
|
|
351
|
+
* glyph, so a screen-reader user hears the band's meaning, not only the value.
|
|
352
|
+
*/
|
|
353
|
+
export interface IconBand {
|
|
354
|
+
min?: number;
|
|
355
|
+
icon: string;
|
|
356
|
+
label?: string;
|
|
357
|
+
variant?: VariantName;
|
|
358
|
+
}
|
|
359
|
+
|
|
344
360
|
export interface DecorationSpec {
|
|
345
361
|
type: DecorationName;
|
|
346
362
|
size?: 'sm' | 'md' | 'lg';
|
|
@@ -349,6 +365,10 @@ export interface DecorationSpec {
|
|
|
349
365
|
edge?: boolean;
|
|
350
366
|
position?: 'start' | 'end';
|
|
351
367
|
name?: string | Record<string, string>;
|
|
368
|
+
/** icon only: a built-in threshold icon set, expanded to `bands`. */
|
|
369
|
+
iconSet?: IconSetName;
|
|
370
|
+
/** icon only: value bands mapped to glyphs, first match by descending `min`. */
|
|
371
|
+
bands?: IconBand[];
|
|
352
372
|
min?: number;
|
|
353
373
|
max?: number;
|
|
354
374
|
origin?: number;
|
|
@@ -738,6 +758,94 @@ export interface Source {
|
|
|
738
758
|
|
|
739
759
|
export interface MemorySourceConfig { mode: 'memory'; columnarBelow?: number }
|
|
740
760
|
|
|
761
|
+
/**
|
|
762
|
+
* How rows are ingested into the column store.
|
|
763
|
+
*/
|
|
764
|
+
export interface IngestConfig {
|
|
765
|
+
/**
|
|
766
|
+
* Retain the caller's row objects by reference so identity round-trips.
|
|
767
|
+
* Default `true`, the historical behaviour: `rows.data()` returns the exact
|
|
768
|
+
* objects you supplied, `row === sourceObject` holds, and a custom renderer
|
|
769
|
+
* reading `row.sourceObject` works.
|
|
770
|
+
*
|
|
771
|
+
* Set `false` to keep only the packed columns and reconstruct a plain row
|
|
772
|
+
* object from them on demand. This drops roughly half the resident footprint,
|
|
773
|
+
* but changes three behaviours: `rows.data()` returns freshly reconstructed
|
|
774
|
+
* objects (new object each call, so `row === sourceObject` no longer holds),
|
|
775
|
+
* a custom renderer that reaches for `row.sourceObject` gets a reconstruction
|
|
776
|
+
* rather than the original, and equality against a row becomes value-based.
|
|
777
|
+
* The stored values are unchanged, so `get()`, `byKey()`, `value()` and
|
|
778
|
+
* `values()` are unaffected.
|
|
779
|
+
*/
|
|
780
|
+
retainSource?: boolean;
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Release the caller's row objects from the *source layer* once the column
|
|
784
|
+
* store has been built, so the columns become the sole resident copy of the
|
|
785
|
+
* data. Default `false`, which keeps today's behaviour.
|
|
786
|
+
*
|
|
787
|
+
* `retainSource:false` stops the {@link https://en.wikipedia.org/wiki/Column-oriented_DBMS column store}
|
|
788
|
+
* from holding the caller's objects, but the memory source and the grid config
|
|
789
|
+
* still retain the supplied array by reference — so the objects stay alive and
|
|
790
|
+
* the resident footprint does not actually fall. This flag closes that gap: it
|
|
791
|
+
* clears `MemorySource`'s retained array and drops the array from the grid
|
|
792
|
+
* config, leaving nothing on the heap but the packed columns. That is where
|
|
793
|
+
* the large reduction comes from (roughly an order of magnitude at a million
|
|
794
|
+
* rows), not from `retainSource` on its own.
|
|
795
|
+
*
|
|
796
|
+
* Implies `retainSource:false`: dropping the caller's objects while the store
|
|
797
|
+
* still expects to read through them would leave the source with no data at
|
|
798
|
+
* all, so setting this on forces the store to reconstruct rows from columns.
|
|
799
|
+
* Every read is therefore served from the columns — `at()`, `byKey()`,
|
|
800
|
+
* `get()`, `value()`, `values()`, filtering, sorting, grouping, totals and
|
|
801
|
+
* export are all unaffected in their values. What changes is the same three
|
|
802
|
+
* identity behaviours `retainSource:false` documents: `rows.data()` returns
|
|
803
|
+
* freshly reconstructed objects (so `row === sourceObject` no longer holds), a
|
|
804
|
+
* custom renderer reaching for `row.sourceObject` gets a reconstruction, and
|
|
805
|
+
* equality against a row becomes value-based.
|
|
806
|
+
*
|
|
807
|
+
* One consumer cannot be served from the columns: an *impure computed column*
|
|
808
|
+
* (a shadow, or a rank/positional column) is deliberately never materialised
|
|
809
|
+
* into the store, so its handle is built by reading the source objects. Under
|
|
810
|
+
* `dropSourceRows` those objects are gone, so such a column reduces over
|
|
811
|
+
* nothing and warns once rather than returning a silently wrong figure. Do not
|
|
812
|
+
* enable `dropSourceRows` on a grid that sorts, filters, groups or totals on a
|
|
813
|
+
* shadow or a positional column.
|
|
814
|
+
*/
|
|
815
|
+
dropSourceRows?: boolean;
|
|
816
|
+
|
|
817
|
+
/**
|
|
818
|
+
* Columnize `stream`-source ingest on a Worker so a large load does not block
|
|
819
|
+
* the main thread. Default `false`. When on, an arriving chunk that clears
|
|
820
|
+
* {@link IngestConfig.workerThreshold} is packed into typed column buffers on
|
|
821
|
+
* the Worker; the main thread merges the finished buffers into the store and
|
|
822
|
+
* renders, without running the per-field extraction pass that otherwise
|
|
823
|
+
* dominates ingest.
|
|
824
|
+
*
|
|
825
|
+
* This makes **stream** ingest non-blocking (remote sources already are).
|
|
826
|
+
* Memory and paged sources cannot be made non-blocking this way — the main
|
|
827
|
+
* thread must read the caller's own row objects — and are unaffected. The
|
|
828
|
+
* effect composes with `retainSource: false`: with it off the source keeps no
|
|
829
|
+
* caller-object array on the main thread at all, so the load is both
|
|
830
|
+
* non-blocking and lighter on memory.
|
|
831
|
+
*
|
|
832
|
+
* A column that reads through a closure — a `date` column's storage
|
|
833
|
+
* conversion, or a computed column — cannot cross the Worker boundary, so a
|
|
834
|
+
* grid with any such column columnizes on the main thread and says so once.
|
|
835
|
+
* Falls back silently to the main thread wherever a Worker cannot be created.
|
|
836
|
+
*/
|
|
837
|
+
useWorker?: boolean;
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Row count in a single stream chunk at or above which columnization is
|
|
841
|
+
* offloaded to the Worker when {@link IngestConfig.useWorker} is on. Default
|
|
842
|
+
* `10000`. A smaller first chunk is packed on the main thread, where the
|
|
843
|
+
* cost is trivial and the postMessage round trip would only add latency to
|
|
844
|
+
* time-to-first-row.
|
|
845
|
+
*/
|
|
846
|
+
workerThreshold?: number;
|
|
847
|
+
}
|
|
848
|
+
|
|
741
849
|
export interface PagedSourceConfig {
|
|
742
850
|
mode: 'paged';
|
|
743
851
|
pageSize?: number;
|
|
@@ -968,6 +1076,15 @@ export interface EditConfig {
|
|
|
968
1076
|
commit?: (write: PendingWrite) => unknown;
|
|
969
1077
|
confirm?: 'auto' | 'manual';
|
|
970
1078
|
pendingTimeout?: number;
|
|
1079
|
+
/**
|
|
1080
|
+
* Show a preview of what a bulk paste will change before it commits (§12),
|
|
1081
|
+
* with confirm/cancel. Off by default: a paste commits straight away, exactly
|
|
1082
|
+
* as it always has. When on, a paste into more than one cell first opens a
|
|
1083
|
+
* dialog listing every cell that changes (old → new) and every cell that would
|
|
1084
|
+
* be rejected (permission, data-type, read-only); confirm commits precisely
|
|
1085
|
+
* that set through the ordinary edit path, cancel commits nothing.
|
|
1086
|
+
*/
|
|
1087
|
+
pastePreview?: boolean;
|
|
971
1088
|
}
|
|
972
1089
|
|
|
973
1090
|
export interface PendingWrite {
|
|
@@ -1010,6 +1127,8 @@ export interface GridConfig {
|
|
|
1010
1127
|
rowKey?: string | ((row: unknown) => string);
|
|
1011
1128
|
/** Where rows come from: memory, paged, remote, stream or derived. */
|
|
1012
1129
|
source?: SourceConfig;
|
|
1130
|
+
/** How rows are ingested into the column store. */
|
|
1131
|
+
ingest?: IngestConfig;
|
|
1013
1132
|
/** Applied to every column before its own settings. */
|
|
1014
1133
|
columnDefaults?: Column;
|
|
1015
1134
|
/** Named bundles of column settings, referenced by a column's `preset`. */
|
|
@@ -1074,6 +1193,21 @@ export interface GridConfig {
|
|
|
1074
1193
|
*/
|
|
1075
1194
|
cornerRadius?: boolean | number | string;
|
|
1076
1195
|
|
|
1196
|
+
/**
|
|
1197
|
+
* Shade alternate data rows (zebra striping).
|
|
1198
|
+
*
|
|
1199
|
+
* Off by default, and strictly opt-in: an existing grid must look exactly the
|
|
1200
|
+
* same on upgrade. When `true`, every other data row takes the theme's
|
|
1201
|
+
* `--lattice-surface-alt` background, which every palette already defines, so
|
|
1202
|
+
* dark, high-contrast and terminal stripe correctly without extra work.
|
|
1203
|
+
*
|
|
1204
|
+
* Parity follows the row's *logical* index, not its position in the DOM, so a
|
|
1205
|
+
* row keeps its stripe across a scroll even though the rows are recycled.
|
|
1206
|
+
* Structural rows — group headings, group footers and the grand total — are
|
|
1207
|
+
* never striped, and both selection and hover still win over the stripe.
|
|
1208
|
+
*/
|
|
1209
|
+
stripedRows?: boolean;
|
|
1210
|
+
|
|
1077
1211
|
/**
|
|
1078
1212
|
* Show a bar above the column headings for filtering columns by tag.
|
|
1079
1213
|
*
|
|
@@ -1228,7 +1362,12 @@ export interface GridConfig {
|
|
|
1228
1362
|
* only the sort, filter and menu controls inside them.
|
|
1229
1363
|
*/
|
|
1230
1364
|
showHeader?: boolean;
|
|
1231
|
-
/**
|
|
1365
|
+
/**
|
|
1366
|
+
* Header height in pixels. Omitted, the header takes its height from the
|
|
1367
|
+
* density-scaled `--lattice-header-height` token, so `density` sizes the
|
|
1368
|
+
* header as it sizes the rows. A number names one explicitly and outranks the
|
|
1369
|
+
* token.
|
|
1370
|
+
*/
|
|
1232
1371
|
headerHeight?: number;
|
|
1233
1372
|
/** How many rows to render beyond the viewport. More costs memory and
|
|
1234
1373
|
* smooths fast scrolling; fewer is lighter and can show a gap. */
|
|
@@ -1374,6 +1513,14 @@ export interface GridConfig {
|
|
|
1374
1513
|
totalOnlyChangedColumns?: boolean;
|
|
1375
1514
|
/** Put the total in the header rather than a footer row. */
|
|
1376
1515
|
showTotalInHeader?: boolean;
|
|
1516
|
+
/**
|
|
1517
|
+
* Let the user pick a column's reduction from the column menu. On, the
|
|
1518
|
+
* totalling entry becomes an "Aggregate" submenu offering the aggregates the
|
|
1519
|
+
* column's type says are meaningful (§9.4); off, the menu keeps its plain
|
|
1520
|
+
* "Total this column" toggle. Off by default, so an existing grid is
|
|
1521
|
+
* unchanged.
|
|
1522
|
+
*/
|
|
1523
|
+
aggregateChooser?: boolean;
|
|
1377
1524
|
/** Render only the visible columns once there are more than this many. */
|
|
1378
1525
|
columnVirtualisationAbove?: number;
|
|
1379
1526
|
/** The bar beneath the grid, and which panels it carries. */
|
|
@@ -1391,6 +1538,23 @@ export interface GridConfig {
|
|
|
1391
1538
|
*/
|
|
1392
1539
|
columnMenu?: boolean | ((p: ColumnMenuParams, defaults: MenuItem[]) => MenuItem[] | void);
|
|
1393
1540
|
|
|
1541
|
+
/**
|
|
1542
|
+
* Chart a selected cell range — the spreadsheet "chart this selection"
|
|
1543
|
+
* gesture. Off by default, so a grid opts in.
|
|
1544
|
+
*
|
|
1545
|
+
* The DOM layer draws no charts itself — the charts module is optional and
|
|
1546
|
+
* loaded by the host — so this is where the host wires the two together: a
|
|
1547
|
+
* function, or an object carrying `onChart`, is called with the grid and the
|
|
1548
|
+
* selected range when the reader chooses "Chart selection" from the cell
|
|
1549
|
+
* menu. The handler typically calls `chartRange` from
|
|
1550
|
+
* `lattice-grid/modules/charts`. `true` offers the item and emits nothing
|
|
1551
|
+
* extra; supply a handler to have it actually draw.
|
|
1552
|
+
*/
|
|
1553
|
+
rangeChart?:
|
|
1554
|
+
| boolean
|
|
1555
|
+
| ((grid: Grid, range: CellRange) => void)
|
|
1556
|
+
| { onChart?: (grid: Grid, range: CellRange) => void };
|
|
1557
|
+
|
|
1394
1558
|
/**
|
|
1395
1559
|
* The `?` keyboard shortcut overlay. `false` suppresses it, for a host
|
|
1396
1560
|
* that wants `?` for itself. Default true.
|
|
@@ -1453,9 +1617,11 @@ export interface GridConfig {
|
|
|
1453
1617
|
* Keep the enclosing group headings pinned above the viewport while
|
|
1454
1618
|
* scrolling inside a group.
|
|
1455
1619
|
*
|
|
1456
|
-
*
|
|
1457
|
-
* `
|
|
1458
|
-
*
|
|
1620
|
+
* Off by default — a deliberate product default; sticky group headers are
|
|
1621
|
+
* opt-in. `true` turns it on, stacking at most two; a number, or `{ depth }`,
|
|
1622
|
+
* sets how many may stack: each costs a row of viewport, so a deep grouping
|
|
1623
|
+
* would otherwise spend the screen describing itself. `false` is off, the
|
|
1624
|
+
* same as leaving it unset.
|
|
1459
1625
|
*/
|
|
1460
1626
|
stickyGroupHeaders?: boolean | number | { depth?: number };
|
|
1461
1627
|
/**
|
|
@@ -1503,6 +1669,22 @@ export interface GridConfig {
|
|
|
1503
1669
|
/** File name for the export action, without the extension. */
|
|
1504
1670
|
exportName?: string;
|
|
1505
1671
|
};
|
|
1672
|
+
/**
|
|
1673
|
+
* A drag-and-drop group-by strip above the column header — the pattern AG
|
|
1674
|
+
* Grid calls the row-group panel. Drag a column heading into it to group by
|
|
1675
|
+
* that column; the active groups show as removable, reorderable chips, and
|
|
1676
|
+
* reordering the chips changes the nesting order. It is keyboard-operable
|
|
1677
|
+
* (arrows navigate, Shift+arrow reorders, Delete ungroups, and an add control
|
|
1678
|
+
* groups any column), and every change is announced through the live region,
|
|
1679
|
+
* which is why it also addresses the drag-only complaint of BACKLOG-0000429.
|
|
1680
|
+
*
|
|
1681
|
+
* Off by default and non-breaking, matching `toolPanel`. It drives the same
|
|
1682
|
+
* grouping model as `grid.columns.group()`; it reimplements nothing.
|
|
1683
|
+
*/
|
|
1684
|
+
groupPanel?: boolean | {
|
|
1685
|
+
/** Placeholder shown while nothing is grouped. */
|
|
1686
|
+
hint?: string;
|
|
1687
|
+
};
|
|
1506
1688
|
/** The quick filter's initial text. */
|
|
1507
1689
|
quickFilterText?: string;
|
|
1508
1690
|
/**
|
|
@@ -1767,6 +1949,103 @@ export interface PushdownPlan {
|
|
|
1767
1949
|
needsAll: boolean;
|
|
1768
1950
|
/** Which parts could not be pushed: `filter`, `sort`, `quick`. */
|
|
1769
1951
|
unpushed: string[];
|
|
1952
|
+
/**
|
|
1953
|
+
* Whether the whole result was fetched because `fullDataset` is on, rather
|
|
1954
|
+
* than only because residual work forced it. When true, totals and statistics
|
|
1955
|
+
* reduce over the whole matching set and the windowed-stat warning is silent.
|
|
1956
|
+
*/
|
|
1957
|
+
full: boolean;
|
|
1958
|
+
/**
|
|
1959
|
+
* Per-aggregate provenance, present only when the last request computed
|
|
1960
|
+
* aggregates (BACKLOG-0000730 Part B): which statistics the engine computed
|
|
1961
|
+
* and which the client did, with the class the pushdown map assigned each.
|
|
1962
|
+
* Under grouping it also carries the `groupBy` the subtotals were computed
|
|
1963
|
+
* over. Build-time inspection, not a runtime per-figure marker.
|
|
1964
|
+
*/
|
|
1965
|
+
aggregates?: {
|
|
1966
|
+
engine: AggregateProvenance[];
|
|
1967
|
+
client: AggregateProvenance[];
|
|
1968
|
+
groupBy?: string[];
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
/**
|
|
1973
|
+
* Opt-in, sticky full-dataset pull for a pushdown/remote source
|
|
1974
|
+
* (BACKLOG-0000730). Off by default. When enabled, the source materialises the
|
|
1975
|
+
* entire matching set client-side once per query signature and serves every
|
|
1976
|
+
* window, total and statistic from it, so those figures are computed over the
|
|
1977
|
+
* whole set rather than the loaded window. A set past either limit is refused
|
|
1978
|
+
* with a visible `source:error` — never silently truncated.
|
|
1979
|
+
*/
|
|
1980
|
+
export interface PushdownFullDatasetConfig {
|
|
1981
|
+
/** Sticky: hold the whole matching set client-side. Default `false`. */
|
|
1982
|
+
enabled?: boolean;
|
|
1983
|
+
/** Refuse (visible error) past this many rows. Default `1_000_000`. */
|
|
1984
|
+
maxRows?: number;
|
|
1985
|
+
/** Refuse past this estimated heap cost, in bytes. Default `512 * 1024 * 1024`. */
|
|
1986
|
+
maxBytesEstimate?: number;
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
/** How one requested aggregate should be computed. */
|
|
1990
|
+
export type AggregateMode = 'engine' | 'client' | 'engine-if-identical';
|
|
1991
|
+
|
|
1992
|
+
/**
|
|
1993
|
+
* Design-time aggregate-pushdown policy for a pushdown source
|
|
1994
|
+
* (BACKLOG-0000730 Part B, ungrouped). The developer chooses, at grid setup
|
|
1995
|
+
* before render, whether each statistic is computed by the engine (fast, over
|
|
1996
|
+
* the matching set) or client-side (the grid's exact definition, needs a
|
|
1997
|
+
* full-dataset pull). It is fixed for the life of the grid, never a runtime
|
|
1998
|
+
* toggle, and never surfaced to an end user.
|
|
1999
|
+
*
|
|
2000
|
+
* Absent, every aggregate is computed client-side — today's behaviour, so no
|
|
2001
|
+
* existing caller regresses. `engine-if-identical` is the recommended setting
|
|
2002
|
+
* for a windowed DuckDB source: it pushes only the statistics whose engine
|
|
2003
|
+
* result is verified identical to the grid kernel, keeping the documented
|
|
2004
|
+
* MAY-DIFFER stats (e.g. `mode`) client-side. The engine is used only when the
|
|
2005
|
+
* filter is fully pushed; a residual filter forces every aggregate client-side,
|
|
2006
|
+
* so an engine figure and a client figure never mix in one result set.
|
|
2007
|
+
*/
|
|
2008
|
+
export interface PushdownAggregatesConfig {
|
|
2009
|
+
/**
|
|
2010
|
+
* The default policy for stats the engine can express. `'engine'` pushes
|
|
2011
|
+
* everything expressible (using the engine's method for MAY-DIFFER stats);
|
|
2012
|
+
* `'engine-if-identical'` pushes only the verified-identical ones; `'client'`
|
|
2013
|
+
* computes everything client-side. Default `'client'`.
|
|
2014
|
+
*/
|
|
2015
|
+
default?: AggregateMode;
|
|
2016
|
+
/** Per-stat overrides, winning over `default`. A stat the engine cannot
|
|
2017
|
+
* express (`weightedQuantile`) is always client-side regardless. */
|
|
2018
|
+
overrides?: Record<string, 'engine' | 'client'>;
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
/**
|
|
2022
|
+
* One aggregate the grid asks the source to compute over the matching set.
|
|
2023
|
+
* `params` carries e.g. `{ share: 0.1 }` so an adapter emits the matching SQL;
|
|
2024
|
+
* `weight` names the second column for a two-column stat like `correlation`.
|
|
2025
|
+
*/
|
|
2026
|
+
export interface AggregateRequest {
|
|
2027
|
+
/** Keys the result back to the request. */
|
|
2028
|
+
id: string;
|
|
2029
|
+
/** The column to reduce. */
|
|
2030
|
+
col: string;
|
|
2031
|
+
/** The statistic name, as used in `total: '<name>'`. */
|
|
2032
|
+
fn: string;
|
|
2033
|
+
/** The second column, for a two-column statistic. */
|
|
2034
|
+
weight?: string;
|
|
2035
|
+
/** Parameters the statistic takes, e.g. a trim share. */
|
|
2036
|
+
params?: Record<string, unknown>;
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
/** How one aggregate was routed, for `lastPlan()` provenance. */
|
|
2040
|
+
export interface AggregateProvenance {
|
|
2041
|
+
id: string;
|
|
2042
|
+
col: string;
|
|
2043
|
+
fn: string;
|
|
2044
|
+
/** How the engine result relates to the grid kernel. */
|
|
2045
|
+
class: 'identical' | 'may-differ' | 'fallback';
|
|
2046
|
+
/** Why it is client-side, when it is (config, fallback, or the guard). */
|
|
2047
|
+
reason?: string;
|
|
2048
|
+
weight?: string;
|
|
1770
2049
|
}
|
|
1771
2050
|
|
|
1772
2051
|
export interface PushdownSourceConfig {
|
|
@@ -1774,6 +2053,16 @@ export interface PushdownSourceConfig {
|
|
|
1774
2053
|
/** The compute barrel, for applying whatever the engine could not. */
|
|
1775
2054
|
compute?: object;
|
|
1776
2055
|
pageSize?: number;
|
|
2056
|
+
/**
|
|
2057
|
+
* Opt-in full-dataset pull. Off unless `fullDataset.enabled` is set. See
|
|
2058
|
+
* {@link PushdownFullDatasetConfig}.
|
|
2059
|
+
*/
|
|
2060
|
+
fullDataset?: PushdownFullDatasetConfig;
|
|
2061
|
+
/**
|
|
2062
|
+
* Design-time aggregate-pushdown policy. Absent = client-side (today's
|
|
2063
|
+
* behaviour). See {@link PushdownAggregatesConfig}.
|
|
2064
|
+
*/
|
|
2065
|
+
aggregates?: PushdownAggregatesConfig;
|
|
1777
2066
|
}
|
|
1778
2067
|
|
|
1779
2068
|
export interface StatisticsApi {
|
|
@@ -2164,6 +2453,11 @@ export interface RowsApi {
|
|
|
2164
2453
|
export interface ColumnsApi {
|
|
2165
2454
|
/** Set or clear a column's totals-row reduction. */
|
|
2166
2455
|
setTotal(id: string, fn: TotalName | TotalFn | null): void;
|
|
2456
|
+
/**
|
|
2457
|
+
* The aggregate names meaningful for a column, honouring its type's
|
|
2458
|
+
* `totals.supported` declaration (§9.4). What the aggregate chooser offers.
|
|
2459
|
+
*/
|
|
2460
|
+
aggregates(id: string): TotalName[];
|
|
2167
2461
|
/** Every distinct value in a column, from the dictionary where there is one. */
|
|
2168
2462
|
distinct(id: string): unknown[];
|
|
2169
2463
|
get(id: string): ResolvedColumn | undefined;
|
|
@@ -2186,6 +2480,13 @@ export interface ColumnsApi {
|
|
|
2186
2480
|
move(id: string, to: number): void;
|
|
2187
2481
|
pin(id: string, side: 'start' | 'end' | null): void;
|
|
2188
2482
|
resize(id: string, px: number): void;
|
|
2483
|
+
/**
|
|
2484
|
+
* Set, change or clear a column's decoration at runtime (§8.7). Pass `null` to
|
|
2485
|
+
* clear it back to plain text. Presentation config: it is not on the undo
|
|
2486
|
+
* timeline and is not carried in a saved view — use `grid.formatting` for
|
|
2487
|
+
* durable, view-persisted conditional styling.
|
|
2488
|
+
*/
|
|
2489
|
+
decorate(id: string, decoration: DecorationName | DecorationSpec | null, opts?: { variant?: VariantSpec }): void;
|
|
2189
2490
|
autoSize(ids?: string | string[]): void;
|
|
2190
2491
|
fit(): void;
|
|
2191
2492
|
group(ids: string | string[]): void;
|
|
@@ -2269,6 +2570,18 @@ export interface EditApi {
|
|
|
2269
2570
|
redo(): void;
|
|
2270
2571
|
setCells(writes: { key: string; colId: string; value: unknown }[], type?: 'cell' | 'fill' | 'paste'): number;
|
|
2271
2572
|
pasteInto(anchor: { key: string; colId: string }, text: string, extent?: { rows?: number; columns?: number }): number;
|
|
2573
|
+
/** Whether a bulk paste is previewed before it commits (`edit.pastePreview`, §12). */
|
|
2574
|
+
readonly pastePreview: boolean;
|
|
2575
|
+
/**
|
|
2576
|
+
* Compute what a paste would change, without committing (§12). The engine
|
|
2577
|
+
* behind `edit.pastePreview`: `changes` are the accepted writes with their old
|
|
2578
|
+
* and new values (and whether each actually differs), `rejected` are the cells
|
|
2579
|
+
* a commit would refuse, each with a reason.
|
|
2580
|
+
*/
|
|
2581
|
+
previewPaste(anchor: { key: string; colId: string }, text: string, extent?: { rows?: number; columns?: number }): {
|
|
2582
|
+
changes: { key: string; colId: string; oldValue: unknown; newValue: unknown; changed: boolean }[];
|
|
2583
|
+
rejected: { key: string; colId: string; value: unknown; reason: 'permission' | 'readOnly' | 'validation' | 'locked' | 'missing' }[];
|
|
2584
|
+
};
|
|
2272
2585
|
settle(id: string, ok: boolean, reason?: string): boolean;
|
|
2273
2586
|
pending(): OpenWrite[];
|
|
2274
2587
|
status(key: string, colId: string): 'pending' | null;
|
|
@@ -3265,7 +3578,51 @@ export function toneOf(direction: string, goodWhen: string): 'good' | 'bad' | 'f
|
|
|
3265
3578
|
*/
|
|
3266
3579
|
export function createPushdownSource(
|
|
3267
3580
|
config: PushdownSourceConfig,
|
|
3268
|
-
): SourceConfig & {
|
|
3581
|
+
): SourceConfig & {
|
|
3582
|
+
lastPlan(): PushdownPlan | null;
|
|
3583
|
+
/**
|
|
3584
|
+
* Compute a set of aggregates over the matching set, splitting them between
|
|
3585
|
+
* the engine and the client by the design-time `aggregates` config
|
|
3586
|
+
* (BACKLOG-0000730 Part B). Ungrouped, returns the engine-computed `values`
|
|
3587
|
+
* keyed by id. When the request carries a `groupBy`, returns `groups` instead:
|
|
3588
|
+
* one entry per subtotal level and the grand total (`level: 0`, produced by a
|
|
3589
|
+
* single `GROUP BY ROLLUP`), each with its key values and its aggregate values
|
|
3590
|
+
* keyed by id. The client list is what the caller computes itself over the
|
|
3591
|
+
* full set. Aggregates are pushed only when the filter is fully pushed and —
|
|
3592
|
+
* under grouping — every grouping key is a plain column the engine can group
|
|
3593
|
+
* by; a residual filter or an unpushable group key forces every aggregate
|
|
3594
|
+
* client-side (no mixed provenance).
|
|
3595
|
+
*/
|
|
3596
|
+
aggregate(
|
|
3597
|
+
request: RemoteRequest,
|
|
3598
|
+
requested: AggregateRequest[],
|
|
3599
|
+
): Promise<{
|
|
3600
|
+
values: Record<string, unknown>;
|
|
3601
|
+
groups?: Array<{
|
|
3602
|
+
keys: unknown[];
|
|
3603
|
+
grouping?: number[];
|
|
3604
|
+
level: number;
|
|
3605
|
+
values: Record<string, unknown>;
|
|
3606
|
+
}>;
|
|
3607
|
+
engine: AggregateProvenance[];
|
|
3608
|
+
client: AggregateProvenance[];
|
|
3609
|
+
}>;
|
|
3610
|
+
};
|
|
3611
|
+
|
|
3612
|
+
/**
|
|
3613
|
+
* The pushdown map (BACKLOG-0000730 Part B): one published record per statistic
|
|
3614
|
+
* giving whether the engine can express it, the DuckDB aggregate SQL it emits,
|
|
3615
|
+
* and whether that result is IDENTICAL to the grid's own kernel or MAY-DIFFER.
|
|
3616
|
+
* The single source of truth the push router, the docs and `lastPlan()` all read.
|
|
3617
|
+
*/
|
|
3618
|
+
export const STAT_PUSHDOWN: Readonly<Record<string, {
|
|
3619
|
+
pushable: boolean;
|
|
3620
|
+
class: 'identical' | 'may-differ' | 'fallback';
|
|
3621
|
+
sql?: string;
|
|
3622
|
+
note?: string;
|
|
3623
|
+
twoColumn?: boolean;
|
|
3624
|
+
blankAware?: boolean;
|
|
3625
|
+
}>>;
|
|
3269
3626
|
|
|
3270
3627
|
/**
|
|
3271
3628
|
* The capability set an adapter that declares nothing is treated as having:
|
|
@@ -3623,6 +3980,12 @@ export interface ChartSpec {
|
|
|
3623
3980
|
y?: string;
|
|
3624
3981
|
/** Splits the measure into one series per distinct value. */
|
|
3625
3982
|
series?: string;
|
|
3983
|
+
/**
|
|
3984
|
+
* The exact rows to chart, overriding the grid's own walk — an array, or a
|
|
3985
|
+
* function returning one at draw time. `chartRange` uses it to bind a chart
|
|
3986
|
+
* to the band of rows a selected range covers rather than the whole grid.
|
|
3987
|
+
*/
|
|
3988
|
+
rows?: object[] | ((grid: Grid) => object[]);
|
|
3626
3989
|
/** Several measures at once, for combo and candlestick. */
|
|
3627
3990
|
measures?: ChartMeasure[];
|
|
3628
3991
|
/** Endpoints, for sankey, chord and network. */
|
|
@@ -3753,6 +4116,39 @@ declare module 'lattice-grid/modules/charts' {
|
|
|
3753
4116
|
export const SCHEMES: Readonly<Record<string, readonly string[]>>;
|
|
3754
4117
|
export const PALETTE: readonly string[];
|
|
3755
4118
|
export function createChart(spec: ChartSpec): Chart;
|
|
4119
|
+
/**
|
|
4120
|
+
* Chart a selected cell range. Derives the chart from the range's shape — a
|
|
4121
|
+
* leading text column becomes the categories, the numeric columns become the
|
|
4122
|
+
* measures — and returns the live chart, or null when the range has nothing
|
|
4123
|
+
* to measure. Respects hidden and unreadable columns. The type is a sensible
|
|
4124
|
+
* default the caller can change with `chart.update({ type })`.
|
|
4125
|
+
*/
|
|
4126
|
+
export function chartRange(
|
|
4127
|
+
grid: Grid,
|
|
4128
|
+
opts: {
|
|
4129
|
+
container: Element | string;
|
|
4130
|
+
range?: CellRange;
|
|
4131
|
+
type?: ChartType;
|
|
4132
|
+
} & Partial<ChartSpec>,
|
|
4133
|
+
): Chart | null;
|
|
4134
|
+
/** Would {@link chartRange} draw something for the grid's current selection? */
|
|
4135
|
+
export function canChartRange(grid: Grid, opts?: { range?: CellRange }): boolean;
|
|
4136
|
+
/**
|
|
4137
|
+
* Decide what a chart of a range should be, without drawing it: the type, the
|
|
4138
|
+
* category column, the measure columns, and a `spec` ready for `createChart`
|
|
4139
|
+
* — or a `reason` naming why the range cannot be charted.
|
|
4140
|
+
*/
|
|
4141
|
+
export function deriveRangeSpec(
|
|
4142
|
+
grid: Grid,
|
|
4143
|
+
opts?: { range?: CellRange; type?: ChartType },
|
|
4144
|
+
): {
|
|
4145
|
+
spec: ChartSpec | null;
|
|
4146
|
+
type: ChartType | null;
|
|
4147
|
+
x: string | null;
|
|
4148
|
+
measures: string[];
|
|
4149
|
+
columns: string[];
|
|
4150
|
+
reason: string | null;
|
|
4151
|
+
};
|
|
3756
4152
|
export function registerScheme(name: string, colours: readonly string[]): void;
|
|
3757
4153
|
export function resolveScheme(spec?: object): object;
|
|
3758
4154
|
export function schemeNames(): string[];
|