argus-table 0.2.2 → 0.4.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 (83) hide show
  1. package/README.md +1 -1
  2. package/dist/argus-column-group.js +66 -0
  3. package/dist/argus-column-group.js.map +1 -0
  4. package/dist/argus-column.js +28 -26
  5. package/dist/argus-column.js.map +1 -1
  6. package/dist/argus-table.js +1497 -285
  7. package/dist/argus-table.js.map +1 -1
  8. package/dist/attributes.js +21 -0
  9. package/dist/attributes.js.map +1 -0
  10. package/dist/cdn/argus-table.js +120 -61
  11. package/dist/cdn/argus-table.js.map +1 -1
  12. package/dist/column-registry.js +23 -0
  13. package/dist/column-registry.js.map +1 -0
  14. package/dist/controllers/auto-width.js +16 -4
  15. package/dist/controllers/auto-width.js.map +1 -1
  16. package/dist/controllers/column-children.js +32 -9
  17. package/dist/controllers/column-children.js.map +1 -1
  18. package/dist/controllers/column-window.js +135 -0
  19. package/dist/controllers/column-window.js.map +1 -0
  20. package/dist/controllers/data-controller.js +9 -4
  21. package/dist/controllers/data-controller.js.map +1 -1
  22. package/dist/controllers/plugins.js +121 -0
  23. package/dist/controllers/plugins.js.map +1 -0
  24. package/dist/controllers/reorder-drag.js +19 -17
  25. package/dist/controllers/reorder-drag.js.map +1 -1
  26. package/dist/controllers/row-measure.js +122 -0
  27. package/dist/controllers/row-measure.js.map +1 -0
  28. package/dist/controllers/virtual-controller.js +315 -21
  29. package/dist/controllers/virtual-controller.js.map +1 -1
  30. package/dist/core/src/columns/column-groups.js +129 -0
  31. package/dist/core/src/columns/column-groups.js.map +1 -0
  32. package/dist/core/src/columns/column-order.js +125 -27
  33. package/dist/core/src/columns/column-order.js.map +1 -1
  34. package/dist/core/src/columns/resolve-columns.js +18 -5
  35. package/dist/core/src/columns/resolve-columns.js.map +1 -1
  36. package/dist/core/src/columns/spread-width.js +43 -0
  37. package/dist/core/src/columns/spread-width.js.map +1 -0
  38. package/dist/core/src/data/page-cache.js +4 -0
  39. package/dist/core/src/data/page-cache.js.map +1 -1
  40. package/dist/core/src/filters/filter.js +183 -0
  41. package/dist/core/src/filters/filter.js.map +1 -0
  42. package/dist/core/src/grid/row-layout.js +19 -11
  43. package/dist/core/src/grid/row-layout.js.map +1 -1
  44. package/dist/core/src/state/selection.js +71 -0
  45. package/dist/core/src/state/selection.js.map +1 -0
  46. package/dist/core/src/table/create-table.js +276 -66
  47. package/dist/core/src/table/create-table.js.map +1 -1
  48. package/dist/core/src/table/filtered-row-model.js +48 -0
  49. package/dist/core/src/table/filtered-row-model.js.map +1 -0
  50. package/dist/core/src/table/sorted-row-model.js +13 -2
  51. package/dist/core/src/table/sorted-row-model.js.map +1 -1
  52. package/dist/core/src/virtual/column-window.js +72 -0
  53. package/dist/core/src/virtual/column-window.js.map +1 -0
  54. package/dist/core/src/virtual/row-pool.js +2 -1
  55. package/dist/core/src/virtual/row-pool.js.map +1 -1
  56. package/dist/core/src/virtual/row-sizes.js +152 -0
  57. package/dist/core/src/virtual/row-sizes.js.map +1 -0
  58. package/dist/core/src/virtual/scroll-scale.js +41 -3
  59. package/dist/core/src/virtual/scroll-scale.js.map +1 -1
  60. package/dist/custom-elements.json +1683 -211
  61. package/dist/events.js +16 -8
  62. package/dist/events.js.map +1 -1
  63. package/dist/index.d.ts +808 -127
  64. package/dist/index.js +4 -2
  65. package/dist/interactive.js +22 -0
  66. package/dist/interactive.js.map +1 -0
  67. package/dist/max-height.js +22 -8
  68. package/dist/max-height.js.map +1 -1
  69. package/dist/render/body.js +48 -8
  70. package/dist/render/body.js.map +1 -1
  71. package/dist/render/cells.js +22 -11
  72. package/dist/render/cells.js.map +1 -1
  73. package/dist/render/content-directive.js +115 -0
  74. package/dist/render/content-directive.js.map +1 -0
  75. package/dist/render/content.js +33 -10
  76. package/dist/render/content.js.map +1 -1
  77. package/dist/render/header.js +104 -22
  78. package/dist/render/header.js.map +1 -1
  79. package/dist/render/pinned-rows.js +1 -1
  80. package/dist/render/pinned-rows.js.map +1 -1
  81. package/dist/styles/base.js +1 -1
  82. package/dist/styles/base.js.map +1 -1
  83. package/package.json +1 -1
@@ -1,14 +1,17 @@
1
- import { moveColumn, normalizeOrder } from "../columns/column-order.js";
1
+ import { cellOver, headerGroupRows, resolveColumnGroups } from "../columns/column-groups.js";
2
+ import { moveUnit, normalizeOrder, siblingUnits } from "../columns/column-order.js";
2
3
  import { resolveColumns } from "../columns/resolve-columns.js";
3
- import { sortedRowModel } from "./sorted-row-model.js";
4
- import { columnPinningFeature, columnSizingFeature, constructTable, rowSortingFeature, sortFn_alphanumeric, sortFn_basic, sortFn_datetime, sortFn_text, tableFeatures } from "@tanstack/table-core";
4
+ import { distinctValues, rowPredicate } from "../filters/filter.js";
5
+ import { filteredRowModel, setRowPredicate } from "./filtered-row-model.js";
6
+ import { sortedRowModel, valuesChanged } from "./sorted-row-model.js";
7
+ import { columnSizingFeature, constructTable, rowSortingFeature, sortFn_alphanumeric, sortFn_basic, sortFn_datetime, sortFn_text, tableFeatures } from "@tanstack/table-core";
5
8
  import { storeReactivityBindings } from "@tanstack/table-core/store-reactivity-bindings";
6
9
  // ../core/src/table/create-table.ts
7
10
  var features = tableFeatures({
8
11
  coreReactivityFeature: storeReactivityBindings(),
9
- columnPinningFeature,
10
12
  columnSizingFeature,
11
13
  rowSortingFeature,
14
+ filteredRowModel: filteredRowModel(),
12
15
  sortedRowModel: sortedRowModel(),
13
16
  sortFns: {
14
17
  alphanumeric: sortFn_alphanumeric,
@@ -17,7 +20,51 @@ var features = tableFeatures({
17
20
  text: sortFn_text
18
21
  }
19
22
  });
23
+ /**
24
+ * Id of the selection column, the checkbox column the model adds first when
25
+ * `selectionColumn` is set. Not a column of `columns`: it never appears in the
26
+ * column order, sizing or events.
27
+ */
28
+ var SELECTION_COLUMN_ID = "--argus-selection";
20
29
  var defaultRowId = (_row, index) => String(index);
30
+ /**
31
+ * Ids of the columns kept from `before` whose accessor changed: a new function,
32
+ * or a different path. A new column has nothing cached and isn't listed.
33
+ */
34
+ function changedAccessors(before, after) {
35
+ const old = new Map(before.map((c) => [c.id, c.accessor]));
36
+ return after.filter((c) => old.has(c.id) && old.get(c.id) !== c.accessor).map((c) => c.id);
37
+ }
38
+ /** The selection column's view: first, pinned to the start, fixed, and inert to sorting, sizing and moves. */
39
+ function selectionView(pinEdge) {
40
+ return {
41
+ id: SELECTION_COLUMN_ID,
42
+ kind: "selection",
43
+ colIndex: 1,
44
+ pin: "start",
45
+ offset: 0,
46
+ pinEdge,
47
+ hidden: false,
48
+ width: 40,
49
+ flex: void 0,
50
+ auto: false,
51
+ minWidth: 40,
52
+ maxWidth: 40,
53
+ sortable: false,
54
+ resizable: false,
55
+ reorderable: false,
56
+ pinnable: false,
57
+ hideable: false,
58
+ filter: void 0,
59
+ filtered: false,
60
+ align: "center",
61
+ wrap: false,
62
+ sorted: false,
63
+ header: void 0,
64
+ cell: void 0,
65
+ hasAccessor: false
66
+ };
67
+ }
21
68
  function toTanStack(column) {
22
69
  return {
23
70
  id: column.id,
@@ -30,9 +77,12 @@ function toTanStack(column) {
30
77
  };
31
78
  }
32
79
  /**
33
- * Creates the table model over TanStack Table. It owns no state: sorting, sizing and order
34
- * come in through `update()`, and `nextSorting()`, `nextSizing()` and `nextOrder()` only propose
80
+ * Creates the table model over TanStack Table. It owns no state: sorting, sizing, order,
81
+ * pinning and visibility come in through `update()`, and the `next*()` methods only propose
35
82
  * changes, so the caller decides (controlled or uncontrolled) whether to apply them.
83
+ *
84
+ * Hidden columns stay in TanStack, so their values still sort and read; only the
85
+ * views leave them out. Pin groups, sticky offsets and the order are the model's own.
36
86
  */
37
87
  function createTableModel(initial) {
38
88
  let options = initial;
@@ -40,40 +90,59 @@ function createTableModel(initial) {
40
90
  let byId = new Map(resolved.map((c) => [c.id, c]));
41
91
  let tanStackById = new Map(resolved.map((c) => [c.id, toTanStack(c)]));
42
92
  let views;
93
+ const treeOf = () => resolveColumnGroups(options.columnGroups, new Set(resolved.map((c) => c.id)));
94
+ let tree = treeOf();
95
+ let groupRows;
96
+ const pinOf = (column, pinning = options.columnPinning) => {
97
+ const state = pinning?.[column.id];
98
+ if (state === "start" || state === "end") return state;
99
+ return state === false ? void 0 : column.pin;
100
+ };
101
+ const hiddenOf = (column, visibility = options.columnVisibility) => {
102
+ const state = visibility?.[column.id];
103
+ return typeof state === "boolean" ? !state : column.hidden;
104
+ };
105
+ const shown = (id) => {
106
+ const column = byId.get(id);
107
+ return column !== void 0 && !hiddenOf(column);
108
+ };
43
109
  let sizing;
44
110
  const sizingState = () => {
45
111
  if (sizing) return sizing;
46
112
  const auto = options.autoWidths;
47
- if (!auto) return sizing = options.columnSizing;
48
113
  const merged = {};
114
+ let any = false;
49
115
  for (const column of resolved) {
50
- const px = auto[column.id];
116
+ if (column.flex !== void 0 && pinOf(column) !== void 0) {
117
+ merged[column.id] = column.pinnedWidth;
118
+ any = true;
119
+ }
120
+ const px = auto?.[column.id];
51
121
  if (!column.auto || px === void 0 || !Number.isFinite(px)) continue;
52
122
  merged[column.id] = Math.min(column.maxWidth, Math.max(column.minWidth, px));
123
+ any = true;
53
124
  }
54
- return sizing = {
125
+ return sizing = any ? {
55
126
  ...merged,
56
127
  ...options.columnSizing
57
- };
128
+ } : options.columnSizing;
58
129
  };
130
+ const orderable = () => resolved.map((c) => ({
131
+ id: c.id,
132
+ pin: pinOf(c),
133
+ reorderable: c.reorderable
134
+ }));
59
135
  let order;
60
- const orderState = () => order ??= normalizeOrder(options.columnOrder ?? [], resolved);
136
+ const orderState = () => order ??= normalizeOrder(options.columnOrder ?? [], orderable(), tree);
61
137
  const rowViews = /* @__PURE__ */ new WeakMap();
62
138
  let indexById;
63
139
  let ordered;
64
140
  const orderedColumns = () => {
65
141
  const current = orderState();
66
- if (ordered?.order !== current) {
67
- const pinOf = (id) => byId.get(id)?.pin;
68
- ordered = {
69
- order: current,
70
- columns: current.flatMap((id) => tanStackById.get(id) ?? []),
71
- pinning: {
72
- start: current.filter((id) => pinOf(id) === "start"),
73
- end: current.filter((id) => pinOf(id) === "end")
74
- }
75
- };
76
- }
142
+ if (ordered?.order !== current) ordered = {
143
+ order: current,
144
+ columns: current.flatMap((id) => tanStackById.get(id) ?? [])
145
+ };
77
146
  return ordered;
78
147
  };
79
148
  const tableOptions = () => ({
@@ -83,51 +152,94 @@ function createTableModel(initial) {
83
152
  getRowId: options.getRowId ?? defaultRowId,
84
153
  state: {
85
154
  sorting: options.sorting,
86
- columnSizing: sizingState(),
87
- columnPinning: orderedColumns().pinning
155
+ columnSizing: sizingState()
88
156
  },
89
157
  onSortingChange: () => void 0,
90
- onColumnSizingChange: () => void 0,
91
- onColumnPinningChange: () => void 0
158
+ onColumnSizingChange: () => void 0
92
159
  });
93
160
  const table = constructTable(tableOptions());
161
+ const predicateFor = (except, quick = false) => options.remote ? void 0 : rowPredicate(byId, options.columnFilters, options.quickFilter, resolved.filter((c) => c.hasAccessor && !hiddenOf(c) && !(quick && except?.has(c.id))), except);
162
+ setRowPredicate(table, predicateFor());
94
163
  const rows = () => table.getRowModel().rows;
95
164
  const pinned = (side) => options.pinnedRows?.[side] ?? [];
165
+ const widthOf = (id) => table.getColumn(id)?.getSize() ?? 0;
166
+ const view = (def, colIndex, offset, pinEdge) => {
167
+ const sort = options.sorting.find((s) => s.id === def.id);
168
+ const pin = pinOf(def);
169
+ const resized = options.columnSizing[def.id] !== void 0;
170
+ return {
171
+ id: def.id,
172
+ kind: "data",
173
+ colIndex,
174
+ pin,
175
+ offset,
176
+ pinEdge,
177
+ hidden: colIndex === 0,
178
+ width: widthOf(def.id),
179
+ flex: pin === void 0 && !resized ? def.flex : void 0,
180
+ auto: def.auto && !resized,
181
+ minWidth: def.minWidth,
182
+ maxWidth: def.maxWidth,
183
+ sortable: def.sortable,
184
+ resizable: def.resizable,
185
+ reorderable: def.reorderable,
186
+ pinnable: def.pinnable,
187
+ hideable: def.hideable,
188
+ filter: def.filter,
189
+ filtered: options.columnFilters?.[def.id] !== void 0,
190
+ align: def.align,
191
+ wrap: def.wrap,
192
+ sorted: sort ? sort.desc ? "desc" : "asc" : false,
193
+ header: def.header,
194
+ cell: def.cell,
195
+ hasAccessor: def.hasAccessor
196
+ };
197
+ };
96
198
  const buildViews = () => {
97
- const start = table.getStartLeafColumns();
98
- const center = table.getCenterLeafColumns();
99
- const end = table.getEndLeafColumns();
100
- const sorting = options.sorting;
101
- const view = (column, colIndex, offset, pinEdge) => {
102
- const def = byId.get(column.id);
103
- if (!def) throw new Error(`argus-table: unknown column '${column.id}'.`);
104
- const sort = sorting.find((s) => s.id === column.id);
105
- return {
106
- id: def.id,
107
- colIndex,
108
- pin: def.pin,
109
- offset,
110
- pinEdge,
111
- width: column.getSize(),
112
- flex: options.columnSizing[def.id] === void 0 ? def.flex : void 0,
113
- auto: def.auto && options.columnSizing[def.id] === void 0,
114
- minWidth: def.minWidth,
115
- maxWidth: def.maxWidth,
116
- sortable: def.sortable,
117
- resizable: def.resizable,
118
- reorderable: def.reorderable,
119
- align: def.align,
120
- sorted: sort ? sort.desc ? "desc" : "asc" : false,
121
- header: def.header,
122
- cell: def.cell,
123
- hasAccessor: def.hasAccessor
124
- };
199
+ const groups = {
200
+ start: [],
201
+ center: [],
202
+ end: []
125
203
  };
126
- return [
127
- ...start.map((c, i) => view(c, i + 1, c.getStart("start"), i === start.length - 1)),
128
- ...center.map((c, i) => view(c, start.length + i + 1, c.getStart("center"), false)),
129
- ...end.map((c, i) => view(c, start.length + center.length + i + 1, c.getAfter("end"), i === 0))
130
- ];
204
+ for (const id of orderState()) {
205
+ const def = byId.get(id);
206
+ if (def && !hiddenOf(def)) groups[pinOf(def) ?? "center"].push(def);
207
+ }
208
+ const { start, center, end } = groups;
209
+ const lead = options.selectionColumn ? 1 : 0;
210
+ if (lead && byId.has("--argus-selection")) throw new Error(`argus-table: the column id '${SELECTION_COLUMN_ID}' is reserved.`);
211
+ let x = lead * 40;
212
+ const list = start.map((def, i) => {
213
+ const v = view(def, lead + i + 1, x, i === start.length - 1);
214
+ x += v.width;
215
+ return v;
216
+ });
217
+ x = 0;
218
+ for (const [i, def] of center.entries()) {
219
+ const v = view(def, lead + start.length + i + 1, x, false);
220
+ list.push(v);
221
+ x += v.width;
222
+ }
223
+ const ends = [];
224
+ x = 0;
225
+ for (const [i, def] of [...end.entries()].reverse()) {
226
+ const v = view(def, lead + start.length + center.length + i + 1, x, i === 0);
227
+ ends.unshift(v);
228
+ x += v.width;
229
+ }
230
+ list.push(...ends);
231
+ if (lead) list.unshift(selectionView(start.length === 0));
232
+ return list;
233
+ };
234
+ let allViews;
235
+ const buildAllViews = (shownViews) => {
236
+ const byShownId = new Map(shownViews.map((v) => [v.id, v]));
237
+ return orderState().flatMap((id) => {
238
+ const shownView = byShownId.get(id);
239
+ if (shownView) return [shownView];
240
+ const def = byId.get(id);
241
+ return def ? [view(def, 0, 0, false)] : [];
242
+ });
131
243
  };
132
244
  return {
133
245
  update(next) {
@@ -136,28 +248,66 @@ function createTableModel(initial) {
136
248
  ...next
137
249
  };
138
250
  if (!Object.keys(next).some((key) => next[key] !== options[key])) return;
251
+ let reread = [];
139
252
  if (next.columns && next.columns !== options.columns) {
253
+ reread = changedAccessors(options.columns, next.columns);
140
254
  resolved = resolveColumns(next.columns);
141
255
  byId = new Map(resolved.map((c) => [c.id, c]));
142
256
  tanStackById = new Map(resolved.map((c) => [c.id, toTanStack(c)]));
143
257
  }
144
- if (merged.columns !== options.columns || merged.columnSizing !== options.columnSizing || merged.autoWidths !== options.autoWidths) sizing = void 0;
145
- if (merged.columns !== options.columns || merged.columnOrder !== options.columnOrder) order = void 0;
258
+ const columnsChanged = merged.columns !== options.columns;
259
+ const pinningChanged = merged.columnPinning !== options.columnPinning;
260
+ const groupsChanged = merged.columnGroups !== options.columnGroups;
261
+ if (columnsChanged || merged.columnSizing !== options.columnSizing || merged.autoWidths !== options.autoWidths || pinningChanged) sizing = void 0;
262
+ if (columnsChanged || groupsChanged || merged.columnOrder !== options.columnOrder || pinningChanged) order = void 0;
263
+ const refilter = columnsChanged || merged.columnFilters !== options.columnFilters || merged.quickFilter !== options.quickFilter || merged.columnVisibility !== options.columnVisibility || merged.remote !== options.remote;
146
264
  options = merged;
265
+ if (columnsChanged || groupsChanged) tree = treeOf();
147
266
  views = void 0;
267
+ allViews = void 0;
268
+ if (refilter) setRowPredicate(table, predicateFor());
148
269
  table.setOptions((prev) => ({
149
270
  ...prev,
150
271
  ...tableOptions()
151
272
  }));
273
+ if (reread.length && !options.remote) {
274
+ for (const row of table.getCoreRowModel().rows) for (const id of reread) Reflect.deleteProperty(row._valuesCache, id);
275
+ valuesChanged(table);
276
+ }
152
277
  },
153
278
  get columns() {
154
279
  return views ??= buildViews();
155
280
  },
281
+ get allColumns() {
282
+ return allViews ??= buildAllViews(this.columns);
283
+ },
156
284
  get rowCount() {
157
285
  return options.remote?.rowCount ?? rows().length;
158
286
  },
287
+ get rowOrder() {
288
+ return options.remote ?? rows();
289
+ },
159
290
  get totalWidth() {
160
- return table.getTotalSize();
291
+ return this.columns.reduce((sum, column) => sum + column.width, 0);
292
+ },
293
+ get headerGroups() {
294
+ const current = this.columns;
295
+ if (groupRows?.views === current && groupRows.tree === tree) return groupRows.rows;
296
+ const key = tree.groups.size ? current.map((c) => `${c.id}\u0000${String(c.pin)}\u0000${String(c.offset)}\u0000${String(c.pinEdge)}\u0000${String(c.reorderable)}\u0000${String(c.resizable)}`).join("") : "";
297
+ if (groupRows?.tree !== tree || groupRows.key !== key) groupRows = {
298
+ views: current,
299
+ tree,
300
+ key,
301
+ rows: headerGroupRows(tree, current)
302
+ };
303
+ else groupRows.views = current;
304
+ return groupRows.rows;
305
+ },
306
+ get headerRows() {
307
+ return this.headerGroups.length + 1;
308
+ },
309
+ headerCell(level, columnId) {
310
+ return cellOver(this.headerGroups, level, columnId);
161
311
  },
162
312
  rowAt(index) {
163
313
  if (options.remote) {
@@ -190,6 +340,10 @@ function createTableModel(initial) {
190
340
  };
191
341
  return indexById.map.get(rowId);
192
342
  },
343
+ selectableIds() {
344
+ if (options.remote) return options.remote.loadedIds();
345
+ return rows().map((r) => r.id);
346
+ },
193
347
  valueAt(index, columnId) {
194
348
  if (options.remote) {
195
349
  const entry = options.remote.entryAt(index);
@@ -242,10 +396,66 @@ function createTableModel(initial) {
242
396
  };
243
397
  },
244
398
  orderOf(base) {
245
- return base === void 0 ? orderState() : normalizeOrder(base, resolved);
399
+ return base === void 0 ? orderState() : normalizeOrder(base, orderable(), tree);
400
+ },
401
+ siblingUnits(unit, base) {
402
+ return siblingUnits(base ?? orderState(), orderable(), tree, unit, shown);
403
+ },
404
+ nextMove(unit, to, base) {
405
+ return moveUnit(base ?? orderState(), orderable(), tree, unit, to, shown);
406
+ },
407
+ nextPinning(columnId, pin, base = options.columnPinning) {
408
+ const column = byId.get(columnId);
409
+ if (!column?.pinnable || (pinOf(column, base) ?? false) === pin) return void 0;
410
+ return {
411
+ ...base,
412
+ [columnId]: pin
413
+ };
414
+ },
415
+ nextVisibility(columnId, hidden, base = options.columnVisibility) {
416
+ const column = byId.get(columnId);
417
+ if (!column || hiddenOf(column, base) === hidden) return void 0;
418
+ const othersShown = resolved.some((c) => c !== column && !hiddenOf(c, base));
419
+ if (hidden && (!column.hideable || !othersShown)) return void 0;
420
+ return {
421
+ ...base,
422
+ [columnId]: !hidden
423
+ };
424
+ },
425
+ nextFilters(columnId, filter, base = options.columnFilters ?? {}) {
426
+ const column = byId.get(columnId);
427
+ if (!column) return void 0;
428
+ const current = base[columnId];
429
+ if (filter === void 0) {
430
+ if (current === void 0) return void 0;
431
+ const next = { ...base };
432
+ Reflect.deleteProperty(next, columnId);
433
+ return next;
434
+ }
435
+ if (column.filter === void 0) return void 0;
436
+ if (current && JSON.stringify(current) === JSON.stringify(filter)) return void 0;
437
+ return {
438
+ ...base,
439
+ [columnId]: filter
440
+ };
441
+ },
442
+ filterValues(columnId, limit = 1e3) {
443
+ const column = byId.get(columnId);
444
+ if (!column) return void 0;
445
+ if (column.filterOptions) return {
446
+ values: [...column.filterOptions],
447
+ truncated: false
448
+ };
449
+ if (options.remote) return void 0;
450
+ const rows = table.getCoreRowModel().rows;
451
+ return distinctValues(rows, column, predicateFor(/* @__PURE__ */ new Set([columnId])), limit);
246
452
  },
247
- nextOrder(columnId, to, base) {
248
- return moveColumn(base ?? orderState(), resolved, columnId, to);
453
+ indexesPassing(except) {
454
+ if (options.remote) return void 0;
455
+ const keep = predicateFor(new Set(except), true);
456
+ const kept = [];
457
+ for (const row of table.getCoreRowModel().rows) if (!keep || keep(row.original, row.index)) kept.push(row.index);
458
+ return kept;
249
459
  },
250
460
  pinnedCount(side) {
251
461
  return pinned(side).length;
@@ -278,6 +488,6 @@ function createTableModel(initial) {
278
488
  }
279
489
  };
280
490
  }
281
- export { createTableModel };
491
+ export { SELECTION_COLUMN_ID, createTableModel };
282
492
 
283
493
  //# sourceMappingURL=create-table.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-table.js","names":[],"sources":["../../../../../core/src/table/create-table.ts"],"sourcesContent":["import {\n columnPinningFeature,\n columnSizingFeature,\n constructTable,\n rowSortingFeature,\n sortFn_alphanumeric,\n sortFn_basic,\n sortFn_datetime,\n sortFn_text,\n tableFeatures,\n type Column,\n type ColumnDef as TanStackColumnDef,\n type Row,\n type Table,\n type TableOptions,\n} from '@tanstack/table-core';\nimport { storeReactivityBindings } from '@tanstack/table-core/store-reactivity-bindings';\nimport { moveColumn, normalizeOrder } from '../columns/column-order.js';\nimport { resolveColumns, type ResolvedColumn } from '../columns/resolve-columns.js';\nimport { sortedRowModel } from './sorted-row-model.js';\nimport type {\n CellContext,\n ColumnAlign,\n ColumnDef,\n ColumnOrderState,\n ColumnPin,\n ColumnSizingState,\n PinnedRows,\n RowPin,\n SortState,\n} from '../types.js';\n\n// The TanStack adapter. Everything TanStack stays in this module: callers only see\n// the view types below, so TanStack can be upgraded or replaced without touching\n// `argus-table`'s public API.\n\nconst features = tableFeatures({\n // Vanilla (framework-free) reactivity; required by `constructTable`.\n coreReactivityFeature: storeReactivityBindings(),\n columnPinningFeature,\n columnSizingFeature,\n rowSortingFeature,\n // Our own: TanStack's is very slow in Firefox at scale (see sorted-row-model.ts).\n sortedRowModel: sortedRowModel(),\n // Registered by name so `sortFn: 'auto'` can pick one by value type.\n sortFns: {\n alphanumeric: sortFn_alphanumeric,\n basic: sortFn_basic,\n datetime: sortFn_datetime,\n text: sortFn_text,\n },\n});\ntype Features = typeof features;\ntype AnyRow = Record<string, unknown>;\n\n/** Sort direction of a column, or `false` when it isn't sorted. */\nexport type SortDirection = 'asc' | 'desc' | false;\n\n/** A column as the renderer sees it, in visual order: start-pinned, scrolling, end-pinned. */\nexport interface ColumnView<TData, TContent> {\n id: string;\n /** 1-based position in visual order, for `aria-colindex`. */\n colIndex: number;\n pin: ColumnPin | undefined;\n /**\n * Sticky inset in px: from the start edge for `'start'` columns, from the end edge\n * for `'end'` columns. For scrolling columns, the start within the scrolling area.\n */\n offset: number;\n /** `true` on the pinned column next to the scrolling area (one per pinned side). */\n pinEdge: boolean;\n /** Current width in px (a resized width wins over the column's own). */\n width: number;\n /** Share of free space, or `undefined` for a fixed width. A resized column stops flexing. */\n flex: number | undefined;\n /**\n * `true` for a `width: 'auto'` column that hasn't been resized: the table measures\n * its content and passes the width in as `autoWidths`.\n */\n auto: boolean;\n minWidth: number;\n maxWidth: number;\n sortable: boolean;\n resizable: boolean;\n reorderable: boolean;\n align: ColumnAlign;\n sorted: SortDirection;\n header: ColumnDef<TData, TContent>['header'];\n cell: ColumnDef<TData, TContent>['cell'];\n hasAccessor: boolean;\n}\n\n/** A row of the current (sorted) row model. */\nexport interface RowView<TData> {\n id: string;\n /** Index in the current row model, 0-based. */\n index: number;\n original: TData;\n}\n\n/**\n * Rows that live outside the model, loaded page by page (`dataSource`). The\n * source sorts them, so the model reads them as they are. `PageCache` implements it.\n */\nexport interface RemoteRows<TData> {\n readonly rowCount: number;\n /** The loaded row at an index, with its id; `undefined` while it isn't loaded. */\n entryAt(index: number): { id: string; row: TData } | undefined;\n /** The index of a loaded row's id, or `undefined`. */\n indexOf(rowId: string): number | undefined;\n}\n\nexport interface TableModelOptions<TData, TContent> {\n columns: readonly ColumnDef<TData, TContent>[];\n data: readonly TData[];\n /**\n * Remote rows. When set, rows come from here instead of `data`, and the model\n * doesn't sort them (the source does).\n */\n remote?: RemoteRows<TData> | undefined;\n /** Row id function. Default: the row's index in `data`, as a string. */\n getRowId: ((row: TData, index: number) => string) | undefined;\n /** Current sort state; its owner is the caller (see `controllable`). */\n sorting: SortState;\n /** Current resized widths; its owner is the caller. */\n columnSizing: ColumnSizingState;\n /**\n * Current column order; its owner is the caller. Each pin group follows it; an\n * empty array (the default) keeps the order of `columns`.\n */\n columnOrder?: ColumnOrderState | undefined;\n /**\n * Measured widths of `width: 'auto'` columns, in px by id. Clamped to the column's\n * bounds; a resized width wins. Ids of other columns are ignored.\n */\n autoWidths?: ColumnSizingState | undefined;\n /** Rows fixed above or below the body. They stay out of the row model: never sorted, not counted. */\n pinnedRows?: PinnedRows<TData> | undefined;\n}\n\nexport interface TableModel<TData, TContent> {\n /** Updates any subset of the options. Unchanged references are ignored. */\n update(options: Partial<TableModelOptions<TData, TContent>>): void;\n /** Columns in visual order. */\n readonly columns: readonly ColumnView<TData, TContent>[];\n /** Number of rows in the current row model. */\n readonly rowCount: number;\n /** Sum of all column widths in px (flex columns count their minimum). */\n readonly totalWidth: number;\n /** The row at an index of the current row model; `undefined` for a remote row not loaded yet. */\n rowAt(index: number): RowView<TData> | undefined;\n /** The index of a row id in the current row model (after sorting), or `undefined`. */\n indexOf(rowId: string): number | undefined;\n /** The value a column reads from the row at `index`. */\n valueAt(index: number, columnId: string): unknown;\n /** What a column's `cell` function receives for the row at `index`. */\n cellContext(index: number, columnId: string): CellContext<TData> | undefined;\n /**\n * The sort state that clicking this column's header would produce:\n * asc → desc → unsorted, one column at a time. `undefined` if it can't sort.\n */\n nextSorting(columnId: string): SortState | undefined;\n /**\n * The sizing state after setting a column to `width` px, clamped to its bounds.\n * `undefined` if the column can't be resized.\n */\n nextSizing(columnId: string, width: number): ColumnSizingState | undefined;\n /**\n * The full column order as the table shows it: start-pinned, scrolling and\n * end-pinned ids. `base` defaults to the current `columnOrder`.\n */\n orderOf(base?: readonly string[]): ColumnOrderState;\n /**\n * The order after moving a column to position `to` (0-based, in the whole order,\n * counted after the move), starting from `base` (default: the current order).\n * `undefined` if the column can't move, `to` is outside its pin group, or nothing changes.\n */\n nextOrder(columnId: string, to: number, base?: readonly string[]): ColumnOrderState | undefined;\n /** Number of rows pinned to a side. */\n pinnedCount(side: RowPin): number;\n /**\n * A pinned row, `index` counted within its side. Its id comes from `getRowId`,\n * else it is `'top-{index}'` or `'bottom-{index}'`, apart from the data rows' index ids.\n */\n pinnedRowAt(side: RowPin, index: number): RowView<TData> | undefined;\n /** The value a column reads from a pinned row. */\n pinnedValueAt(side: RowPin, index: number, columnId: string): unknown;\n /** What a column's `cell` function receives for a pinned row (with `pinned` set). */\n pinnedCellContext(side: RowPin, index: number, columnId: string): CellContext<TData> | undefined;\n}\n\nconst defaultRowId = (_row: unknown, index: number) => String(index);\n\nfunction toTanStack<TData, TContent>(\n column: ResolvedColumn<TData, TContent>,\n): TanStackColumnDef<Features, AnyRow> {\n return {\n id: column.id,\n accessorFn: column.getValue as (row: AnyRow, index: number) => unknown,\n size: column.width,\n minSize: column.minWidth,\n maxSize: column.maxWidth,\n enableSorting: column.sortable,\n sortUndefined: 'last',\n };\n}\n\n/**\n * Creates the table model over TanStack Table. It owns no state: sorting, sizing and order\n * come in through `update()`, and `nextSorting()`, `nextSizing()` and `nextOrder()` only propose\n * changes, so the caller decides (controlled or uncontrolled) whether to apply them.\n */\nexport function createTableModel<TData, TContent>(\n initial: TableModelOptions<TData, TContent>,\n): TableModel<TData, TContent> {\n let options = initial;\n let resolved = resolveColumns(options.columns);\n let byId = new Map(resolved.map((c) => [c.id, c]));\n // TanStack column defs by id, kept between updates that don't change `columns`.\n let tanStackById = new Map(resolved.map((c) => [c.id, toTanStack(c)]));\n let views: ColumnView<TData, TContent>[] | undefined;\n // TanStack's sizing state: measured auto widths under the resized ones. Kept stable\n // between updates that don't touch either.\n let sizing: ColumnSizingState | undefined;\n const sizingState = (): ColumnSizingState => {\n if (sizing) return sizing;\n const auto = options.autoWidths;\n if (!auto) return (sizing = options.columnSizing);\n const merged: ColumnSizingState = {};\n for (const column of resolved) {\n const px = auto[column.id];\n if (!column.auto || px === undefined || !Number.isFinite(px)) continue;\n merged[column.id] = Math.min(column.maxWidth, Math.max(column.minWidth, px));\n }\n return (sizing = { ...merged, ...options.columnSizing });\n };\n // The normalized order, kept stable between updates that touch neither columns nor order.\n let order: ColumnOrderState | undefined;\n const orderState = (): ColumnOrderState =>\n (order ??= normalizeOrder(options.columnOrder ?? [], resolved));\n const rowViews = new WeakMap<Row<Features, AnyRow>, RowView<TData>>();\n // Built lazily per row model (sorting or new data gives a new array).\n let indexById: { rows: readonly Row<Features, AnyRow>[]; map: Map<string, number> } | undefined;\n\n // The order reaches TanStack as the order of its column defs (the scrolling\n // columns follow it) and of the pinning arrays (the pinned ones do). Rebuilt only\n // when the order changes: a new columns array makes TanStack rebuild its columns,\n // though not its row models, which depend on data and sorting alone.\n let ordered:\n | {\n order: ColumnOrderState;\n columns: TanStackColumnDef<Features, AnyRow>[];\n pinning: { start: string[]; end: string[] };\n }\n | undefined;\n const orderedColumns = () => {\n const current = orderState();\n if (ordered?.order !== current) {\n const pinOf = (id: string) => byId.get(id)?.pin;\n ordered = {\n order: current,\n columns: current.flatMap((id) => tanStackById.get(id) ?? []),\n pinning: {\n start: current.filter((id) => pinOf(id) === 'start'),\n end: current.filter((id) => pinOf(id) === 'end'),\n },\n };\n }\n return ordered;\n };\n\n const tableOptions = (): TableOptions<Features, AnyRow> => ({\n features,\n columns: orderedColumns().columns,\n // Remote rows bypass TanStack's row models; it still handles columns and state.\n data: (options.remote ? [] : options.data) as AnyRow[],\n getRowId: (options.getRowId ?? defaultRowId) as (row: AnyRow, index: number) => string,\n state: {\n sorting: options.sorting,\n columnSizing: sizingState(),\n columnPinning: orderedColumns().pinning,\n },\n // State is owned by the caller; TanStack's own setters must not change it.\n onSortingChange: () => undefined,\n onColumnSizingChange: () => undefined,\n onColumnPinningChange: () => undefined,\n });\n\n const table: Table<Features, AnyRow> = constructTable(tableOptions());\n\n const rows = () => table.getRowModel().rows;\n const pinned = (side: RowPin): readonly TData[] => options.pinnedRows?.[side] ?? [];\n\n const buildViews = (): ColumnView<TData, TContent>[] => {\n const start = table.getStartLeafColumns();\n const center = table.getCenterLeafColumns();\n const end = table.getEndLeafColumns();\n const sorting = options.sorting;\n const view = (\n column: Column<Features, AnyRow>,\n colIndex: number,\n offset: number,\n pinEdge: boolean,\n ): ColumnView<TData, TContent> => {\n const def = byId.get(column.id);\n if (!def) throw new Error(`argus-table: unknown column '${column.id}'.`);\n const sort = sorting.find((s) => s.id === column.id);\n return {\n id: def.id,\n colIndex,\n pin: def.pin,\n offset,\n pinEdge,\n width: column.getSize(),\n flex: options.columnSizing[def.id] === undefined ? def.flex : undefined,\n auto: def.auto && options.columnSizing[def.id] === undefined,\n minWidth: def.minWidth,\n maxWidth: def.maxWidth,\n sortable: def.sortable,\n resizable: def.resizable,\n reorderable: def.reorderable,\n align: def.align,\n sorted: sort ? (sort.desc ? 'desc' : 'asc') : false,\n header: def.header,\n cell: def.cell,\n hasAccessor: def.hasAccessor,\n };\n };\n return [\n ...start.map((c, i) => view(c, i + 1, c.getStart('start'), i === start.length - 1)),\n ...center.map((c, i) => view(c, start.length + i + 1, c.getStart('center'), false)),\n ...end.map((c, i) =>\n view(c, start.length + center.length + i + 1, c.getAfter('end'), i === 0),\n ),\n ];\n };\n\n return {\n update(next) {\n const merged = { ...options, ...next };\n const changed = (Object.keys(next) as (keyof typeof next)[]).some(\n (key) => next[key] !== options[key],\n );\n if (!changed) return;\n if (next.columns && next.columns !== options.columns) {\n resolved = resolveColumns(next.columns);\n byId = new Map(resolved.map((c) => [c.id, c]));\n tanStackById = new Map(resolved.map((c) => [c.id, toTanStack(c)]));\n }\n if (\n merged.columns !== options.columns ||\n merged.columnSizing !== options.columnSizing ||\n merged.autoWidths !== options.autoWidths\n ) {\n sizing = undefined;\n }\n if (merged.columns !== options.columns || merged.columnOrder !== options.columnOrder) {\n order = undefined;\n }\n options = merged;\n views = undefined;\n table.setOptions((prev) => ({ ...prev, ...tableOptions() }));\n },\n\n get columns() {\n return (views ??= buildViews());\n },\n\n get rowCount() {\n return options.remote?.rowCount ?? rows().length;\n },\n\n get totalWidth() {\n return table.getTotalSize();\n },\n\n rowAt(index) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n return entry && { id: entry.id, index, original: entry.row };\n }\n const row = rows()[index];\n if (!row) return undefined;\n let view = rowViews.get(row);\n if (view?.index !== index) {\n view = { id: row.id, index, original: row.original as TData };\n rowViews.set(row, view);\n }\n return view;\n },\n\n indexOf(rowId) {\n if (options.remote) return options.remote.indexOf(rowId);\n const current = rows();\n if (indexById?.rows !== current) {\n indexById = { rows: current, map: new Map(current.map((r, i) => [r.id, i])) };\n }\n return indexById.map.get(rowId);\n },\n\n valueAt(index, columnId) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n return entry && byId.get(columnId)?.getValue(entry.row, index);\n }\n return rows()[index]?.getValue(columnId);\n },\n\n cellContext(index, columnId) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n const column = byId.get(columnId);\n if (!entry || !column) return undefined;\n return {\n row: entry.row,\n rowId: entry.id,\n index,\n columnId,\n value: column.getValue(entry.row, index),\n };\n }\n const row = rows()[index];\n if (!row || !byId.has(columnId)) return undefined;\n return {\n row: row.original as TData,\n rowId: row.id,\n index,\n columnId,\n value: row.getValue(columnId),\n };\n },\n\n nextSorting(columnId) {\n if (byId.get(columnId)?.sortable !== true) return undefined;\n const current = options.sorting.find((s) => s.id === columnId);\n if (!current) return [{ id: columnId, desc: false }];\n return current.desc ? [] : [{ id: columnId, desc: true }];\n },\n\n nextSizing(columnId, width) {\n const column = byId.get(columnId);\n if (!column?.resizable || !Number.isFinite(width)) return undefined;\n const clamped = Math.round(Math.min(column.maxWidth, Math.max(column.minWidth, width)));\n return { ...options.columnSizing, [columnId]: clamped };\n },\n\n orderOf(base) {\n return base === undefined ? orderState() : normalizeOrder(base, resolved);\n },\n\n nextOrder(columnId, to, base) {\n return moveColumn(base ?? orderState(), resolved, columnId, to);\n },\n\n pinnedCount(side) {\n return pinned(side).length;\n },\n\n pinnedRowAt(side, index) {\n if (index < 0 || index >= pinned(side).length) return undefined;\n const row = pinned(side)[index] as TData;\n const id = options.getRowId ? options.getRowId(row, index) : `${side}-${String(index)}`;\n return { id, index, original: row };\n },\n\n pinnedValueAt(side, index, columnId) {\n if (index < 0 || index >= pinned(side).length) return undefined;\n return byId.get(columnId)?.getValue(pinned(side)[index] as TData, index);\n },\n\n pinnedCellContext(side, index, columnId) {\n const row = this.pinnedRowAt(side, index);\n const column = byId.get(columnId);\n if (!row || !column) return undefined;\n return {\n row: row.original,\n rowId: row.id,\n index,\n columnId,\n value: column.getValue(row.original, index),\n pinned: side,\n };\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"create-table.js","names":[],"sources":["../../../../../core/src/table/create-table.ts"],"sourcesContent":["import {\n columnSizingFeature,\n constructTable,\n rowSortingFeature,\n sortFn_alphanumeric,\n sortFn_basic,\n sortFn_datetime,\n sortFn_text,\n tableFeatures,\n type ColumnDef as TanStackColumnDef,\n type Row,\n type Table,\n type TableOptions,\n} from '@tanstack/table-core';\nimport { storeReactivityBindings } from '@tanstack/table-core/store-reactivity-bindings';\nimport {\n cellOver,\n headerGroupRows,\n resolveColumnGroups,\n type GroupTree,\n type HeaderGroupCell,\n} from '../columns/column-groups.js';\nimport {\n moveUnit,\n normalizeOrder,\n siblingUnits,\n type OrderUnit,\n type SiblingUnit,\n} from '../columns/column-order.js';\nimport { resolveColumns, type ResolvedColumn } from '../columns/resolve-columns.js';\nimport { distinctValues, rowPredicate } from '../filters/filter.js';\nimport { filteredRowModel, setRowPredicate } from './filtered-row-model.js';\nimport { sortedRowModel, valuesChanged } from './sorted-row-model.js';\nimport type {\n CellContext,\n ColumnAlign,\n ColumnDef,\n ColumnGroup,\n ColumnFilter,\n ColumnFilterState,\n ColumnOrderState,\n ColumnPin,\n ColumnPinningState,\n ColumnSizingState,\n ColumnVisibilityState,\n FilterKind,\n FilterValue,\n PinnedRows,\n RowPin,\n SortItem,\n SortState,\n} from '../types.js';\n\n// The TanStack adapter. Everything TanStack stays in this module: callers only see\n// the view types below, so TanStack can be upgraded or replaced without touching\n// `argus-table`'s public API.\n\nconst features = tableFeatures({\n // Vanilla (framework-free) reactivity; required by `constructTable`.\n coreReactivityFeature: storeReactivityBindings(),\n // No pinning, ordering or visibility feature: the model groups, orders and hides\n // columns itself (see `buildViews`), so they cost no bundle size.\n columnSizingFeature,\n rowSortingFeature,\n // Our own filtering, without TanStack's filtering feature (see filtered-row-model.ts).\n // TanStack's types tie this slot to that feature; at runtime the core row models read it.\n ...({ filteredRowModel: filteredRowModel() } as object),\n // Our own: TanStack's is very slow in Firefox at scale (see sorted-row-model.ts).\n sortedRowModel: sortedRowModel(),\n // Registered by name so `sortFn: 'auto'` can pick one by value type.\n sortFns: {\n alphanumeric: sortFn_alphanumeric,\n basic: sortFn_basic,\n datetime: sortFn_datetime,\n text: sortFn_text,\n },\n});\ntype Features = typeof features;\ntype AnyRow = Record<string, unknown>;\n\n/** Sort direction of a column, or `false` when it isn't sorted. */\nexport type SortDirection = 'asc' | 'desc' | false;\n\n/**\n * Id of the selection column, the checkbox column the model adds first when\n * `selectionColumn` is set. Not a column of `columns`: it never appears in the\n * column order, sizing or events.\n */\nexport const SELECTION_COLUMN_ID = '--argus-selection';\n\n/** Width of the selection column in px. */\nexport const SELECTION_COLUMN_WIDTH = 40;\n\n/** A column as the renderer sees it, in visual order: start-pinned, scrolling, end-pinned. */\nexport interface ColumnView<TData, TContent> {\n id: string;\n /** `'data'` for a column of `columns`; `'selection'` for the checkbox column. */\n kind: 'data' | 'selection';\n /** 1-based position in visual order, for `aria-colindex`. `0` for a hidden column. */\n colIndex: number;\n /** The pin in effect: `columnPinning`'s, else the column's own. */\n pin: ColumnPin | undefined;\n /**\n * Sticky inset in px: from the start edge for `'start'` columns, from the end edge\n * for `'end'` columns. For scrolling columns, the start within the scrolling area.\n */\n offset: number;\n /** `true` on the pinned column next to the scrolling area (one per pinned side). */\n pinEdge: boolean;\n /**\n * `true` for a hidden column. Only `allColumns` lists hidden columns; `columns`\n * holds the ones the table shows.\n */\n hidden: boolean;\n /** Current width in px (a resized width wins over the column's own). */\n width: number;\n /** Share of free space, or `undefined` for a fixed width. A resized column stops flexing. */\n flex: number | undefined;\n /**\n * `true` for a `width: 'auto'` column that hasn't been resized: the table measures\n * its content and passes the width in as `autoWidths`.\n */\n auto: boolean;\n minWidth: number;\n maxWidth: number;\n sortable: boolean;\n resizable: boolean;\n reorderable: boolean;\n pinnable: boolean;\n hideable: boolean;\n /** The kind of filter users can set, or `undefined` when they can't filter the column. */\n filter: FilterKind | undefined;\n /** `true` when `columnFilters` has a filter for the column. */\n filtered: boolean;\n align: ColumnAlign;\n /** Whether the cell text wraps (`ColumnDef.wrap`). */\n wrap: boolean;\n sorted: SortDirection;\n header: ColumnDef<TData, TContent>['header'];\n cell: ColumnDef<TData, TContent>['cell'];\n hasAccessor: boolean;\n}\n\n/** A row of the current (filtered and sorted) row model. */\nexport interface RowView<TData> {\n id: string;\n /** Index in the current row model, 0-based. */\n index: number;\n original: TData;\n}\n\n/**\n * Rows that live outside the model, loaded page by page (`dataSource`). The\n * source sorts them, so the model reads them as they are. `PageCache` implements it.\n */\nexport interface RemoteRows<TData> {\n readonly rowCount: number;\n /** The loaded row at an index, with its id; `undefined` while it isn't loaded. */\n entryAt(index: number): { id: string; row: TData } | undefined;\n /** The index of a loaded row's id, or `undefined`. */\n indexOf(rowId: string): number | undefined;\n /** The ids of every loaded row, in row order. */\n loadedIds(): string[];\n}\n\nexport interface TableModelOptions<TData, TContent> {\n columns: readonly ColumnDef<TData, TContent>[];\n /**\n * Headers over several columns, nested to any depth. Their columns stay next to\n * each other in the order, and each level adds a header row.\n */\n columnGroups?: readonly ColumnGroup<TContent>[] | undefined;\n data: readonly TData[];\n /**\n * Remote rows. When set, rows come from here instead of `data`, and the model\n * doesn't sort them (the source does).\n */\n remote?: RemoteRows<TData> | undefined;\n /** Row id function. Default: the row's index in `data`, as a string. */\n getRowId: ((row: TData, index: number) => string) | undefined;\n /** Current sort state; its owner is the caller (see `controllable`). */\n sorting: SortState;\n /** Current resized widths; its owner is the caller. */\n columnSizing: ColumnSizingState;\n /**\n * Current column order; its owner is the caller. Each pin group follows it; an\n * empty array (the default) keeps the order of `columns`.\n */\n columnOrder?: ColumnOrderState | undefined;\n /** Pins set at runtime, over the columns' own `pin`; its owner is the caller. */\n columnPinning?: ColumnPinningState | undefined;\n /** Visibility set at runtime, over the columns' own `hidden`; its owner is the caller. */\n columnVisibility?: ColumnVisibilityState | undefined;\n /**\n * Column filters; its owner is the caller. Rows that fail one leave the row model.\n * Remote rows aren't filtered: the source does it.\n */\n columnFilters?: ColumnFilterState | undefined;\n /**\n * Words to find in the shown columns' values as text, ignoring case: a row stays\n * when each word is in one of its values. Remote rows aren't filtered.\n */\n quickFilter?: string | undefined;\n /**\n * Measured widths of `width: 'auto'` columns, in px by id. Clamped to the column's\n * bounds; a resized width wins. Ids of other columns are ignored.\n */\n autoWidths?: ColumnSizingState | undefined;\n /** Rows fixed above or below the body. They stay out of the row model: never sorted, not counted. */\n pinnedRows?: PinnedRows<TData> | undefined;\n /**\n * Adds the selection (checkbox) column first among the start-pinned columns. It\n * has the id `SELECTION_COLUMN_ID`, a fixed width, and no part in sorting,\n * sizing or the column order.\n */\n selectionColumn?: boolean | undefined;\n}\n\nexport interface TableModel<TData, TContent> {\n /** Updates any subset of the options. Unchanged references are ignored. */\n update(options: Partial<TableModelOptions<TData, TContent>>): void;\n /** The columns the table shows, in visual order. */\n readonly columns: readonly ColumnView<TData, TContent>[];\n /**\n * Every column of `columns`, hidden ones included (with `hidden: true` and\n * `colIndex: 0`), in the order of `orderOf()`. Not the selection column.\n */\n readonly allColumns: readonly ColumnView<TData, TContent>[];\n /** Number of rows in the current row model. */\n readonly rowCount: number;\n /**\n * Changes identity whenever the row at an index may have changed: new data, a\n * sort, a filter, a new remote source. Compare it by identity only.\n */\n readonly rowOrder: object;\n /** Sum of the shown columns' widths in px (flex columns count their minimum). */\n readonly totalWidth: number;\n /**\n * The group header rows over `columns`, top row first; empty without column groups.\n * Keeps its identity while `columns` does.\n */\n readonly headerGroups: readonly (readonly HeaderGroupCell<TContent>[])[];\n /** Number of header rows: the group rows and the row of column headers. */\n readonly headerRows: number;\n /** The cell of group header row `level` over a column, or `undefined`. */\n headerCell(level: number, columnId: string): HeaderGroupCell<TContent> | undefined;\n /** The row at an index of the current row model; `undefined` for a remote row not loaded yet. */\n rowAt(index: number): RowView<TData> | undefined;\n /** The index of a row id in the current row model (after filtering and sorting), or `undefined`. */\n indexOf(rowId: string): number | undefined;\n /**\n * The ids of the rows that can be selected, in row order: every row of the row\n * model, or only the loaded ones for remote rows.\n */\n selectableIds(): string[];\n /** The value a column reads from the row at `index`. */\n valueAt(index: number, columnId: string): unknown;\n /** What a column's `cell` function receives for the row at `index`. */\n cellContext(index: number, columnId: string): CellContext<TData> | undefined;\n /**\n * The sort state that clicking this column's header would produce:\n * asc → desc → unsorted, one column at a time. `undefined` if it can't sort.\n */\n nextSorting(columnId: string): SortState | undefined;\n /**\n * The sizing state after setting a column to `width` px, clamped to its bounds.\n * `undefined` if the column can't be resized.\n */\n nextSizing(columnId: string, width: number): ColumnSizingState | undefined;\n /**\n * The full column order as the table shows it: start-pinned, scrolling and\n * end-pinned ids. `base` defaults to the current `columnOrder`.\n */\n orderOf(base?: readonly string[]): ColumnOrderState;\n /**\n * The units a column or group moves among: the shown columns and groups with the\n * same parent group on the same pin side, in visual order, starting from `base`\n * (default: the current order). Empty if the unit isn't shown.\n */\n siblingUnits(unit: OrderUnit, base?: readonly string[]): SiblingUnit[];\n /**\n * The order after moving a column or group to position `to` among its sibling\n * units (0-based, counted after the move; hidden columns keep their place),\n * starting from `base` (default: the current order). `undefined` if it can't\n * move or is hidden, `to` is out of range, or nothing changes.\n */\n nextMove(unit: OrderUnit, to: number, base?: readonly string[]): ColumnOrderState | undefined;\n /**\n * The pinning state after pinning a column to a side, or unpinning it with `false`,\n * starting from `base` (default: the current `columnPinning`). `undefined` for an\n * unknown column, one with `pinnable: false`, or no change.\n */\n nextPinning(\n columnId: string,\n pin: ColumnPin | false,\n base?: ColumnPinningState,\n ): ColumnPinningState | undefined;\n /**\n * The visibility state after hiding or showing a column, starting from `base`\n * (default: the current `columnVisibility`). `undefined` for an unknown column,\n * hiding one with `hideable: false` or the last one shown, or no change.\n */\n nextVisibility(\n columnId: string,\n hidden: boolean,\n base?: ColumnVisibilityState,\n ): ColumnVisibilityState | undefined;\n /**\n * The filter state after setting a column's filter, or clearing it with `undefined`,\n * starting from `base` (default: the current `columnFilters`). `undefined` for an\n * unknown column, setting a filter on a column without `filter`, or no change.\n */\n nextFilters(\n columnId: string,\n filter: ColumnFilter | undefined,\n base?: ColumnFilterState,\n ): ColumnFilterState | undefined;\n /**\n * The values a `'set'` filter on the column offers: its `filterOptions`, else (not for\n * remote rows) the distinct values of the rows the other filters keep, sorted, at most\n * `limit` of them (`truncated` when there are more). `undefined` for an unknown column,\n * or remote rows without `filterOptions`.\n */\n filterValues(\n columnId: string,\n limit?: number,\n ): { values: FilterValue[]; truncated: boolean } | undefined;\n /**\n * The indexes in `data` of the rows the column filters and the quick filter keep,\n * ascending (not sorted), leaving out the filters on the `except` columns and their\n * text in the quick filter. `undefined` for remote rows. Reads only the core rows\n * and the other columns' accessors, so an accessor of an `except` column can call it\n * while the model filters or sorts.\n */\n indexesPassing(except?: Iterable<string>): readonly number[] | undefined;\n /** Number of rows pinned to a side. */\n pinnedCount(side: RowPin): number;\n /**\n * A pinned row, `index` counted within its side. Its id comes from `getRowId`,\n * else it is `'top-{index}'` or `'bottom-{index}'`, apart from the data rows' index ids.\n */\n pinnedRowAt(side: RowPin, index: number): RowView<TData> | undefined;\n /** The value a column reads from a pinned row. */\n pinnedValueAt(side: RowPin, index: number, columnId: string): unknown;\n /** What a column's `cell` function receives for a pinned row (with `pinned` set). */\n pinnedCellContext(side: RowPin, index: number, columnId: string): CellContext<TData> | undefined;\n}\n\nconst defaultRowId = (_row: unknown, index: number) => String(index);\n\n/**\n * Ids of the columns kept from `before` whose accessor changed: a new function,\n * or a different path. A new column has nothing cached and isn't listed.\n */\nfunction changedAccessors<TData, TContent>(\n before: readonly ColumnDef<TData, TContent>[],\n after: readonly ColumnDef<TData, TContent>[],\n): string[] {\n const old = new Map(before.map((c) => [c.id, c.accessor]));\n return after.filter((c) => old.has(c.id) && old.get(c.id) !== c.accessor).map((c) => c.id);\n}\n\n/** The selection column's view: first, pinned to the start, fixed, and inert to sorting, sizing and moves. */\nfunction selectionView<TData, TContent>(pinEdge: boolean): ColumnView<TData, TContent> {\n return {\n id: SELECTION_COLUMN_ID,\n kind: 'selection',\n colIndex: 1,\n pin: 'start',\n offset: 0,\n pinEdge,\n hidden: false,\n width: SELECTION_COLUMN_WIDTH,\n flex: undefined,\n auto: false,\n minWidth: SELECTION_COLUMN_WIDTH,\n maxWidth: SELECTION_COLUMN_WIDTH,\n sortable: false,\n resizable: false,\n reorderable: false,\n pinnable: false,\n hideable: false,\n filter: undefined,\n filtered: false,\n align: 'center',\n wrap: false,\n sorted: false,\n header: undefined,\n cell: undefined,\n hasAccessor: false,\n };\n}\n\nfunction toTanStack<TData, TContent>(\n column: ResolvedColumn<TData, TContent>,\n): TanStackColumnDef<Features, AnyRow> {\n return {\n id: column.id,\n accessorFn: column.getValue as (row: AnyRow, index: number) => unknown,\n size: column.width,\n minSize: column.minWidth,\n maxSize: column.maxWidth,\n enableSorting: column.sortable,\n sortUndefined: 'last',\n };\n}\n\n/**\n * Creates the table model over TanStack Table. It owns no state: sorting, sizing, order,\n * pinning and visibility come in through `update()`, and the `next*()` methods only propose\n * changes, so the caller decides (controlled or uncontrolled) whether to apply them.\n *\n * Hidden columns stay in TanStack, so their values still sort and read; only the\n * views leave them out. Pin groups, sticky offsets and the order are the model's own.\n */\nexport function createTableModel<TData, TContent>(\n initial: TableModelOptions<TData, TContent>,\n): TableModel<TData, TContent> {\n let options = initial;\n let resolved = resolveColumns(options.columns);\n let byId = new Map(resolved.map((c) => [c.id, c]));\n // TanStack column defs by id, kept between updates that don't change `columns`.\n let tanStackById = new Map(resolved.map((c) => [c.id, toTanStack(c)]));\n let views: ColumnView<TData, TContent>[] | undefined;\n const treeOf = () =>\n resolveColumnGroups(options.columnGroups, new Set(resolved.map((c) => c.id)));\n let tree: GroupTree<TContent> = treeOf();\n // The group header rows, kept while the tree and what they read of the views stay.\n let groupRows:\n | {\n views: readonly ColumnView<TData, TContent>[];\n tree: GroupTree<TContent>;\n key: string;\n rows: HeaderGroupCell<TContent>[][];\n }\n | undefined;\n // The pin and visibility in effect: the state's, else the column's own.\n const pinOf = (\n column: ResolvedColumn<TData, TContent>,\n pinning = options.columnPinning,\n ): ColumnPin | undefined => {\n const state = pinning?.[column.id];\n if (state === 'start' || state === 'end') return state;\n return state === false ? undefined : column.pin;\n };\n const hiddenOf = (\n column: ResolvedColumn<TData, TContent>,\n visibility = options.columnVisibility,\n ): boolean => {\n const state = visibility?.[column.id];\n return typeof state === 'boolean' ? !state : column.hidden;\n };\n const shown = (id: string) => {\n const column = byId.get(id);\n return column !== undefined && !hiddenOf(column);\n };\n // TanStack's sizing state: measured auto widths and the widths of pinned flex columns\n // under the resized ones. Kept stable between updates that don't touch them.\n let sizing: ColumnSizingState | undefined;\n const sizingState = (): ColumnSizingState => {\n if (sizing) return sizing;\n const auto = options.autoWidths;\n const merged: ColumnSizingState = {};\n let any = false;\n for (const column of resolved) {\n // A pinned column can't flex: it takes a fixed width for its sticky offsets.\n if (column.flex !== undefined && pinOf(column) !== undefined) {\n merged[column.id] = column.pinnedWidth;\n any = true;\n }\n const px = auto?.[column.id];\n if (!column.auto || px === undefined || !Number.isFinite(px)) continue;\n merged[column.id] = Math.min(column.maxWidth, Math.max(column.minWidth, px));\n any = true;\n }\n return (sizing = any ? { ...merged, ...options.columnSizing } : options.columnSizing);\n };\n // What ordering needs, with the pin in effect.\n const orderable = () =>\n resolved.map((c) => ({ id: c.id, pin: pinOf(c), reorderable: c.reorderable }));\n // The normalized order, kept stable between updates that touch neither columns,\n // order nor pinning.\n let order: ColumnOrderState | undefined;\n const orderState = (): ColumnOrderState =>\n (order ??= normalizeOrder(options.columnOrder ?? [], orderable(), tree));\n const rowViews = new WeakMap<Row<Features, AnyRow>, RowView<TData>>();\n // Built lazily per row model (sorting or new data gives a new array).\n let indexById: { rows: readonly Row<Features, AnyRow>[]; map: Map<string, number> } | undefined;\n\n // TanStack gets its column defs in the order, hidden ones included. Rebuilt only when\n // the order changes: a new columns array makes TanStack rebuild its columns, though\n // not its row models, which depend on data and sorting alone.\n let ordered:\n { order: ColumnOrderState; columns: TanStackColumnDef<Features, AnyRow>[] } | undefined;\n const orderedColumns = () => {\n const current = orderState();\n if (ordered?.order !== current) {\n ordered = { order: current, columns: current.flatMap((id) => tanStackById.get(id) ?? []) };\n }\n return ordered;\n };\n\n const tableOptions = (): TableOptions<Features, AnyRow> => ({\n features,\n columns: orderedColumns().columns,\n // Remote rows bypass TanStack's row models; it still handles columns and state.\n data: (options.remote ? [] : options.data) as AnyRow[],\n getRowId: (options.getRowId ?? defaultRowId) as (row: AnyRow, index: number) => string,\n state: {\n // TanStack's type is mutable; it never changes the array.\n sorting: options.sorting as SortItem[],\n columnSizing: sizingState(),\n },\n // State is owned by the caller; TanStack's own setters must not change it.\n onSortingChange: () => undefined,\n onColumnSizingChange: () => undefined,\n });\n\n const table: Table<Features, AnyRow> = constructTable(tableOptions());\n\n // The row test of the filters, the quick filter and the shown columns (which the quick\n // filter reads). Remote rows are filtered by their source.\n // `except`: columns whose filter is left out; with `quick`, their text is left out\n // of the quick filter too.\n const predicateFor = (except?: ReadonlySet<string>, quick = false) =>\n options.remote\n ? undefined\n : rowPredicate(\n byId,\n options.columnFilters,\n options.quickFilter,\n resolved.filter((c) => c.hasAccessor && !hiddenOf(c) && !(quick && except?.has(c.id))),\n except,\n );\n setRowPredicate(table, predicateFor());\n\n const rows = () => table.getRowModel().rows;\n const pinned = (side: RowPin): readonly TData[] => options.pinnedRows?.[side] ?? [];\n\n const widthOf = (id: string) => table.getColumn(id)?.getSize() ?? 0;\n const view = (\n def: ResolvedColumn<TData, TContent>,\n colIndex: number,\n offset: number,\n pinEdge: boolean,\n ): ColumnView<TData, TContent> => {\n const sort = options.sorting.find((s) => s.id === def.id);\n const pin = pinOf(def);\n const resized = options.columnSizing[def.id] !== undefined;\n return {\n id: def.id,\n kind: 'data',\n colIndex,\n pin,\n offset,\n pinEdge,\n hidden: colIndex === 0,\n width: widthOf(def.id),\n flex: pin === undefined && !resized ? def.flex : undefined,\n auto: def.auto && !resized,\n minWidth: def.minWidth,\n maxWidth: def.maxWidth,\n sortable: def.sortable,\n resizable: def.resizable,\n reorderable: def.reorderable,\n pinnable: def.pinnable,\n hideable: def.hideable,\n filter: def.filter,\n filtered: options.columnFilters?.[def.id] !== undefined,\n align: def.align,\n wrap: def.wrap,\n sorted: sort ? (sort.desc ? 'desc' : 'asc') : false,\n header: def.header,\n cell: def.cell,\n hasAccessor: def.hasAccessor,\n };\n };\n\n const buildViews = (): ColumnView<TData, TContent>[] => {\n const groups: Record<ColumnPin | 'center', ResolvedColumn<TData, TContent>[]> = {\n start: [],\n center: [],\n end: [],\n };\n for (const id of orderState()) {\n const def = byId.get(id);\n if (def && !hiddenOf(def)) groups[pinOf(def) ?? 'center'].push(def);\n }\n const { start, center, end } = groups;\n // The selection column comes first: it shifts every column one place on, and\n // the other start-pinned columns its width further from the start edge.\n const lead = options.selectionColumn ? 1 : 0;\n if (lead && byId.has(SELECTION_COLUMN_ID)) {\n throw new Error(`argus-table: the column id '${SELECTION_COLUMN_ID}' is reserved.`);\n }\n // Offsets: start columns from the start edge (after the selection column), the\n // scrolling ones within the scrolling area, end columns from the end edge.\n let x = lead * SELECTION_COLUMN_WIDTH;\n const list = start.map((def, i) => {\n const v = view(def, lead + i + 1, x, i === start.length - 1);\n x += v.width;\n return v;\n });\n x = 0;\n for (const [i, def] of center.entries()) {\n const v = view(def, lead + start.length + i + 1, x, false);\n list.push(v);\n x += v.width;\n }\n const ends: ColumnView<TData, TContent>[] = [];\n x = 0;\n for (const [i, def] of [...end.entries()].reverse()) {\n const v = view(def, lead + start.length + center.length + i + 1, x, i === 0);\n ends.unshift(v);\n x += v.width;\n }\n list.push(...ends);\n if (lead) list.unshift(selectionView(start.length === 0));\n return list;\n };\n\n let allViews: ColumnView<TData, TContent>[] | undefined;\n const buildAllViews = (shownViews: readonly ColumnView<TData, TContent>[]) => {\n const byShownId = new Map(shownViews.map((v) => [v.id, v]));\n return orderState().flatMap((id) => {\n const shownView = byShownId.get(id);\n if (shownView) return [shownView];\n const def = byId.get(id);\n return def ? [view(def, 0, 0, false)] : [];\n });\n };\n\n return {\n update(next) {\n const merged = { ...options, ...next };\n const changed = (Object.keys(next) as (keyof typeof next)[]).some(\n (key) => next[key] !== options[key],\n );\n if (!changed) return;\n let reread: string[] = [];\n if (next.columns && next.columns !== options.columns) {\n reread = changedAccessors(options.columns, next.columns);\n resolved = resolveColumns(next.columns);\n byId = new Map(resolved.map((c) => [c.id, c]));\n tanStackById = new Map(resolved.map((c) => [c.id, toTanStack(c)]));\n }\n const columnsChanged = merged.columns !== options.columns;\n const pinningChanged = merged.columnPinning !== options.columnPinning;\n const groupsChanged = merged.columnGroups !== options.columnGroups;\n if (\n columnsChanged ||\n merged.columnSizing !== options.columnSizing ||\n merged.autoWidths !== options.autoWidths ||\n pinningChanged\n ) {\n sizing = undefined;\n }\n if (\n columnsChanged ||\n groupsChanged ||\n merged.columnOrder !== options.columnOrder ||\n pinningChanged\n ) {\n order = undefined;\n }\n const refilter =\n columnsChanged ||\n merged.columnFilters !== options.columnFilters ||\n merged.quickFilter !== options.quickFilter ||\n merged.columnVisibility !== options.columnVisibility ||\n merged.remote !== options.remote;\n options = merged;\n if (columnsChanged || groupsChanged) tree = treeOf();\n views = undefined;\n allViews = undefined;\n if (refilter) setRowPredicate(table, predicateFor());\n table.setOptions((prev) => ({ ...prev, ...tableOptions() }));\n if (reread.length && !options.remote) {\n // TanStack caches each value on its row by column id, and keeps rows\n // while the data is the same: drop the values of the columns that now\n // read differently, and sort again.\n for (const row of table.getCoreRowModel().rows) {\n for (const id of reread) Reflect.deleteProperty(row._valuesCache, id);\n }\n valuesChanged(table);\n }\n },\n\n get columns() {\n return (views ??= buildViews());\n },\n\n get allColumns() {\n return (allViews ??= buildAllViews(this.columns));\n },\n\n get rowCount() {\n return options.remote?.rowCount ?? rows().length;\n },\n get rowOrder() {\n return options.remote ?? rows();\n },\n\n get totalWidth() {\n return this.columns.reduce((sum, column) => sum + column.width, 0);\n },\n\n get headerGroups() {\n const current = this.columns;\n if (groupRows?.views === current && groupRows.tree === tree) return groupRows.rows;\n // Views are rebuilt on every update; the rows only change with what they read.\n const key = tree.groups.size\n ? current\n .map(\n (c) =>\n `${c.id}\\u0000${String(c.pin)}\\u0000${String(c.offset)}\\u0000${String(c.pinEdge)}\\u0000${String(c.reorderable)}\\u0000${String(c.resizable)}`,\n )\n .join('\\u0001')\n : '';\n if (groupRows?.tree !== tree || groupRows.key !== key) {\n groupRows = { views: current, tree, key, rows: headerGroupRows(tree, current) };\n } else {\n groupRows.views = current;\n }\n return groupRows.rows;\n },\n\n get headerRows() {\n return this.headerGroups.length + 1;\n },\n\n headerCell(level, columnId) {\n return cellOver(this.headerGroups, level, columnId);\n },\n\n rowAt(index) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n return entry && { id: entry.id, index, original: entry.row };\n }\n const row = rows()[index];\n if (!row) return undefined;\n let view = rowViews.get(row);\n if (view?.index !== index) {\n view = { id: row.id, index, original: row.original as TData };\n rowViews.set(row, view);\n }\n return view;\n },\n\n indexOf(rowId) {\n if (options.remote) return options.remote.indexOf(rowId);\n const current = rows();\n if (indexById?.rows !== current) {\n indexById = { rows: current, map: new Map(current.map((r, i) => [r.id, i])) };\n }\n return indexById.map.get(rowId);\n },\n\n selectableIds() {\n if (options.remote) return options.remote.loadedIds();\n return rows().map((r) => r.id);\n },\n\n valueAt(index, columnId) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n return entry && byId.get(columnId)?.getValue(entry.row, index);\n }\n return rows()[index]?.getValue(columnId);\n },\n\n cellContext(index, columnId) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n const column = byId.get(columnId);\n if (!entry || !column) return undefined;\n return {\n row: entry.row,\n rowId: entry.id,\n index,\n columnId,\n value: column.getValue(entry.row, index),\n };\n }\n const row = rows()[index];\n if (!row || !byId.has(columnId)) return undefined;\n return {\n row: row.original as TData,\n rowId: row.id,\n index,\n columnId,\n value: row.getValue(columnId),\n };\n },\n\n nextSorting(columnId) {\n if (byId.get(columnId)?.sortable !== true) return undefined;\n const current = options.sorting.find((s) => s.id === columnId);\n if (!current) return [{ id: columnId, desc: false }];\n return current.desc ? [] : [{ id: columnId, desc: true }];\n },\n\n nextSizing(columnId, width) {\n const column = byId.get(columnId);\n if (!column?.resizable || !Number.isFinite(width)) return undefined;\n const clamped = Math.round(Math.min(column.maxWidth, Math.max(column.minWidth, width)));\n return { ...options.columnSizing, [columnId]: clamped };\n },\n\n orderOf(base) {\n return base === undefined ? orderState() : normalizeOrder(base, orderable(), tree);\n },\n\n siblingUnits(unit, base) {\n return siblingUnits(base ?? orderState(), orderable(), tree, unit, shown);\n },\n\n nextMove(unit, to, base) {\n return moveUnit(base ?? orderState(), orderable(), tree, unit, to, shown);\n },\n\n nextPinning(columnId, pin, base = options.columnPinning) {\n const column = byId.get(columnId);\n if (!column?.pinnable || (pinOf(column, base) ?? false) === pin) return undefined;\n return { ...base, [columnId]: pin };\n },\n\n nextVisibility(columnId, hidden, base = options.columnVisibility) {\n const column = byId.get(columnId);\n if (!column || hiddenOf(column, base) === hidden) return undefined;\n const othersShown = resolved.some((c) => c !== column && !hiddenOf(c, base));\n if (hidden && (!column.hideable || !othersShown)) return undefined;\n return { ...base, [columnId]: !hidden };\n },\n\n nextFilters(columnId, filter, base = options.columnFilters ?? {}) {\n const column = byId.get(columnId);\n if (!column) return undefined;\n const current = base[columnId];\n if (filter === undefined) {\n if (current === undefined) return undefined;\n const next = { ...base };\n Reflect.deleteProperty(next, columnId);\n return next;\n }\n if (column.filter === undefined) return undefined;\n if (current && JSON.stringify(current) === JSON.stringify(filter)) return undefined;\n return { ...base, [columnId]: filter };\n },\n\n filterValues(columnId, limit = 1000) {\n const column = byId.get(columnId);\n if (!column) return undefined;\n if (column.filterOptions) return { values: [...column.filterOptions], truncated: false };\n if (options.remote) return undefined;\n const rows = table.getCoreRowModel().rows as unknown as Iterable<{\n original: TData;\n index: number;\n }>;\n return distinctValues(rows, column, predicateFor(new Set([columnId])), limit);\n },\n\n indexesPassing(except) {\n if (options.remote) return undefined;\n const keep = predicateFor(new Set(except), true);\n const kept: number[] = [];\n for (const row of table.getCoreRowModel().rows) {\n if (!keep || keep(row.original as TData, row.index)) kept.push(row.index);\n }\n return kept;\n },\n\n pinnedCount(side) {\n return pinned(side).length;\n },\n\n pinnedRowAt(side, index) {\n if (index < 0 || index >= pinned(side).length) return undefined;\n const row = pinned(side)[index] as TData;\n const id = options.getRowId ? options.getRowId(row, index) : `${side}-${String(index)}`;\n return { id, index, original: row };\n },\n\n pinnedValueAt(side, index, columnId) {\n if (index < 0 || index >= pinned(side).length) return undefined;\n return byId.get(columnId)?.getValue(pinned(side)[index] as TData, index);\n },\n\n pinnedCellContext(side, index, columnId) {\n const row = this.pinnedRowAt(side, index);\n const column = byId.get(columnId);\n if (!row || !column) return undefined;\n return {\n row: row.original,\n rowId: row.id,\n index,\n columnId,\n value: column.getValue(row.original, index),\n pinned: side,\n };\n },\n };\n}\n"],"mappings":"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"}