@lavalogic/scoria 0.12.3 → 0.13.2

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 (85) hide show
  1. package/dist/Components/Table/Body/QuickSearchCell.svelte +4 -5
  2. package/dist/Components/Table/Body/QuickSearchCell.svelte.d.ts +12 -12
  3. package/dist/Components/Table/Body/QuickSearchCellProps.d.ts +2 -2
  4. package/dist/Components/Table/Body/Rows/ColumnList.svelte +2 -2
  5. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +3 -3
  6. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte.d.ts +12 -12
  7. package/dist/Components/Table/Body/Rows/ColumnListRowProps.d.ts +2 -2
  8. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +26 -16
  9. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte.d.ts +1 -1
  10. package/dist/Components/Table/Body/Rows/Columns/ActionsCellProps.d.ts +2 -2
  11. package/dist/Components/Table/Body/Rows/Columns/ActionsColumn.d.ts +1 -1
  12. package/dist/Components/Table/Body/Rows/Columns/ActionsTableCell.d.ts +2 -2
  13. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +8 -6
  14. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +11 -3
  15. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte.d.ts +13 -12
  16. package/dist/Components/Table/Body/Rows/Columns/ExpandCellProps.d.ts +5 -4
  17. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +1 -1
  18. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +8 -6
  19. package/dist/Components/Table/Body/Rows/Columns/RowSelectionColumn.d.ts +2 -1
  20. package/dist/Components/Table/Body/Rows/Columns/RowSelectionTableCell.d.ts +2 -1
  21. package/dist/Components/Table/Body/Rows/Columns/SelectColumn.d.ts +2 -1
  22. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +4 -4
  23. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte.d.ts +14 -14
  24. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +1 -1
  25. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +7 -4
  26. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte.d.ts +3 -2
  27. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +3 -3
  28. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +7 -6
  29. package/dist/Components/Table/Body/Rows/Columns/TableQueryColumn.d.ts +2 -1
  30. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +8 -6
  31. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +7 -4
  32. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +8 -6
  33. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +8 -6
  34. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +3 -3
  35. package/dist/Components/Table/Body/Rows/TableRow.svelte +8 -7
  36. package/dist/Components/Table/Body/TableBody.svelte +19 -15
  37. package/dist/Components/Table/Body/TableBodyProps.d.ts +1 -1
  38. package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDefRepository.svelte.d.ts +1 -1
  39. package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDefRepository.svelte.js +17 -15
  40. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +29 -16
  41. package/dist/Components/Table/Headers/SelectAllHeader.svelte +1 -1
  42. package/dist/Components/Table/Headers/TableHead.svelte +4 -4
  43. package/dist/Components/Table/Misc/ColumnPanel.svelte +1 -1
  44. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +1 -1
  45. package/dist/Components/Table/Misc/FilterInput.svelte +3 -5
  46. package/dist/Components/Table/Misc/FilterInput.svelte.d.ts +12 -12
  47. package/dist/Components/Table/Misc/FilterInputProps.d.ts +2 -2
  48. package/dist/Components/Table/Misc/FilterPanel.svelte +2 -2
  49. package/dist/Components/Table/Misc/FilterPanelModal.svelte +2 -2
  50. package/dist/Components/Table/Misc/TableFooter.svelte +1 -1
  51. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +1 -1
  52. package/dist/Components/Table/Misc/TableSidebar.svelte +2 -1
  53. package/dist/Components/Table/Misc/ToolboxPanel.svelte +2 -2
  54. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +1 -1
  55. package/dist/Components/Table/NestedTable.svelte +12 -8
  56. package/dist/Components/Table/NestedTable.svelte.d.ts +15 -15
  57. package/dist/Components/Table/Table.svelte +111 -118
  58. package/dist/Components/Table/Table.svelte.d.ts +16 -15
  59. package/dist/Components/Table/Types/Columns/Column.d.ts +1 -1
  60. package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.d.ts +1 -1
  61. package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.d.ts +2 -2
  62. package/dist/Components/Table/Types/Columns/Definitions/ColumnDefSet.d.ts +1 -1
  63. package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.d.ts +6 -6
  64. package/dist/Components/Table/Types/Columns/Definitions/JSONColumnDefSet.d.ts +1 -1
  65. package/dist/Components/Table/Types/Columns/Definitions/RowSelection/RowSelectionDef.svelte.d.ts +2 -1
  66. package/dist/Components/Table/Types/Columns/DefsWrapper.d.ts +2 -2
  67. package/dist/Components/Table/Types/Columns/ExpandColumn.d.ts +3 -2
  68. package/dist/Components/Table/Types/Columns/ExpandTableCell.d.ts +3 -2
  69. package/dist/Components/Table/Types/Context/ITable.d.ts +5 -5
  70. package/dist/Components/Table/Types/Context/Row.d.ts +3 -3
  71. package/dist/Components/Table/Types/Context/TableContext.svelte.d.ts +40 -37
  72. package/dist/Components/Table/Types/Context/TableContext.svelte.js +318 -279
  73. package/dist/Components/Table/Types/Context/TableInitOptions.d.ts +4 -2
  74. package/dist/Components/Table/Types/DataRepository/IDataRepository.d.ts +1 -1
  75. package/dist/Components/Table/Types/DataRepository/ILocalDataRepository.d.ts +1 -2
  76. package/dist/Components/Table/Types/DataRepository/LocalTableDataRepository.svelte.d.ts +2 -1
  77. package/dist/Components/Table/Types/DataRepository/LocalTableDataRepository.svelte.js +31 -8
  78. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.d.ts +2 -1
  79. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.js +4 -1
  80. package/dist/Components/Table/Types/Focus/TableFocusDetails.svelte.d.ts +3 -3
  81. package/dist/Components/Table/Types/Focus/TableFocusDetails.svelte.js +1 -1
  82. package/dist/Components/Table/Types/Header.d.ts +2 -2
  83. package/dist/Components/Table/Types/HeaderGroup.d.ts +1 -1
  84. package/dist/index.d.ts +1 -1
  85. package/package.json +11 -11
@@ -1,6 +1,6 @@
1
1
  import { browser, dev } from '$app/environment';
2
- import { asyncAll, asyncFilterIndices, asyncSleep, devCatch, getCanvasContext, getErrorMessage } from '../../../../Helpers/Helpers.svelte.js';
3
- import { tick } from 'svelte';
2
+ import { asyncAll, asyncFilterIndices, asyncForEach, asyncMap, asyncSleep, devCatch, getCanvasContext, getErrorMessage } from '../../../../Helpers/Helpers.svelte.js';
3
+ import { tick, untrack } from 'svelte';
4
4
  import { SvelteMap, SvelteSet } from 'svelte/reactivity';
5
5
  import { ColumnType } from '../Columns/ColumnType.js';
6
6
  import { AccessorDef } from '../Columns/Definitions/Accessors/AccessorDef.svelte.js';
@@ -39,15 +39,16 @@ export class TableContext {
39
39
  selectionExtractor;
40
40
  getUserId;
41
41
  _onEditCell;
42
+ debug;
42
43
  static identifier = Symbol();
43
44
  static init(defaultColumnDefs, tableName, dataRepo, options) {
44
- const context = new this(InternalSymbol, defaultColumnDefs, tableName, dataRepo, options.allowCopy ?? true, options.enableResize ?? true, options.allowColumnReordering ?? true, options.allowQuickFiltering ?? true, options.showQuickFilterByDefault ?? true, options.allowAdvancedFiltering ?? true, options.toolbar ?? ToolbarPosition.Right, options.displayFooter ?? true, options.selectionExtractor, options.getUserId, options.onEditCell);
45
+ const context = new this(InternalSymbol, defaultColumnDefs, tableName, dataRepo, options.allowCopy ?? true, options.enableResize ?? true, options.allowColumnReordering ?? true, options.allowQuickFiltering ?? true, options.showQuickFilterByDefault ?? true, options.allowAdvancedFiltering ?? true, options.toolbar ?? ToolbarPosition.Right, options.displayFooter ?? true, options.selectionExtractor, options.getUserId, options.onEditCell, options.debug ?? false);
45
46
  return context;
46
47
  }
47
48
  // #region constructor
48
49
  constructor(INTERNAL_ONLY, defaultColumnDefs, tableName, dataRepo, allowCopy, enableResize, allowColumnReordering, allowQuickFiltering, showQuickFilterByDefault, allowAdvancedFiltering, toolbarPosition, displayFooter, selectionExtractor, getUserId, _onEditCell = () => {
49
50
  console.warn('Cannot edit immutable table');
50
- }) {
51
+ }, debug) {
51
52
  this.defaultColumnDefs = defaultColumnDefs;
52
53
  this.tableName = tableName;
53
54
  this.allowCopy = allowCopy;
@@ -61,11 +62,24 @@ export class TableContext {
61
62
  this.selectionExtractor = selectionExtractor;
62
63
  this.getUserId = getUserId;
63
64
  this._onEditCell = _onEditCell;
65
+ this.debug = debug;
64
66
  if (INTERNAL_ONLY != InternalSymbol) {
65
67
  throw new Error('This class may only be instantiated through the static init() method');
66
68
  }
67
69
  this._dataRepo = $state(dataRepo);
68
70
  // this.dataRepo.forceRefresh = this.forceVisibilityUpdate;
71
+ $effect(() => {
72
+ void this.currentPageData;
73
+ void this.selectedItems;
74
+ untrack(async () => {
75
+ await this.currentPageData;
76
+ if (this.paginationRepo?.paginationState.pageIndex != undefined) {
77
+ await this.updateSelectedItems();
78
+ this.resetHighlightedRows();
79
+ this.recalculateAllSelectedInCurrentPage();
80
+ }
81
+ }).catch(devCatch);
82
+ });
69
83
  if (defaultColumnDefs.remoteFilters) {
70
84
  this.remoteFilters = defaultColumnDefs.remoteFilters;
71
85
  }
@@ -142,11 +156,13 @@ export class TableContext {
142
156
  $effect(() => {
143
157
  void this.paginationRepo?.paginationType;
144
158
  void this.dataRepo.filtering;
145
- void this.dataRepo.filterModes.values();
159
+ void this.dataRepo.filterModes;
146
160
  void this.dataRepo.data;
161
+ void this.paginationRepo?.paginationState;
162
+ // console.log('massive effect start');
147
163
  (async () => {
148
164
  const startTime = Date.now();
149
- let currentTimerPromise;
165
+ let currentTimer;
150
166
  const abortController = new AbortController();
151
167
  try {
152
168
  if (this.paginationRepo?.paginationType == PaginationType.Local) {
@@ -156,77 +172,75 @@ export class TableContext {
156
172
  const snapshot = $state.snapshot(filter.value);
157
173
  checkedIds.add(filter.id);
158
174
  const filterMode = this.dataRepo.filterModes.get(filter.id);
159
- return (!!filterMode &&
160
- (allowedEmptyFilterModes.has(filterMode) ||
161
- (snapshot !== '' && (!Array.isArray(snapshot) || snapshot[0] !== ''))));
175
+ return ((snapshot !== '' &&
176
+ snapshot != null &&
177
+ (!Array.isArray(snapshot) || !!snapshot[0])) ||
178
+ (!!filterMode && allowedEmptyFilterModes.has(filterMode)));
162
179
  });
163
180
  const data = this.dataRepo.data;
164
- // HACK add filter state for filters that don't require a value to function
165
- // this.dataRepo?.filterModes?.entries().forEach(([key, value]) => {
166
- // if (!checkedIds.has(key)) {
167
- // checkedIds.add(key);
168
- // if (allowedEmptyFilterModes.has(value)) {
169
- // filterState.push({
170
- // id: key,
171
- // value: ''
172
- // });
173
- // }
174
- // } else {
175
- // console.warn(`key ${key} was already checked, new value:`, value);
176
- // }
177
- // });
178
- if (!filterState.length) {
179
- this.filteredIndices = data.map((_, index) => index);
180
- }
181
- currentTimerPromise = this.filterTimer = this.filterTimer + 1;
181
+ currentTimer = ++this.filterTimer;
182
182
  await asyncSleep(150);
183
- const currentTimer = currentTimerPromise;
184
- if (currentTimerPromise != this.filterTimer) {
183
+ if (currentTimer != this.filterTimer) {
185
184
  throw new Error('stale filter');
186
185
  }
187
- let settled = false;
188
- const filterPromise = asyncFilterIndices(data, async (item, index) => {
189
- const row = this.createRow(item, index, index);
190
- return asyncAll(filterState, async (filter) => {
191
- abortController.signal.throwIfAborted();
192
- const def = this.columnDefsById.get(filter.id);
193
- if (!def) {
194
- console.warn(`Could not find column def for filter with id ${filter.id}`);
186
+ if (!filterState.length) {
187
+ if (dev) {
188
+ console.log('no filter state was found');
189
+ }
190
+ this.filteredIndices = data.map((_item, index) => {
191
+ return index;
192
+ });
193
+ }
194
+ else {
195
+ this.dataRepo.isLoading = true;
196
+ if (this.debug) {
197
+ console.log('getting filter promise');
198
+ }
199
+ const settled = $state({ value: false });
200
+ const filterPromise = asyncFilterIndices(data, async (item, index) => {
201
+ const row = this.createRow(item, index, index);
202
+ return asyncAll(filterState, async (filter) => {
203
+ abortController.signal.throwIfAborted();
204
+ const def = this.columnDefsById.get(filter.id);
205
+ if (!def) {
206
+ console.warn(`Could not find column def for filter with id ${filter.id}`);
207
+ return false;
208
+ }
209
+ if (def.filterFn) {
210
+ return def.filterFn(row, filter.id, filter.value);
211
+ }
212
+ if (this.debug) {
213
+ console.warn(`column ${def.id} did not have a filter function`);
214
+ }
195
215
  return false;
216
+ });
217
+ });
218
+ filterPromise
219
+ .then((indices) => {
220
+ if (this.debug) {
221
+ console.log(`iteration ${currentTimer}: got indices from filter promise:`, indices);
222
+ }
223
+ this.filteredIndices = indices;
224
+ })
225
+ .catch((e) => {
226
+ if (this.debug) {
227
+ console.log(`caught filter rejection:`, e);
228
+ console.log(`iteration ${currentTimer} cancelled after ${Date.now() - startTime}ms`);
229
+ }
230
+ })
231
+ .finally(() => {
232
+ if (this.debug) {
233
+ console.log(`timer ${currentTimer} is settled`);
196
234
  }
197
- if (def.filterFn) {
198
- return def.filterFn(row, filter.id, filter.value);
235
+ settled.value = true;
236
+ if (currentTimer === this.filterTimer) {
237
+ this.dataRepo.isLoading = false;
199
238
  }
200
- if (dev) {
201
- console.warn(`column ${def.id} did not have a filter function`);
239
+ else if (this.debug) {
240
+ console.warn(`skipping disabling load overlay because current timer is ${currentTimer} but newest is ${this.filterTimer}`);
202
241
  }
203
- return false;
204
242
  });
205
- });
206
- filterPromise
207
- .then((indices) => {
208
- this.filteredIndices = indices;
209
- })
210
- .catch((e) => {
211
- if (dev) {
212
- console.log(`caught filter rejection:`, e);
213
- console.log(`iteration ${currentTimer} cancelled after ${Date.now() - startTime}ms`);
214
- }
215
- })
216
- .finally(() => {
217
- settled = true;
218
- });
219
- for (;;) {
220
- if (currentTimerPromise !== this.filterTimer) {
221
- abortController.abort('stale data');
222
- }
223
- // HACK this warning is wrong. We're in an async context and settled is being changed in the finally callback above
224
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
225
- if (settled) {
226
- console.log(`iteration ${currentTimerPromise} finished ${Date.now() - startTime}ms`);
227
- return;
228
- }
229
- await tick();
243
+ await this.filteringLoop(currentTimer, abortController, settled, startTime);
230
244
  }
231
245
  }
232
246
  }
@@ -234,9 +248,11 @@ export class TableContext {
234
248
  if (dev) {
235
249
  const message = getErrorMessage(e);
236
250
  if (!message.toLocaleLowerCase().startsWith('stale')) {
237
- console.error(e);
251
+ console.error(`Iteration ${currentTimer}`, e);
252
+ }
253
+ else {
254
+ console.log(`iteration ${currentTimer} cancelled after ${Date.now() - startTime}ms`);
238
255
  }
239
- console.log(`iteration ${currentTimerPromise} cancelled after ${Date.now() - startTime}ms`);
240
256
  }
241
257
  }
242
258
  })().catch(devCatch);
@@ -258,6 +274,14 @@ export class TableContext {
258
274
  return this._showQuickFiltering;
259
275
  }
260
276
  set showQuickFiltering(v) {
277
+ if (this.debug) {
278
+ if (!this.allowQuickFiltering) {
279
+ console.log(`attempted to toggle quick filtering when allowQuickFiltering = false`);
280
+ }
281
+ else {
282
+ console.log(`setting quick filtering = ${v}`);
283
+ }
284
+ }
261
285
  this._showQuickFiltering = this.allowQuickFiltering && v;
262
286
  }
263
287
  _dataRepo;
@@ -293,6 +317,8 @@ export class TableContext {
293
317
  set limitFooter(v) {
294
318
  this._limitFooter = v;
295
319
  }
320
+ /* eslint-disable @typescript-eslint/no-explicit-any */
321
+ // type here set to any because users of this property should not access the filter type, but typescript doesn't support that
296
322
  _dragTarget = $state(null);
297
323
  get dragTarget() {
298
324
  return this._dragTarget;
@@ -300,17 +326,13 @@ export class TableContext {
300
326
  set dragTarget(v) {
301
327
  this._dragTarget = v;
302
328
  }
329
+ /* eslint-enable @typescript-eslint/no-explicit-any */
303
330
  _columnDefs = $state([]);
304
331
  get columnDefs() {
305
332
  return this._columnDefs;
306
333
  }
307
334
  set columnDefs(v) {
308
- // if (this._columnDefs.length > 0 && v != this._columnDefs) {
309
- // debugger;
310
- // }
311
335
  this._columnDefs = v;
312
- // this causes an error...?
313
- // this.table = createTable(this.tableOptions);
314
336
  }
315
337
  _columnPresets = $state([]);
316
338
  get columnPresets() {
@@ -358,7 +380,7 @@ export class TableContext {
358
380
  }
359
381
  set focusStart(v) {
360
382
  this._focusStart = v;
361
- this._recalculateFocusedElements();
383
+ this._recalculateFocusedElements().catch(devCatch);
362
384
  }
363
385
  _focusStartIsBeingEdited = $state(false);
364
386
  get focusStartIsBeingEdited() {
@@ -373,7 +395,7 @@ export class TableContext {
373
395
  }
374
396
  set focusEnd(v) {
375
397
  this._focusEnd = v;
376
- this._recalculateFocusedElements();
398
+ this._recalculateFocusedElements().catch(devCatch);
377
399
  }
378
400
  _singleClickEditing = $state(false);
379
401
  get singleClickEditing() {
@@ -445,34 +467,38 @@ export class TableContext {
445
467
  set openModalCoordinates(v) {
446
468
  this._openModalCoordinates = v;
447
469
  }
448
- _allSelectedInCurrentPage = $derived.by(() => {
470
+ _allSelectedInCurrentPage = $derived.by(async () => {
449
471
  if (this.selectedItems.size === 0) {
450
472
  return Promise.resolve(false);
451
473
  }
474
+ void this.paginationRepo?.pageStartIndex;
475
+ void this.columnDefs;
476
+ const sortedData = await this.sortedData;
452
477
  const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
453
478
  const pageEndIndexExclusive = this.paginationRepo
454
- ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
455
- : this.sortedData.length;
479
+ ? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
480
+ : sortedData.length;
456
481
  const selectableMethod = this.columnDefs.find((it) => it instanceof RowSelectionDef)?.isSelectable;
457
- return this.allSelectedBySelectableMethod(pageStartIndex, pageEndIndexExclusive, selectableMethod);
482
+ return await this.allSelectedBySelectableMethod(pageStartIndex, pageEndIndexExclusive, selectableMethod);
458
483
  });
459
484
  get allSelectedInCurrentPage() {
460
485
  return this._allSelectedInCurrentPage;
461
486
  }
462
487
  async allSelectedBySelectableMethod(pageStartIndex, pageEndIndexExclusive, selectableMethod) {
488
+ const sortedData = await this.sortedData;
463
489
  if (selectableMethod) {
464
490
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
465
- const item = this.sortedData[index];
491
+ const item = sortedData[index];
466
492
  if ((await selectableMethod(item, index)) &&
467
- !this.selectedItems.has(this.selectionExtractor(item))) {
493
+ !this.selectedItems.has(await this.selectionExtractor(item))) {
468
494
  return Promise.resolve(false);
469
495
  }
470
496
  }
471
497
  }
472
498
  else {
473
499
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
474
- const item = this.sortedData[index];
475
- if (!this.selectedItems.has(this.selectionExtractor(item))) {
500
+ const item = sortedData[index];
501
+ if (!this.selectedItems.has(await this.selectionExtractor(item))) {
476
502
  return Promise.resolve(false);
477
503
  }
478
504
  }
@@ -480,48 +506,28 @@ export class TableContext {
480
506
  return Promise.resolve(true);
481
507
  }
482
508
  async _areAllHighlighted(pageStartIndex, pageEndIndexExclusive) {
509
+ const sortedData = await this.sortedData;
483
510
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
484
- const item = this.sortedData[index];
485
- if (!this.highlightedItems.has(this.selectionExtractor(item))) {
511
+ const item = sortedData[index];
512
+ if (!this.highlightedItems.has(await this.selectionExtractor(item))) {
486
513
  return Promise.resolve(false);
487
514
  }
488
515
  }
489
516
  return Promise.resolve(true);
490
517
  }
491
- _allHighlighted = $derived.by(() => {
518
+ _allHighlighted = $derived.by(async () => {
492
519
  if (this.highlightedItems.size === 0) {
493
520
  return Promise.resolve(false);
494
521
  }
495
522
  const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
496
523
  const pageEndIndexExclusive = this.paginationRepo
497
- ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
498
- : this.sortedData.length;
499
- return this._areAllHighlighted(pageStartIndex, pageEndIndexExclusive);
524
+ ? Math.min(this.paginationRepo.pageEndIndexExclusive, (await this.sortedData).length)
525
+ : (await this.sortedData).length;
526
+ return await this._areAllHighlighted(pageStartIndex, pageEndIndexExclusive);
500
527
  });
501
528
  get allHighlighted() {
502
529
  return this._allHighlighted;
503
530
  }
504
- // private _allHighlighted: boolean = $derived.by(() => {
505
- // if (!this.dataRepo || this.highlightedItems.size === 0) {
506
- // return false;
507
- // }
508
- // const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
509
- // const pageEndIndexExclusive = this.paginationRepo
510
- // ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
511
- // : this.sortedData.length;
512
- // if (pageStartIndex == undefined || pageEndIndexExclusive == undefined) {
513
- // return false;
514
- // }
515
- // for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
516
- // if (!this.highlightedItems.has(index)) {
517
- // return false;
518
- // }
519
- // }
520
- // return true;
521
- // });
522
- // public get allHighlighted(): boolean {
523
- // return this._allHighlighted;
524
- // }
525
531
  _hasHighlightedItems = $derived(this.highlightedItems.size > 0);
526
532
  get hasHighlightedItems() {
527
533
  return this._hasHighlightedItems;
@@ -534,18 +540,6 @@ export class TableContext {
534
540
  set selectedItems(v) {
535
541
  this._selectedItems = v;
536
542
  }
537
- // HACK this is lazily loaded. it will not be used before initialisation.
538
- // public getSelectedItemsAsObjects = (): T[] => {
539
- // if (!this.selectionExtractor) {
540
- // throw new Error("No selection extractor was supplied.")
541
- // };
542
- // return this.sortedData.filter((item) => {
543
- // return this._selectedIdentifiers.has(this.selectionExtractor(item));
544
- // }) ?? []
545
- // }
546
- // public get selectedItemsAsObjects(): T[] {
547
- // return this._selectedItemsAsObjects;
548
- // }
549
543
  _invalidValues = $state(new SvelteMap());
550
544
  get invalidValues() {
551
545
  return this._invalidValues;
@@ -591,10 +585,6 @@ export class TableContext {
591
585
  // }
592
586
  return comparableSortingFn(id, desc);
593
587
  };
594
- originalRowIndices = $derived(
595
- // TODO decide
596
- // eslint-disable-next-line svelte/prefer-svelte-reactivity
597
- new Map(this.dataRepo.data.map((item, index) => [item, index])));
598
588
  // private _filterTimer: ReturnType<typeof setTimeout> | undefined;
599
589
  _filterTimer = 1;
600
590
  get filterTimer() {
@@ -608,31 +598,43 @@ export class TableContext {
608
598
  return this._filteredIndices;
609
599
  }
610
600
  set filteredIndices(v) {
601
+ if (this.debug) {
602
+ console.log('updating filtered indices');
603
+ }
611
604
  this._filteredIndices = v;
612
605
  }
613
606
  filteredData = $derived.by(() => {
607
+ void this.dataRepo.data;
608
+ void this.filteredIndices;
609
+ void this.showSelectedOnly;
610
+ const dataRepo = this.dataRepo;
614
611
  if (this.paginationRepo?.paginationType == PaginationType.Local) {
615
612
  const data = this.showSelectedOnly
616
613
  ? // FIXME this will show the selected items by order of insertion to the selectedItems map.
617
614
  [...this.selectedItems.values()]
618
615
  : this.filteredIndices.map((index) => {
619
- return this.dataRepo.data[index];
616
+ return dataRepo.data[index];
620
617
  });
621
618
  return data;
622
619
  }
623
- return this.showSelectedOnly ? [...this.selectedItems.values()] : this.dataRepo.data;
620
+ if (this.debug) {
621
+ console.log(`updating filtered data. Selected only: ${this.showSelectedOnly}`);
622
+ }
623
+ return this.showSelectedOnly ? [...this.selectedItems.values()] : dataRepo.data;
624
624
  });
625
- sortedData = $derived.by(() => {
625
+ // eslint-disable-next-line @typescript-eslint/require-await
626
+ sortedData = $derived.by(async () => {
627
+ if (this.debug) {
628
+ console.log('sorted data');
629
+ }
630
+ const fd = this.filteredData;
631
+ const sorting = this.dataRepo.sorting;
626
632
  if (this.paginationRepo?.paginationType == PaginationType.Local) {
627
- const state = this.dataRepo.sorting;
628
- const sortedData = this.showSelectedOnly
629
- ? // FIXME this will show the selected items by order of insertion to the selectedItems map.
630
- [...this.selectedItems.values()]
631
- : this.filteredData.concat();
632
- sortedData.sort((a, b) => {
633
- const end = state.length;
633
+ const dataToSort = fd.concat();
634
+ dataToSort.sort((a, b) => {
635
+ const end = sorting.length;
634
636
  for (let i = 0; i < end; i++) {
635
- const { id, desc } = state[i];
637
+ const { id, desc } = sorting[i];
636
638
  const sortingFn = this.getSortingFn(id, desc);
637
639
  if (sortingFn) {
638
640
  const result = sortingFn(a, b);
@@ -640,19 +642,27 @@ export class TableContext {
640
642
  return result;
641
643
  }
642
644
  }
643
- else {
645
+ else if (dev) {
644
646
  console.warn('no sorting fn found for ' + id);
645
647
  }
646
648
  }
647
649
  return 0;
648
650
  });
649
- return sortedData;
651
+ return dataToSort;
650
652
  }
651
- return this.filteredData;
653
+ return fd;
652
654
  });
653
- sortedRowModel = $derived.by(() => {
654
- const rows = this.sortedData.map((item, index) => {
655
- const unsortedIndex = this.originalRowIndices.get(item) ?? index;
655
+ sortedRowModel = $derived.by(async () => {
656
+ void this.originalRowIndices;
657
+ void this.sortedData;
658
+ const sd = await this.sortedData;
659
+ const ori = await this.originalRowIndices;
660
+ const rows = await asyncMap(sd, async (item, index) => {
661
+ const originalIndex = ori.get(await this.selectionExtractor(item));
662
+ const unsortedIndex = originalIndex ?? index;
663
+ if (originalIndex == null) {
664
+ throw new Error(`Sorted Data not found in Original Row Indices: original index ${originalIndex}, index ${index}`);
665
+ }
656
666
  return this.createRow(item, index, unsortedIndex);
657
667
  });
658
668
  return {
@@ -661,13 +671,33 @@ export class TableContext {
661
671
  rowsById: new Map(rows.map((it, index) => [index.toString(), it])) //FIXME should this be by sorted id or by original id?
662
672
  };
663
673
  });
664
- _currentPageData = $derived(this.dataRepo.paginationType == PaginationType.Local
665
- ? this.sortedData.slice(this.dataRepo.pageStartIndex, this.dataRepo.pageEndIndexExclusive)
666
- : this.sortedData);
667
- paginationRowModel = $derived.by(() => {
668
- const sortedData = this._currentPageData;
669
- const rows = sortedData.map((item, index) => {
670
- const unsortedIndex = this.originalRowIndices.get(item) ?? index;
674
+ currentPageData = $derived.by(async () => {
675
+ void this.sortedData;
676
+ const dataRepo = this.dataRepo;
677
+ const sd = await this.sortedData;
678
+ if (dataRepo.paginationType != PaginationType.Local) {
679
+ return sd;
680
+ }
681
+ const x = sd.slice(dataRepo.pageStartIndex, dataRepo.pageEndIndexExclusive);
682
+ return x;
683
+ });
684
+ // FIXME this is most likely the cuplrit for add pod not working on receipt. It may be one tick behind the other values
685
+ originalRowIndices = $derived.by(async () => {
686
+ const dataRepo = this.dataRepo;
687
+ const awaited = await asyncMap(dataRepo.data, async (item, index) => [await this.selectionExtractor(item), index]);
688
+ // eslint-disable-next-line svelte/prefer-svelte-reactivity
689
+ return new Map(awaited);
690
+ });
691
+ paginationRowModel = $derived.by(async () => {
692
+ void this.originalRowIndices;
693
+ void this.currentPageData;
694
+ void this.columnDefsById;
695
+ void this.columnVisibility;
696
+ void this.paginationRepo?.sorting;
697
+ void this.columnPinning;
698
+ const currentPageData = await this.currentPageData;
699
+ const rows = await asyncMap(currentPageData, async (item, index) => {
700
+ const unsortedIndex = (await this.originalRowIndices).get(item) ?? index;
671
701
  const row = {
672
702
  getValue: async (key) => {
673
703
  const gotValue = await this.columnDefsById.get(key)?.accessorFn?.(item, index);
@@ -739,44 +769,25 @@ export class TableContext {
739
769
  rowsById: new Map(rows.map((it, index) => [index.toString(), it])) //FIXME should this be by sorted id or by original id?
740
770
  };
741
771
  });
742
- get currentPageData() {
743
- return this._currentPageData;
744
- }
745
772
  // #endregion
746
773
  // #region public methods
747
- selectionContains = (item) => {
774
+ selectionContains = async (item) => {
748
775
  if (!this.isSelectable) {
749
776
  return true;
750
777
  }
751
- return this.selectedItems.has(this.selectionExtractor(item));
778
+ return this.selectedItems.has(await this.selectionExtractor(item));
752
779
  };
753
- // public readonly HACK__reselectItem = (item: T) => {
754
- // if (!this.selectionExtractor) {
755
- // throw new Error('No selection extractor was supplied');
756
- // }
757
- // if (!this.isSelectable) {
758
- // return true;
759
- // }
760
- // const key = this.selectionExtractor(item);
761
- // if (this.selectedItems.has(key)) {
762
- // this.selectedItems.delete(key);
763
- // this.selectedItems.set(key, item);
764
- // } else {
765
- // this.selectedItems.set(key, item);
766
- // this.selectedItems.delete(key);
767
- // }
768
- // };
769
- addInvalidValue = (item) => {
770
- this.invalidValues.set(this.selectionExtractor(item), item);
780
+ addInvalidValue = async (item) => {
781
+ this.invalidValues.set(await this.selectionExtractor(item), item);
771
782
  };
772
- removeInvalidValue = (item) => {
773
- this.invalidValues.delete(this.selectionExtractor(item));
783
+ removeInvalidValue = async (item) => {
784
+ this.invalidValues.delete(await this.selectionExtractor(item));
774
785
  };
775
786
  setOpenModalCoordinates = (coordinates) => {
776
787
  this.openModalCoordinates = coordinates ? { ...coordinates } : null;
777
788
  };
778
- toggleHighlightedRow = (item) => {
779
- const key = this.selectionExtractor(item);
789
+ toggleHighlightedRow = async (item) => {
790
+ const key = await this.selectionExtractor(item);
780
791
  if (this.highlightedItems.has(key)) {
781
792
  this.highlightedItems.delete(key);
782
793
  }
@@ -784,58 +795,49 @@ export class TableContext {
784
795
  this.highlightedItems.set(key, item);
785
796
  }
786
797
  };
787
- // public readonly toggleHighlightedRow = (rowIndex: number) => {
788
- // if (this.highlightedRowIndexIds.has(rowIndex)) {
789
- // this.highlightedRowIndexIds.delete(rowIndex);
790
- // } else {
791
- // this.highlightedRowIndexIds.add(rowIndex);
792
- // }
793
- // };
794
798
  resetHighlightedRows = () => {
795
799
  this.highlightedItems.clear();
796
800
  };
797
- toggleSelected = (item, selected) => {
798
- const key = this.selectionExtractor(item);
801
+ toggleSelected = async (item, selected) => {
802
+ const key = await this.selectionExtractor(item);
799
803
  if (selected) {
800
804
  this.selectedItems.set(key, item);
801
805
  }
802
806
  else {
803
807
  this.selectedItems.delete(key);
804
808
  }
805
- this.recalculateAllSelectedInCurrentPage();
806
809
  };
807
810
  setSelectionMap = (set) => {
808
811
  this.selectedItems = set;
809
812
  };
810
813
  updateSelectedItems = async () => {
811
814
  const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
815
+ const sortedData = await this.sortedData;
812
816
  const pageEndIndexExclusive = this.paginationRepo
813
- ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
814
- : this.sortedData.length;
817
+ ? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
818
+ : sortedData.length;
815
819
  const selectableMethod = this.columnDefs.find((it) => it instanceof RowSelectionDef)?.isSelectable;
820
+ const updateSelectedItem = async (item) => {
821
+ const key = await this.selectionExtractor(item);
822
+ if (this.selectedItems.has(key)) {
823
+ //replace selected item with newer version of the same identity
824
+ this.selectedItems.set(key, item);
825
+ }
826
+ };
816
827
  if (selectableMethod) {
817
828
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
818
- const item = this.sortedData[index];
829
+ const item = sortedData[index];
819
830
  if (await selectableMethod(item, index)) {
820
- const key = this.selectionExtractor(item);
821
- if (this.selectedItems.has(key)) {
822
- //replace selected item with newer version of the same identity
823
- this.selectedItems.set(key, item);
824
- }
831
+ await updateSelectedItem(item);
825
832
  }
826
833
  }
827
834
  }
828
835
  else {
829
836
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
830
- const item = this.sortedData[index];
831
- const key = this.selectionExtractor(item);
832
- if (this.selectedItems.has(key)) {
833
- //replace selected item with newer version of the same identity
834
- this.selectedItems.set(key, item);
835
- }
837
+ const item = sortedData[index];
838
+ await updateSelectedItem(item);
836
839
  }
837
840
  }
838
- this.recalculateAllSelectedInCurrentPage();
839
841
  };
840
842
  resetSelectedItems = () => {
841
843
  for (const key of this.selectedItems.keys()) {
@@ -843,25 +845,37 @@ export class TableContext {
843
845
  }
844
846
  this.recalculateAllSelectedInCurrentPage();
845
847
  };
848
+ lastIncrement = Number.MIN_SAFE_INTEGER;
846
849
  recalculateAllSelectedInCurrentPage = () => {
847
- tick()
850
+ const invalidValues = this._invalidValues;
851
+ const allSelectedInCurrentPage = [...this.selectedItems.keys()];
852
+ const currentIncrement = ++this.lastIncrement;
853
+ this.allSelectedInCurrentPage
848
854
  .then(() => {
849
- return this.allSelectedInCurrentPage.then(() => {
850
- this.hasInvalidSelectedItems = [...this.selectedItems.keys()].some((key) => this._invalidValues.has(key));
851
- });
855
+ if (this.lastIncrement == currentIncrement) {
856
+ this.hasInvalidSelectedItems = allSelectedInCurrentPage.some((key) => {
857
+ return invalidValues.has(key);
858
+ });
859
+ }
860
+ else {
861
+ if (dev) {
862
+ console.log('skipping recalculation due to stale data');
863
+ }
864
+ }
852
865
  })
853
866
  .catch(devCatch);
854
867
  };
855
868
  selectAllInCurrentPage = async () => {
869
+ void this.paginationRepo?.pageStartIndex;
870
+ const sortedData = await this.sortedData;
856
871
  if (await this.allSelectedInCurrentPage) {
857
- // this.resetSelectedItems();
858
872
  const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
859
873
  const pageEndIndexExclusive = this.paginationRepo
860
- ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
861
- : this.sortedData.length;
874
+ ? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
875
+ : sortedData.length;
862
876
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
863
- const item = this.sortedData[index];
864
- this.selectedItems.delete(this.selectionExtractor(item));
877
+ const item = sortedData[index];
878
+ this.selectedItems.delete(await this.selectionExtractor(item));
865
879
  }
866
880
  }
867
881
  else {
@@ -869,50 +883,51 @@ export class TableContext {
869
883
  // const selectedItems = new SvelteSet<number>();
870
884
  const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
871
885
  const pageEndIndexExclusive = this.paginationRepo
872
- ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
873
- : this.sortedData.length;
886
+ ? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
887
+ : sortedData.length;
874
888
  const selectableMethod = this.columnDefs.find((it) => it instanceof RowSelectionDef)?.isSelectable;
875
889
  if (selectableMethod) {
876
890
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
877
- const item = this.sortedData[index];
891
+ const item = sortedData[index];
878
892
  if (await selectableMethod(item, index)) {
879
- this.selectedItems.set(this.selectionExtractor(item), item);
893
+ this.selectedItems.set(await this.selectionExtractor(item), item);
880
894
  }
881
895
  }
882
896
  }
883
897
  else {
884
898
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
885
- const item = this.sortedData[index];
886
- this.selectedItems.set(this.selectionExtractor(item), item);
899
+ const item = sortedData[index];
900
+ this.selectedItems.set(await this.selectionExtractor(item), item);
887
901
  }
888
902
  }
889
903
  }
890
- this.recalculateAllSelectedInCurrentPage();
891
904
  };
892
905
  onHighlightAll = () => {
893
906
  this.allHighlighted
894
907
  .then((areAllHighlighted) => {
895
908
  if (areAllHighlighted) {
896
909
  this.highlightedItems.clear();
910
+ return Promise.resolve();
897
911
  }
898
912
  else {
899
- this._currentPageData.forEach((item) => {
900
- this.highlightedItems.set(this.selectionExtractor(item), item);
913
+ return this.currentPageData.then((items) => {
914
+ return asyncForEach(items, async (item) => {
915
+ this.highlightedItems.set(await this.selectionExtractor(item), item);
916
+ });
901
917
  });
902
918
  }
903
919
  })
904
920
  .catch(devCatch);
905
921
  };
906
922
  onEditCell = async (item, coords, value) => {
907
- const oldKey = this.selectionExtractor(item);
908
- const wasSelected = oldKey != null && this.selectedItems.has(oldKey);
909
- // debugger;
923
+ const oldKey = await this.selectionExtractor(item);
924
+ const wasSelected = this.selectedItems.has(oldKey);
910
925
  if (wasSelected) {
911
926
  this.selectedItems.delete(oldKey);
912
927
  }
913
928
  await this._onEditCell?.(item, coords, value);
914
929
  if (wasSelected && this.isSelectable) {
915
- const newKey = this.selectionExtractor(item);
930
+ const newKey = await this.selectionExtractor(item);
916
931
  if (newKey) {
917
932
  this.selectedItems.set(newKey, item);
918
933
  }
@@ -941,13 +956,16 @@ export class TableContext {
941
956
  this.tabBackward();
942
957
  }
943
958
  else {
944
- this.tabForward();
959
+ this.tabForward().catch(devCatch);
945
960
  }
946
961
  }
947
962
  if (e.target.tagName === 'INPUT' &&
948
963
  e.target.attributes.getNamedItem('type')?.value !== 'checkbox') {
949
964
  return;
950
965
  }
966
+ this.handleKeystroke(e).catch(devCatch);
967
+ };
968
+ async handleKeystroke(e) {
951
969
  switch (e.key) {
952
970
  case 'Enter':
953
971
  case 'F2':
@@ -955,7 +973,6 @@ export class TableContext {
955
973
  break;
956
974
  }
957
975
  e.preventDefault();
958
- e.stopPropagation();
959
976
  e.target?.dispatchEvent(new CustomEvent('edit', { detail: { selectAll: e.key === 'Enter' } }));
960
977
  // focusStartIsBeingEdited.set(true);
961
978
  break;
@@ -966,20 +983,20 @@ export class TableContext {
966
983
  if (!this.allowCopy) {
967
984
  return;
968
985
  }
969
- this.focusToTop();
986
+ await this.focusToTop();
970
987
  }
971
988
  else {
972
- this.moveToTop();
989
+ await this.moveToTop();
973
990
  }
974
991
  }
975
992
  else if (e.getModifierState('Shift')) {
976
993
  if (!this.allowCopy) {
977
994
  return;
978
995
  }
979
- this.moveFocusUp();
996
+ await this.moveFocusUp();
980
997
  }
981
998
  else {
982
- this.setFocusUp();
999
+ await this.setFocusUp();
983
1000
  }
984
1001
  return;
985
1002
  }
@@ -990,20 +1007,20 @@ export class TableContext {
990
1007
  if (!this.allowCopy) {
991
1008
  return;
992
1009
  }
993
- this.focusToBottom();
1010
+ await this.focusToBottom();
994
1011
  }
995
1012
  else {
996
- this.moveToBottom();
1013
+ await this.moveToBottom();
997
1014
  }
998
1015
  }
999
1016
  else if (e.getModifierState('Shift')) {
1000
1017
  if (!this.allowCopy) {
1001
1018
  return;
1002
1019
  }
1003
- this.moveFocusDown();
1020
+ await this.moveFocusDown();
1004
1021
  }
1005
1022
  else {
1006
- this.setFocusDown();
1023
+ await this.setFocusDown();
1007
1024
  }
1008
1025
  return;
1009
1026
  }
@@ -1058,9 +1075,9 @@ export class TableContext {
1058
1075
  case 'a': {
1059
1076
  if (e.ctrlKey) {
1060
1077
  e.preventDefault();
1061
- this.moveToTop();
1078
+ await this.moveToTop();
1062
1079
  this.moveToStart();
1063
- this.focusToBottom();
1080
+ await this.focusToBottom();
1064
1081
  this.focusToEnd();
1065
1082
  }
1066
1083
  break;
@@ -1069,12 +1086,12 @@ export class TableContext {
1069
1086
  case 'C':
1070
1087
  if (e.getModifierState('Control')) {
1071
1088
  e.preventDefault();
1072
- this.copyDataToClipboard().catch(devCatch);
1089
+ await this.copyDataToClipboard();
1073
1090
  }
1074
1091
  break;
1075
1092
  }
1076
1093
  }
1077
- };
1094
+ }
1078
1095
  toggleQuickFiltering = () => {
1079
1096
  if (this.allowQuickFiltering) {
1080
1097
  const fs = this.focusStart;
@@ -1147,12 +1164,12 @@ export class TableContext {
1147
1164
  if (!browser) {
1148
1165
  return;
1149
1166
  }
1150
- const ctx = getCanvasContext();
1151
- const currentPageContents = this.currentPageData;
1152
1167
  const colId = columnDef.id;
1153
1168
  if (!colId) {
1154
1169
  return;
1155
1170
  }
1171
+ const currentPageContents = await this.currentPageData;
1172
+ const ctx = getCanvasContext();
1156
1173
  let maxWidth = 0;
1157
1174
  if (columnDef.accessorFn) {
1158
1175
  for (let i = currentPageContents.length - 1; i > -1; i--) {
@@ -1325,41 +1342,41 @@ export class TableContext {
1325
1342
  this.focusStart = null;
1326
1343
  this.focusEnd = null;
1327
1344
  };
1328
- focusToTop = () => {
1345
+ focusToTop = async () => {
1329
1346
  if (!this.allowCopy) {
1330
1347
  return;
1331
1348
  }
1332
- this._moveFocusEndRow(-Infinity);
1349
+ return this._moveFocusEndRow(-Infinity);
1333
1350
  };
1334
1351
  focusToBottom = () => {
1335
1352
  if (!this.allowCopy) {
1336
1353
  return;
1337
1354
  }
1338
- this._moveFocusEndRow(Infinity);
1355
+ return this._moveFocusEndRow(Infinity);
1339
1356
  };
1340
- moveToBottom = () => {
1341
- this._moveFocusRow(Infinity);
1357
+ moveToBottom = async () => {
1358
+ return this._moveFocusRow(Infinity);
1342
1359
  };
1343
- moveToTop = () => {
1344
- this._moveFocusRow(-Infinity);
1360
+ moveToTop = async () => {
1361
+ return this._moveFocusRow(-Infinity);
1345
1362
  };
1346
- moveFocusUp = () => {
1363
+ moveFocusUp = async () => {
1347
1364
  if (!this.allowCopy) {
1348
1365
  return;
1349
1366
  }
1350
- this._moveFocusEndRow(-1);
1367
+ return this._moveFocusEndRow(-1);
1351
1368
  };
1352
- setFocusUp = () => {
1353
- this._moveFocusRow(-1);
1369
+ setFocusUp = async () => {
1370
+ return this._moveFocusRow(-1);
1354
1371
  };
1355
- tabForward = () => {
1372
+ tabForward = async () => {
1356
1373
  if (!this.allowCopy) {
1357
1374
  return;
1358
1375
  }
1359
1376
  const defs = this.columnDefs;
1360
1377
  const visibility = this.columnVisibility;
1361
1378
  const indexBounds = defs.length;
1362
- const rowBounds = this.sortedData.length;
1379
+ const rowBounds = (await this.sortedData).length;
1363
1380
  if (!this.focusStart || !rowBounds) {
1364
1381
  return;
1365
1382
  }
@@ -1480,14 +1497,14 @@ export class TableContext {
1480
1497
  }
1481
1498
  //otherwise return without doing anything
1482
1499
  };
1483
- moveFocusDown = () => {
1500
+ moveFocusDown = async () => {
1484
1501
  if (!this.allowCopy) {
1485
1502
  return;
1486
1503
  }
1487
- this._moveFocusEndRow(1);
1504
+ return this._moveFocusEndRow(1);
1488
1505
  };
1489
- setFocusDown = () => {
1490
- this._moveFocusRow(1);
1506
+ setFocusDown = async () => {
1507
+ return this._moveFocusRow(1);
1491
1508
  };
1492
1509
  moveFocusLeft = () => {
1493
1510
  if (!this.allowCopy) {
@@ -1611,6 +1628,9 @@ export class TableContext {
1611
1628
  // }
1612
1629
  // };
1613
1630
  setSelectedPreset = (preset) => {
1631
+ if (this.debug) {
1632
+ console.log('setting selected preset:', preset);
1633
+ }
1614
1634
  this.columnDefs = preset.columnDefs;
1615
1635
  if (!this.paginationRepo?.updateSorting) {
1616
1636
  console.warn('no sorting state found');
@@ -1751,7 +1771,7 @@ export class TableContext {
1751
1771
  };
1752
1772
  localStorage.setItem(`${this.userId}-${this.tableName}-settings`, JSON.stringify(settingsObject));
1753
1773
  }
1754
- _moveFocusEndRow(offset) {
1774
+ async _moveFocusEndRow(offset) {
1755
1775
  if (!this.allowCopy) {
1756
1776
  return;
1757
1777
  }
@@ -1760,27 +1780,27 @@ export class TableContext {
1760
1780
  return;
1761
1781
  }
1762
1782
  const focusEnd = this.focusEnd;
1763
- const rows = this.paginationRowModel.rows;
1783
+ const rows = (await this.paginationRowModel).rows;
1764
1784
  const endRowIndex = rows.findIndex((row) => row.visibleIndex === focusEnd.row);
1765
1785
  this.focusEnd = {
1766
1786
  ...this.focusEnd,
1767
1787
  row: rows[Math.max(Math.min(endRowIndex + offset, rows.length - 1), 0)].visibleIndex
1768
1788
  };
1769
1789
  }
1770
- _moveFocusRow(offset) {
1790
+ async _moveFocusRow(offset) {
1771
1791
  if (!this.focusStart) {
1772
1792
  console.warn('no focusStart found');
1773
1793
  return;
1774
1794
  }
1775
1795
  const focusStart = this.focusStart;
1776
- const newEndRowIndex = (() => {
1777
- const rows = this.paginationRowModel.rows;
1796
+ const newEndRowIndex = await (async () => {
1797
+ const rows = (await this.paginationRowModel).rows;
1778
1798
  const endRowIndex = rows.findIndex((row) => row.visibleIndex === focusStart.row);
1779
1799
  return rows[Math.max(Math.min(endRowIndex + offset, rows.length - 1), 0)].visibleIndex;
1780
1800
  })();
1781
1801
  this.moveFocus({ ...this.focusStart, row: newEndRowIndex });
1782
1802
  }
1783
- _recalculateFocusedElements() {
1803
+ async _recalculateFocusedElements() {
1784
1804
  if (!this.focusStart || !this.focusEnd) {
1785
1805
  this.focusedRowIndexIds = new SvelteSet();
1786
1806
  this.focusedColumnIds = new SvelteSet();
@@ -1788,7 +1808,7 @@ export class TableContext {
1788
1808
  }
1789
1809
  const { row: startRowIndexId, column: startColumnIndex } = this.focusStart;
1790
1810
  const { row: endRowIndexId, column: endColumnIndex } = this.focusEnd;
1791
- const model = this.sortedRowModel;
1811
+ const model = await this.sortedRowModel;
1792
1812
  const startRowIndex = model.rows.findIndex((row) => row.visibleIndex === startRowIndexId);
1793
1813
  const endRowIndex = model.rows.findIndex((row) => row.visibleIndex === endRowIndexId);
1794
1814
  if (startRowIndex == -1 || endRowIndex == -1) {
@@ -1822,11 +1842,12 @@ export class TableContext {
1822
1842
  // eslint-disable-next-line svelte/prefer-svelte-reactivity
1823
1843
  const indices = new Map();
1824
1844
  const selectedRows = [...this.highlightedItems.values()];
1845
+ const sortedData = await this.sortedData;
1825
1846
  for (const item of selectedRows) {
1826
- const rowIndex = this.sortedData.indexOf(item);
1847
+ const rowIndex = sortedData.indexOf(item);
1827
1848
  if (rowIndex == -1) {
1828
- // eslint-disable-next-line no-debugger
1829
- debugger;
1849
+ console.warn(`row index for highlighted row data not found`);
1850
+ continue;
1830
1851
  }
1831
1852
  indices.set(item, rowIndex);
1832
1853
  }
@@ -1835,22 +1856,22 @@ export class TableContext {
1835
1856
  const rowLength = selectedRows.length;
1836
1857
  for (let rowIndex = 0; rowIndex < rowLength; rowIndex++) {
1837
1858
  const item = selectedRows[rowIndex];
1838
- const key = this.selectionExtractor(item);
1859
+ const key = await this.selectionExtractor(item);
1839
1860
  selectedCells[rowIndex] = [];
1840
1861
  const targetRow = selectedCells[rowIndex];
1841
1862
  const colLength = affectedColumns.length;
1842
1863
  for (let colIndex = 0; colIndex < colLength; colIndex++) {
1843
1864
  const columnDef = affectedColumns[colIndex];
1844
1865
  if (columnDef instanceof RowSelectionDef) {
1845
- targetRow.push(key !== undefined && this.selectedItems.has(key) ? 'true' : 'false');
1866
+ targetRow.push(this.selectedItems.has(key) ? 'true' : 'false');
1846
1867
  continue;
1847
1868
  }
1848
1869
  if (uncopyableColumns.has(columnDef.columnType)) {
1849
1870
  continue;
1850
1871
  }
1851
- const x = (await columnDef.getDisplayValue?.(item, this.sortedData.lastIndexOf(item))) ||
1872
+ const x = (await columnDef.getDisplayValue?.(item, sortedData.lastIndexOf(item))) ||
1852
1873
  ('accessorFn' in columnDef &&
1853
- (await columnDef.accessorFn?.(item, this.sortedData.indexOf(item))));
1874
+ (await columnDef.accessorFn?.(item, sortedData.indexOf(item))));
1854
1875
  if (x && typeof x === 'string') {
1855
1876
  targetRow.push(x);
1856
1877
  continue;
@@ -1878,10 +1899,10 @@ export class TableContext {
1878
1899
  const { row: startRowIndexId, column: startColumnIndex } = this.focusStart;
1879
1900
  const { row: endRowIndexId, column: endColumnIndex } = this.focusEnd;
1880
1901
  // const model = this._currentPageData;
1881
- const model = this.paginationRowModel;
1902
+ const model = await this.paginationRowModel;
1882
1903
  const startRowIndex = model.rows.findIndex((row) => row.visibleIndex === startRowIndexId);
1883
1904
  const endRowIndex = model.rows.findIndex((row) => row.visibleIndex === endRowIndexId);
1884
- if (!this._currentPageData.length || startRowIndex == -1 || endRowIndex == -1) {
1905
+ if (!(await this.currentPageData).length || startRowIndex == -1 || endRowIndex == -1) {
1885
1906
  throw new Error(`copy was missing one of the two indices. First: ${startRowIndex}, second: ${endRowIndex}`);
1886
1907
  }
1887
1908
  const minRowIndex = Math.min(startRowIndex, endRowIndex);
@@ -1906,24 +1927,25 @@ export class TableContext {
1906
1927
  // TODO somewhere between here and the ending of the copy functionality, we end up with issues where instead of it using the accessor fn, it tries to pick up the select option, and ends up using the value ("1", etc)
1907
1928
  const selectedCells = [];
1908
1929
  const rowLength = selectedRows.length;
1930
+ const sortedData = await this.sortedData;
1909
1931
  for (let rowIndex = 0; rowIndex < rowLength; rowIndex++) {
1910
1932
  const item = selectedRows[rowIndex];
1911
- const key = this.selectionExtractor(item);
1933
+ const key = await this.selectionExtractor(item);
1912
1934
  selectedCells[rowIndex] = [];
1913
1935
  const targetRow = selectedCells[rowIndex];
1914
1936
  const colLength = affectedColumns.length;
1915
1937
  for (let colIndex = 0; colIndex < colLength; colIndex++) {
1916
1938
  const columnDef = affectedColumns[colIndex];
1917
1939
  if (columnDef instanceof RowSelectionDef) {
1918
- targetRow.push(key !== undefined && this.selectedItems.has(key) ? 'true' : 'false');
1940
+ targetRow.push(this.selectedItems.has(key) ? 'true' : 'false');
1919
1941
  continue;
1920
1942
  }
1921
1943
  if (uncopyableColumns.has(columnDef.columnType)) {
1922
1944
  continue;
1923
1945
  }
1924
- const x = (await columnDef.getDisplayValue?.(item, this.sortedData.lastIndexOf(item))) ||
1946
+ const x = (await columnDef.getDisplayValue?.(item, sortedData.lastIndexOf(item))) ||
1925
1947
  ('accessorFn' in columnDef &&
1926
- (await columnDef.accessorFn?.(item, this.sortedData.indexOf(item))));
1948
+ (await columnDef.accessorFn?.(item, sortedData.indexOf(item))));
1927
1949
  if (x && typeof x === 'string') {
1928
1950
  targetRow.push(x);
1929
1951
  continue;
@@ -2207,6 +2229,22 @@ export class TableContext {
2207
2229
  };
2208
2230
  });
2209
2231
  }
2232
+ async filteringLoop(currentTimer, abortController, settled, startTime) {
2233
+ for (;;) {
2234
+ if (currentTimer !== this.filterTimer) {
2235
+ if (this.debug) {
2236
+ console.log(`aborting due to stale data`);
2237
+ }
2238
+ abortController.abort('stale data');
2239
+ return;
2240
+ }
2241
+ if (settled.value) {
2242
+ console.log(`iteration ${currentTimer} finished ${Date.now() - startTime}ms`);
2243
+ return;
2244
+ }
2245
+ await tick();
2246
+ }
2247
+ }
2210
2248
  }
2211
2249
  // #region static functions
2212
2250
  function areDefsEquivalent(newColumnDefs, oldColumnDefs) {
@@ -2222,7 +2260,8 @@ function areDefsEquivalent(newColumnDefs, oldColumnDefs) {
2222
2260
  const oldDef = oldColumnDefs.find((d) => d.id === newDef.id);
2223
2261
  if (oldDef === undefined ||
2224
2262
  newDef.header !== oldDef.header ||
2225
- newDef.columnType !== oldDef.columnType
2263
+ newDef.columnType !== oldDef.columnType ||
2264
+ newDef.filterValueType !== oldDef.filterValueType
2226
2265
  // ||
2227
2266
  // newDef.defaultHidden !== oldDef.defaultHidden ||
2228
2267
  // newDef.enableHiding !== oldDef.enableHiding ||