@lavalogic/scoria 0.12.2 → 0.13.1

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 (97) hide show
  1. package/dist/Components/Base/ContextWrapper.svelte +16 -1
  2. package/dist/Components/Base/ContextWrapper.svelte.d.ts +13 -0
  3. package/dist/Components/TabGroupButtonProps.d.ts +1 -1
  4. package/dist/Components/Table/Body/QuickSearchCell.svelte +2 -3
  5. package/dist/Components/Table/Body/Rows/ColumnList.svelte +1 -1
  6. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +1 -1
  7. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +3 -3
  8. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte.d.ts +12 -12
  9. package/dist/Components/Table/Body/Rows/Columns/AccessorComponentProps.d.ts +2 -2
  10. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +27 -17
  11. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte.d.ts +11 -11
  12. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +11 -9
  13. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte.d.ts +12 -12
  14. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +8 -4
  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 +4 -4
  18. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte.d.ts +12 -12
  19. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCellProps.d.ts +2 -2
  20. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +11 -8
  21. package/dist/Components/Table/Body/Rows/Columns/RowSelectionColumn.d.ts +5 -0
  22. package/dist/Components/Table/Body/Rows/Columns/RowSelectionColumn.js +1 -0
  23. package/dist/Components/Table/Body/Rows/Columns/RowSelectionTableCell.d.ts +5 -0
  24. package/dist/Components/Table/Body/Rows/Columns/RowSelectionTableCell.js +1 -0
  25. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +4 -3
  26. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte.d.ts +2 -1
  27. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +16 -9
  28. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte.d.ts +17 -16
  29. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +5 -4
  30. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +10 -8
  31. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte.d.ts +2 -1
  32. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +10 -7
  33. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +11 -7
  34. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte.d.ts +2 -1
  35. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +10 -7
  36. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +11 -9
  37. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte.d.ts +12 -12
  38. package/dist/Components/Table/Body/Rows/Columns/TableTextInputProps.d.ts +2 -2
  39. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +7 -7
  40. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte.d.ts +12 -12
  41. package/dist/Components/Table/Body/Rows/Columns/ValidityCellProps.d.ts +2 -2
  42. package/dist/Components/Table/Body/Rows/TableRow.svelte +7 -6
  43. package/dist/Components/Table/Body/TableBody.svelte +19 -15
  44. package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDefRepository.svelte.d.ts +1 -1
  45. package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDefRepository.svelte.js +17 -2
  46. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +29 -16
  47. package/dist/Components/Table/Headers/SelectAllHeader.svelte +1 -1
  48. package/dist/Components/Table/Headers/TableHead.svelte +1 -1
  49. package/dist/Components/Table/Misc/ColumnPanel.svelte +1 -1
  50. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +1 -1
  51. package/dist/Components/Table/Misc/FilterInput.svelte +1 -3
  52. package/dist/Components/Table/Misc/FilterPanel.svelte +2 -2
  53. package/dist/Components/Table/Misc/FilterPanelModal.svelte +1 -1
  54. package/dist/Components/Table/Misc/TableFooter.svelte +1 -1
  55. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +1 -1
  56. package/dist/Components/Table/Misc/TableSidebar.svelte +2 -1
  57. package/dist/Components/Table/Misc/ToolboxPanel.svelte +2 -2
  58. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +1 -1
  59. package/dist/Components/Table/NestedTable.svelte +12 -8
  60. package/dist/Components/Table/NestedTable.svelte.d.ts +15 -15
  61. package/dist/Components/Table/Table.svelte +111 -118
  62. package/dist/Components/Table/Table.svelte.d.ts +16 -15
  63. package/dist/Components/Table/Types/Columns/Column.d.ts +2 -2
  64. package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.d.ts +2 -2
  65. package/dist/Components/Table/Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.d.ts +6 -6
  66. package/dist/Components/Table/Types/Columns/Definitions/Display/ValidityDef.svelte.d.ts +3 -3
  67. package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.d.ts +6 -6
  68. package/dist/Components/Table/Types/Columns/DefsWrapper.d.ts +2 -2
  69. package/dist/Components/Table/Types/Columns/ExpandColumn.d.ts +3 -2
  70. package/dist/Components/Table/Types/Columns/ExpandTableCell.d.ts +3 -2
  71. package/dist/Components/Table/Types/Columns/ProgressBarTableCell.d.ts +2 -1
  72. package/dist/Components/Table/Types/Columns/TableCell.d.ts +2 -2
  73. package/dist/Components/Table/Types/Context/ITable.d.ts +1 -1
  74. package/dist/Components/Table/Types/Context/TableContext.svelte.d.ts +32 -29
  75. package/dist/Components/Table/Types/Context/TableContext.svelte.js +313 -278
  76. package/dist/Components/Table/Types/Context/TableInitOptions.d.ts +4 -2
  77. package/dist/Components/Table/Types/DataRepository/IDataRepository.d.ts +1 -1
  78. package/dist/Components/Table/Types/DataRepository/ILocalDataRepository.d.ts +1 -2
  79. package/dist/Components/Table/Types/DataRepository/LocalTableDataRepository.svelte.d.ts +2 -1
  80. package/dist/Components/Table/Types/DataRepository/LocalTableDataRepository.svelte.js +31 -8
  81. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.d.ts +2 -1
  82. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.js +4 -1
  83. package/dist/Components/Table/Types/Filtering/CustomFilterFn.d.ts +1 -1
  84. package/dist/Components/Table/Types/Filtering/FilterFn.d.ts +1 -1
  85. package/dist/Components/Table/Types/Focus/TableFocusDetails.svelte.d.ts +7 -6
  86. package/dist/Components/Table/Types/Focus/TableFocusDetails.svelte.js +8 -2
  87. package/dist/Components/VerticalTabGroupButton.svelte +1 -1
  88. package/dist/Components/VerticalTabGroupButton.svelte.d.ts +5 -5
  89. package/dist/Components/VerticalTabGroupProps.d.ts +2 -2
  90. package/dist/Contexts/ToastContext.svelte.d.ts +3 -1
  91. package/dist/Contexts/ToastContext.svelte.js +2 -2
  92. package/dist/Helpers/Helpers.svelte.d.ts +1 -2
  93. package/dist/Types/Examples/ExampleModal.svelte +2 -2
  94. package/dist/Types/Examples/ExampleModal.svelte.d.ts +23 -2
  95. package/dist/Types/Internal/TabOption.d.ts +1 -1
  96. package/dist/index.d.ts +1 -1
  97. package/package.json +18 -18
@@ -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;
@@ -305,12 +329,7 @@ export class TableContext {
305
329
  return this._columnDefs;
306
330
  }
307
331
  set columnDefs(v) {
308
- // if (this._columnDefs.length > 0 && v != this._columnDefs) {
309
- // debugger;
310
- // }
311
332
  this._columnDefs = v;
312
- // this causes an error...?
313
- // this.table = createTable(this.tableOptions);
314
333
  }
315
334
  _columnPresets = $state([]);
316
335
  get columnPresets() {
@@ -358,7 +377,7 @@ export class TableContext {
358
377
  }
359
378
  set focusStart(v) {
360
379
  this._focusStart = v;
361
- this._recalculateFocusedElements();
380
+ this._recalculateFocusedElements().catch(devCatch);
362
381
  }
363
382
  _focusStartIsBeingEdited = $state(false);
364
383
  get focusStartIsBeingEdited() {
@@ -373,7 +392,7 @@ export class TableContext {
373
392
  }
374
393
  set focusEnd(v) {
375
394
  this._focusEnd = v;
376
- this._recalculateFocusedElements();
395
+ this._recalculateFocusedElements().catch(devCatch);
377
396
  }
378
397
  _singleClickEditing = $state(false);
379
398
  get singleClickEditing() {
@@ -445,34 +464,38 @@ export class TableContext {
445
464
  set openModalCoordinates(v) {
446
465
  this._openModalCoordinates = v;
447
466
  }
448
- _allSelectedInCurrentPage = $derived.by(() => {
467
+ _allSelectedInCurrentPage = $derived.by(async () => {
449
468
  if (this.selectedItems.size === 0) {
450
469
  return Promise.resolve(false);
451
470
  }
471
+ void this.paginationRepo?.pageStartIndex;
472
+ void this.columnDefs;
473
+ const sortedData = await this.sortedData;
452
474
  const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
453
475
  const pageEndIndexExclusive = this.paginationRepo
454
- ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
455
- : this.sortedData.length;
476
+ ? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
477
+ : sortedData.length;
456
478
  const selectableMethod = this.columnDefs.find((it) => it instanceof RowSelectionDef)?.isSelectable;
457
- return this.allSelectedBySelectableMethod(pageStartIndex, pageEndIndexExclusive, selectableMethod);
479
+ return await this.allSelectedBySelectableMethod(pageStartIndex, pageEndIndexExclusive, selectableMethod);
458
480
  });
459
481
  get allSelectedInCurrentPage() {
460
482
  return this._allSelectedInCurrentPage;
461
483
  }
462
484
  async allSelectedBySelectableMethod(pageStartIndex, pageEndIndexExclusive, selectableMethod) {
485
+ const sortedData = await this.sortedData;
463
486
  if (selectableMethod) {
464
487
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
465
- const item = this.sortedData[index];
488
+ const item = sortedData[index];
466
489
  if ((await selectableMethod(item, index)) &&
467
- !this.selectedItems.has(this.selectionExtractor(item))) {
490
+ !this.selectedItems.has(await this.selectionExtractor(item))) {
468
491
  return Promise.resolve(false);
469
492
  }
470
493
  }
471
494
  }
472
495
  else {
473
496
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
474
- const item = this.sortedData[index];
475
- if (!this.selectedItems.has(this.selectionExtractor(item))) {
497
+ const item = sortedData[index];
498
+ if (!this.selectedItems.has(await this.selectionExtractor(item))) {
476
499
  return Promise.resolve(false);
477
500
  }
478
501
  }
@@ -480,48 +503,28 @@ export class TableContext {
480
503
  return Promise.resolve(true);
481
504
  }
482
505
  async _areAllHighlighted(pageStartIndex, pageEndIndexExclusive) {
506
+ const sortedData = await this.sortedData;
483
507
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
484
- const item = this.sortedData[index];
485
- if (!this.highlightedItems.has(this.selectionExtractor(item))) {
508
+ const item = sortedData[index];
509
+ if (!this.highlightedItems.has(await this.selectionExtractor(item))) {
486
510
  return Promise.resolve(false);
487
511
  }
488
512
  }
489
513
  return Promise.resolve(true);
490
514
  }
491
- _allHighlighted = $derived.by(() => {
515
+ _allHighlighted = $derived.by(async () => {
492
516
  if (this.highlightedItems.size === 0) {
493
517
  return Promise.resolve(false);
494
518
  }
495
519
  const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
496
520
  const pageEndIndexExclusive = this.paginationRepo
497
- ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
498
- : this.sortedData.length;
499
- return this._areAllHighlighted(pageStartIndex, pageEndIndexExclusive);
521
+ ? Math.min(this.paginationRepo.pageEndIndexExclusive, (await this.sortedData).length)
522
+ : (await this.sortedData).length;
523
+ return await this._areAllHighlighted(pageStartIndex, pageEndIndexExclusive);
500
524
  });
501
525
  get allHighlighted() {
502
526
  return this._allHighlighted;
503
527
  }
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
528
  _hasHighlightedItems = $derived(this.highlightedItems.size > 0);
526
529
  get hasHighlightedItems() {
527
530
  return this._hasHighlightedItems;
@@ -534,18 +537,6 @@ export class TableContext {
534
537
  set selectedItems(v) {
535
538
  this._selectedItems = v;
536
539
  }
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
540
  _invalidValues = $state(new SvelteMap());
550
541
  get invalidValues() {
551
542
  return this._invalidValues;
@@ -591,10 +582,6 @@ export class TableContext {
591
582
  // }
592
583
  return comparableSortingFn(id, desc);
593
584
  };
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
585
  // private _filterTimer: ReturnType<typeof setTimeout> | undefined;
599
586
  _filterTimer = 1;
600
587
  get filterTimer() {
@@ -608,31 +595,43 @@ export class TableContext {
608
595
  return this._filteredIndices;
609
596
  }
610
597
  set filteredIndices(v) {
598
+ if (this.debug) {
599
+ console.log('updating filtered indices');
600
+ }
611
601
  this._filteredIndices = v;
612
602
  }
613
603
  filteredData = $derived.by(() => {
604
+ void this.dataRepo.data;
605
+ void this.filteredIndices;
606
+ void this.showSelectedOnly;
607
+ const dataRepo = this.dataRepo;
614
608
  if (this.paginationRepo?.paginationType == PaginationType.Local) {
615
609
  const data = this.showSelectedOnly
616
610
  ? // FIXME this will show the selected items by order of insertion to the selectedItems map.
617
611
  [...this.selectedItems.values()]
618
612
  : this.filteredIndices.map((index) => {
619
- return this.dataRepo.data[index];
613
+ return dataRepo.data[index];
620
614
  });
621
615
  return data;
622
616
  }
623
- return this.showSelectedOnly ? [...this.selectedItems.values()] : this.dataRepo.data;
617
+ if (this.debug) {
618
+ console.log(`updating filtered data. Selected only: ${this.showSelectedOnly}`);
619
+ }
620
+ return this.showSelectedOnly ? [...this.selectedItems.values()] : dataRepo.data;
624
621
  });
625
- sortedData = $derived.by(() => {
622
+ // eslint-disable-next-line @typescript-eslint/require-await
623
+ sortedData = $derived.by(async () => {
624
+ if (this.debug) {
625
+ console.log('sorted data');
626
+ }
627
+ const fd = this.filteredData;
628
+ const sorting = this.dataRepo.sorting;
626
629
  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;
630
+ const dataToSort = fd.concat();
631
+ dataToSort.sort((a, b) => {
632
+ const end = sorting.length;
634
633
  for (let i = 0; i < end; i++) {
635
- const { id, desc } = state[i];
634
+ const { id, desc } = sorting[i];
636
635
  const sortingFn = this.getSortingFn(id, desc);
637
636
  if (sortingFn) {
638
637
  const result = sortingFn(a, b);
@@ -640,19 +639,27 @@ export class TableContext {
640
639
  return result;
641
640
  }
642
641
  }
643
- else {
642
+ else if (dev) {
644
643
  console.warn('no sorting fn found for ' + id);
645
644
  }
646
645
  }
647
646
  return 0;
648
647
  });
649
- return sortedData;
648
+ return dataToSort;
650
649
  }
651
- return this.filteredData;
650
+ return fd;
652
651
  });
653
- sortedRowModel = $derived.by(() => {
654
- const rows = this.sortedData.map((item, index) => {
655
- const unsortedIndex = this.originalRowIndices.get(item) ?? index;
652
+ sortedRowModel = $derived.by(async () => {
653
+ void this.originalRowIndices;
654
+ void this.sortedData;
655
+ const sd = await this.sortedData;
656
+ const ori = await this.originalRowIndices;
657
+ const rows = await asyncMap(sd, async (item, index) => {
658
+ const originalIndex = ori.get(await this.selectionExtractor(item));
659
+ const unsortedIndex = originalIndex ?? index;
660
+ if (originalIndex == null) {
661
+ throw new Error(`Sorted Data not found in Original Row Indices: original index ${originalIndex}, index ${index}`);
662
+ }
656
663
  return this.createRow(item, index, unsortedIndex);
657
664
  });
658
665
  return {
@@ -661,13 +668,33 @@ export class TableContext {
661
668
  rowsById: new Map(rows.map((it, index) => [index.toString(), it])) //FIXME should this be by sorted id or by original id?
662
669
  };
663
670
  });
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;
671
+ currentPageData = $derived.by(async () => {
672
+ void this.sortedData;
673
+ const dataRepo = this.dataRepo;
674
+ const sd = await this.sortedData;
675
+ if (dataRepo.paginationType != PaginationType.Local) {
676
+ return sd;
677
+ }
678
+ const x = sd.slice(dataRepo.pageStartIndex, dataRepo.pageEndIndexExclusive);
679
+ return x;
680
+ });
681
+ // FIXME this is most likely the cuplrit for add pod not working on receipt. It may be one tick behind the other values
682
+ originalRowIndices = $derived.by(async () => {
683
+ const dataRepo = this.dataRepo;
684
+ const awaited = await asyncMap(dataRepo.data, async (item, index) => [await this.selectionExtractor(item), index]);
685
+ // eslint-disable-next-line svelte/prefer-svelte-reactivity
686
+ return new Map(awaited);
687
+ });
688
+ paginationRowModel = $derived.by(async () => {
689
+ void this.originalRowIndices;
690
+ void this.currentPageData;
691
+ void this.columnDefsById;
692
+ void this.columnVisibility;
693
+ void this.paginationRepo?.sorting;
694
+ void this.columnPinning;
695
+ const currentPageData = await this.currentPageData;
696
+ const rows = await asyncMap(currentPageData, async (item, index) => {
697
+ const unsortedIndex = (await this.originalRowIndices).get(item) ?? index;
671
698
  const row = {
672
699
  getValue: async (key) => {
673
700
  const gotValue = await this.columnDefsById.get(key)?.accessorFn?.(item, index);
@@ -739,44 +766,25 @@ export class TableContext {
739
766
  rowsById: new Map(rows.map((it, index) => [index.toString(), it])) //FIXME should this be by sorted id or by original id?
740
767
  };
741
768
  });
742
- get currentPageData() {
743
- return this._currentPageData;
744
- }
745
769
  // #endregion
746
770
  // #region public methods
747
- selectionContains = (item) => {
771
+ selectionContains = async (item) => {
748
772
  if (!this.isSelectable) {
749
773
  return true;
750
774
  }
751
- return this.selectedItems.has(this.selectionExtractor(item));
775
+ return this.selectedItems.has(await this.selectionExtractor(item));
752
776
  };
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);
777
+ addInvalidValue = async (item) => {
778
+ this.invalidValues.set(await this.selectionExtractor(item), item);
771
779
  };
772
- removeInvalidValue = (item) => {
773
- this.invalidValues.delete(this.selectionExtractor(item));
780
+ removeInvalidValue = async (item) => {
781
+ this.invalidValues.delete(await this.selectionExtractor(item));
774
782
  };
775
783
  setOpenModalCoordinates = (coordinates) => {
776
784
  this.openModalCoordinates = coordinates ? { ...coordinates } : null;
777
785
  };
778
- toggleHighlightedRow = (item) => {
779
- const key = this.selectionExtractor(item);
786
+ toggleHighlightedRow = async (item) => {
787
+ const key = await this.selectionExtractor(item);
780
788
  if (this.highlightedItems.has(key)) {
781
789
  this.highlightedItems.delete(key);
782
790
  }
@@ -784,58 +792,49 @@ export class TableContext {
784
792
  this.highlightedItems.set(key, item);
785
793
  }
786
794
  };
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
795
  resetHighlightedRows = () => {
795
796
  this.highlightedItems.clear();
796
797
  };
797
- toggleSelected = (item, selected) => {
798
- const key = this.selectionExtractor(item);
798
+ toggleSelected = async (item, selected) => {
799
+ const key = await this.selectionExtractor(item);
799
800
  if (selected) {
800
801
  this.selectedItems.set(key, item);
801
802
  }
802
803
  else {
803
804
  this.selectedItems.delete(key);
804
805
  }
805
- this.recalculateAllSelectedInCurrentPage();
806
806
  };
807
807
  setSelectionMap = (set) => {
808
808
  this.selectedItems = set;
809
809
  };
810
810
  updateSelectedItems = async () => {
811
811
  const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
812
+ const sortedData = await this.sortedData;
812
813
  const pageEndIndexExclusive = this.paginationRepo
813
- ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
814
- : this.sortedData.length;
814
+ ? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
815
+ : sortedData.length;
815
816
  const selectableMethod = this.columnDefs.find((it) => it instanceof RowSelectionDef)?.isSelectable;
817
+ const updateSelectedItem = async (item) => {
818
+ const key = await this.selectionExtractor(item);
819
+ if (this.selectedItems.has(key)) {
820
+ //replace selected item with newer version of the same identity
821
+ this.selectedItems.set(key, item);
822
+ }
823
+ };
816
824
  if (selectableMethod) {
817
825
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
818
- const item = this.sortedData[index];
826
+ const item = sortedData[index];
819
827
  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
- }
828
+ await updateSelectedItem(item);
825
829
  }
826
830
  }
827
831
  }
828
832
  else {
829
833
  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
- }
834
+ const item = sortedData[index];
835
+ await updateSelectedItem(item);
836
836
  }
837
837
  }
838
- this.recalculateAllSelectedInCurrentPage();
839
838
  };
840
839
  resetSelectedItems = () => {
841
840
  for (const key of this.selectedItems.keys()) {
@@ -843,25 +842,37 @@ export class TableContext {
843
842
  }
844
843
  this.recalculateAllSelectedInCurrentPage();
845
844
  };
845
+ lastIncrement = Number.MIN_SAFE_INTEGER;
846
846
  recalculateAllSelectedInCurrentPage = () => {
847
- tick()
847
+ const invalidValues = this._invalidValues;
848
+ const allSelectedInCurrentPage = [...this.selectedItems.keys()];
849
+ const currentIncrement = ++this.lastIncrement;
850
+ this.allSelectedInCurrentPage
848
851
  .then(() => {
849
- return this.allSelectedInCurrentPage.then(() => {
850
- this.hasInvalidSelectedItems = [...this.selectedItems.keys()].some((key) => this._invalidValues.has(key));
851
- });
852
+ if (this.lastIncrement == currentIncrement) {
853
+ this.hasInvalidSelectedItems = allSelectedInCurrentPage.some((key) => {
854
+ return invalidValues.has(key);
855
+ });
856
+ }
857
+ else {
858
+ if (dev) {
859
+ console.log('skipping recalculation due to stale data');
860
+ }
861
+ }
852
862
  })
853
863
  .catch(devCatch);
854
864
  };
855
865
  selectAllInCurrentPage = async () => {
866
+ void this.paginationRepo?.pageStartIndex;
867
+ const sortedData = await this.sortedData;
856
868
  if (await this.allSelectedInCurrentPage) {
857
- // this.resetSelectedItems();
858
869
  const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
859
870
  const pageEndIndexExclusive = this.paginationRepo
860
- ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
861
- : this.sortedData.length;
871
+ ? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
872
+ : sortedData.length;
862
873
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
863
- const item = this.sortedData[index];
864
- this.selectedItems.delete(this.selectionExtractor(item));
874
+ const item = sortedData[index];
875
+ this.selectedItems.delete(await this.selectionExtractor(item));
865
876
  }
866
877
  }
867
878
  else {
@@ -869,50 +880,51 @@ export class TableContext {
869
880
  // const selectedItems = new SvelteSet<number>();
870
881
  const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
871
882
  const pageEndIndexExclusive = this.paginationRepo
872
- ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
873
- : this.sortedData.length;
883
+ ? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
884
+ : sortedData.length;
874
885
  const selectableMethod = this.columnDefs.find((it) => it instanceof RowSelectionDef)?.isSelectable;
875
886
  if (selectableMethod) {
876
887
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
877
- const item = this.sortedData[index];
888
+ const item = sortedData[index];
878
889
  if (await selectableMethod(item, index)) {
879
- this.selectedItems.set(this.selectionExtractor(item), item);
890
+ this.selectedItems.set(await this.selectionExtractor(item), item);
880
891
  }
881
892
  }
882
893
  }
883
894
  else {
884
895
  for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
885
- const item = this.sortedData[index];
886
- this.selectedItems.set(this.selectionExtractor(item), item);
896
+ const item = sortedData[index];
897
+ this.selectedItems.set(await this.selectionExtractor(item), item);
887
898
  }
888
899
  }
889
900
  }
890
- this.recalculateAllSelectedInCurrentPage();
891
901
  };
892
902
  onHighlightAll = () => {
893
903
  this.allHighlighted
894
904
  .then((areAllHighlighted) => {
895
905
  if (areAllHighlighted) {
896
906
  this.highlightedItems.clear();
907
+ return Promise.resolve();
897
908
  }
898
909
  else {
899
- this._currentPageData.forEach((item) => {
900
- this.highlightedItems.set(this.selectionExtractor(item), item);
910
+ return this.currentPageData.then((items) => {
911
+ return asyncForEach(items, async (item) => {
912
+ this.highlightedItems.set(await this.selectionExtractor(item), item);
913
+ });
901
914
  });
902
915
  }
903
916
  })
904
917
  .catch(devCatch);
905
918
  };
906
919
  onEditCell = async (item, coords, value) => {
907
- const oldKey = this.selectionExtractor(item);
908
- const wasSelected = oldKey != null && this.selectedItems.has(oldKey);
909
- // debugger;
920
+ const oldKey = await this.selectionExtractor(item);
921
+ const wasSelected = this.selectedItems.has(oldKey);
910
922
  if (wasSelected) {
911
923
  this.selectedItems.delete(oldKey);
912
924
  }
913
925
  await this._onEditCell?.(item, coords, value);
914
926
  if (wasSelected && this.isSelectable) {
915
- const newKey = this.selectionExtractor(item);
927
+ const newKey = await this.selectionExtractor(item);
916
928
  if (newKey) {
917
929
  this.selectedItems.set(newKey, item);
918
930
  }
@@ -941,13 +953,16 @@ export class TableContext {
941
953
  this.tabBackward();
942
954
  }
943
955
  else {
944
- this.tabForward();
956
+ this.tabForward().catch(devCatch);
945
957
  }
946
958
  }
947
959
  if (e.target.tagName === 'INPUT' &&
948
960
  e.target.attributes.getNamedItem('type')?.value !== 'checkbox') {
949
961
  return;
950
962
  }
963
+ this.handleKeystroke(e).catch(devCatch);
964
+ };
965
+ async handleKeystroke(e) {
951
966
  switch (e.key) {
952
967
  case 'Enter':
953
968
  case 'F2':
@@ -955,7 +970,6 @@ export class TableContext {
955
970
  break;
956
971
  }
957
972
  e.preventDefault();
958
- e.stopPropagation();
959
973
  e.target?.dispatchEvent(new CustomEvent('edit', { detail: { selectAll: e.key === 'Enter' } }));
960
974
  // focusStartIsBeingEdited.set(true);
961
975
  break;
@@ -966,20 +980,20 @@ export class TableContext {
966
980
  if (!this.allowCopy) {
967
981
  return;
968
982
  }
969
- this.focusToTop();
983
+ await this.focusToTop();
970
984
  }
971
985
  else {
972
- this.moveToTop();
986
+ await this.moveToTop();
973
987
  }
974
988
  }
975
989
  else if (e.getModifierState('Shift')) {
976
990
  if (!this.allowCopy) {
977
991
  return;
978
992
  }
979
- this.moveFocusUp();
993
+ await this.moveFocusUp();
980
994
  }
981
995
  else {
982
- this.setFocusUp();
996
+ await this.setFocusUp();
983
997
  }
984
998
  return;
985
999
  }
@@ -990,20 +1004,20 @@ export class TableContext {
990
1004
  if (!this.allowCopy) {
991
1005
  return;
992
1006
  }
993
- this.focusToBottom();
1007
+ await this.focusToBottom();
994
1008
  }
995
1009
  else {
996
- this.moveToBottom();
1010
+ await this.moveToBottom();
997
1011
  }
998
1012
  }
999
1013
  else if (e.getModifierState('Shift')) {
1000
1014
  if (!this.allowCopy) {
1001
1015
  return;
1002
1016
  }
1003
- this.moveFocusDown();
1017
+ await this.moveFocusDown();
1004
1018
  }
1005
1019
  else {
1006
- this.setFocusDown();
1020
+ await this.setFocusDown();
1007
1021
  }
1008
1022
  return;
1009
1023
  }
@@ -1058,9 +1072,9 @@ export class TableContext {
1058
1072
  case 'a': {
1059
1073
  if (e.ctrlKey) {
1060
1074
  e.preventDefault();
1061
- this.moveToTop();
1075
+ await this.moveToTop();
1062
1076
  this.moveToStart();
1063
- this.focusToBottom();
1077
+ await this.focusToBottom();
1064
1078
  this.focusToEnd();
1065
1079
  }
1066
1080
  break;
@@ -1069,12 +1083,12 @@ export class TableContext {
1069
1083
  case 'C':
1070
1084
  if (e.getModifierState('Control')) {
1071
1085
  e.preventDefault();
1072
- this.copyDataToClipboard().catch(devCatch);
1086
+ await this.copyDataToClipboard();
1073
1087
  }
1074
1088
  break;
1075
1089
  }
1076
1090
  }
1077
- };
1091
+ }
1078
1092
  toggleQuickFiltering = () => {
1079
1093
  if (this.allowQuickFiltering) {
1080
1094
  const fs = this.focusStart;
@@ -1147,12 +1161,12 @@ export class TableContext {
1147
1161
  if (!browser) {
1148
1162
  return;
1149
1163
  }
1150
- const ctx = getCanvasContext();
1151
- const currentPageContents = this.currentPageData;
1152
1164
  const colId = columnDef.id;
1153
1165
  if (!colId) {
1154
1166
  return;
1155
1167
  }
1168
+ const currentPageContents = await this.currentPageData;
1169
+ const ctx = getCanvasContext();
1156
1170
  let maxWidth = 0;
1157
1171
  if (columnDef.accessorFn) {
1158
1172
  for (let i = currentPageContents.length - 1; i > -1; i--) {
@@ -1325,41 +1339,41 @@ export class TableContext {
1325
1339
  this.focusStart = null;
1326
1340
  this.focusEnd = null;
1327
1341
  };
1328
- focusToTop = () => {
1342
+ focusToTop = async () => {
1329
1343
  if (!this.allowCopy) {
1330
1344
  return;
1331
1345
  }
1332
- this._moveFocusEndRow(-Infinity);
1346
+ return this._moveFocusEndRow(-Infinity);
1333
1347
  };
1334
1348
  focusToBottom = () => {
1335
1349
  if (!this.allowCopy) {
1336
1350
  return;
1337
1351
  }
1338
- this._moveFocusEndRow(Infinity);
1352
+ return this._moveFocusEndRow(Infinity);
1339
1353
  };
1340
- moveToBottom = () => {
1341
- this._moveFocusRow(Infinity);
1354
+ moveToBottom = async () => {
1355
+ return this._moveFocusRow(Infinity);
1342
1356
  };
1343
- moveToTop = () => {
1344
- this._moveFocusRow(-Infinity);
1357
+ moveToTop = async () => {
1358
+ return this._moveFocusRow(-Infinity);
1345
1359
  };
1346
- moveFocusUp = () => {
1360
+ moveFocusUp = async () => {
1347
1361
  if (!this.allowCopy) {
1348
1362
  return;
1349
1363
  }
1350
- this._moveFocusEndRow(-1);
1364
+ return this._moveFocusEndRow(-1);
1351
1365
  };
1352
- setFocusUp = () => {
1353
- this._moveFocusRow(-1);
1366
+ setFocusUp = async () => {
1367
+ return this._moveFocusRow(-1);
1354
1368
  };
1355
- tabForward = () => {
1369
+ tabForward = async () => {
1356
1370
  if (!this.allowCopy) {
1357
1371
  return;
1358
1372
  }
1359
1373
  const defs = this.columnDefs;
1360
1374
  const visibility = this.columnVisibility;
1361
1375
  const indexBounds = defs.length;
1362
- const rowBounds = this.sortedData.length;
1376
+ const rowBounds = (await this.sortedData).length;
1363
1377
  if (!this.focusStart || !rowBounds) {
1364
1378
  return;
1365
1379
  }
@@ -1480,14 +1494,14 @@ export class TableContext {
1480
1494
  }
1481
1495
  //otherwise return without doing anything
1482
1496
  };
1483
- moveFocusDown = () => {
1497
+ moveFocusDown = async () => {
1484
1498
  if (!this.allowCopy) {
1485
1499
  return;
1486
1500
  }
1487
- this._moveFocusEndRow(1);
1501
+ return this._moveFocusEndRow(1);
1488
1502
  };
1489
- setFocusDown = () => {
1490
- this._moveFocusRow(1);
1503
+ setFocusDown = async () => {
1504
+ return this._moveFocusRow(1);
1491
1505
  };
1492
1506
  moveFocusLeft = () => {
1493
1507
  if (!this.allowCopy) {
@@ -1611,6 +1625,9 @@ export class TableContext {
1611
1625
  // }
1612
1626
  // };
1613
1627
  setSelectedPreset = (preset) => {
1628
+ if (this.debug) {
1629
+ console.log('setting selected preset:', preset);
1630
+ }
1614
1631
  this.columnDefs = preset.columnDefs;
1615
1632
  if (!this.paginationRepo?.updateSorting) {
1616
1633
  console.warn('no sorting state found');
@@ -1751,7 +1768,7 @@ export class TableContext {
1751
1768
  };
1752
1769
  localStorage.setItem(`${this.userId}-${this.tableName}-settings`, JSON.stringify(settingsObject));
1753
1770
  }
1754
- _moveFocusEndRow(offset) {
1771
+ async _moveFocusEndRow(offset) {
1755
1772
  if (!this.allowCopy) {
1756
1773
  return;
1757
1774
  }
@@ -1760,27 +1777,27 @@ export class TableContext {
1760
1777
  return;
1761
1778
  }
1762
1779
  const focusEnd = this.focusEnd;
1763
- const rows = this.paginationRowModel.rows;
1780
+ const rows = (await this.paginationRowModel).rows;
1764
1781
  const endRowIndex = rows.findIndex((row) => row.visibleIndex === focusEnd.row);
1765
1782
  this.focusEnd = {
1766
1783
  ...this.focusEnd,
1767
1784
  row: rows[Math.max(Math.min(endRowIndex + offset, rows.length - 1), 0)].visibleIndex
1768
1785
  };
1769
1786
  }
1770
- _moveFocusRow(offset) {
1787
+ async _moveFocusRow(offset) {
1771
1788
  if (!this.focusStart) {
1772
1789
  console.warn('no focusStart found');
1773
1790
  return;
1774
1791
  }
1775
1792
  const focusStart = this.focusStart;
1776
- const newEndRowIndex = (() => {
1777
- const rows = this.paginationRowModel.rows;
1793
+ const newEndRowIndex = await (async () => {
1794
+ const rows = (await this.paginationRowModel).rows;
1778
1795
  const endRowIndex = rows.findIndex((row) => row.visibleIndex === focusStart.row);
1779
1796
  return rows[Math.max(Math.min(endRowIndex + offset, rows.length - 1), 0)].visibleIndex;
1780
1797
  })();
1781
1798
  this.moveFocus({ ...this.focusStart, row: newEndRowIndex });
1782
1799
  }
1783
- _recalculateFocusedElements() {
1800
+ async _recalculateFocusedElements() {
1784
1801
  if (!this.focusStart || !this.focusEnd) {
1785
1802
  this.focusedRowIndexIds = new SvelteSet();
1786
1803
  this.focusedColumnIds = new SvelteSet();
@@ -1788,7 +1805,7 @@ export class TableContext {
1788
1805
  }
1789
1806
  const { row: startRowIndexId, column: startColumnIndex } = this.focusStart;
1790
1807
  const { row: endRowIndexId, column: endColumnIndex } = this.focusEnd;
1791
- const model = this.sortedRowModel;
1808
+ const model = await this.sortedRowModel;
1792
1809
  const startRowIndex = model.rows.findIndex((row) => row.visibleIndex === startRowIndexId);
1793
1810
  const endRowIndex = model.rows.findIndex((row) => row.visibleIndex === endRowIndexId);
1794
1811
  if (startRowIndex == -1 || endRowIndex == -1) {
@@ -1822,11 +1839,12 @@ export class TableContext {
1822
1839
  // eslint-disable-next-line svelte/prefer-svelte-reactivity
1823
1840
  const indices = new Map();
1824
1841
  const selectedRows = [...this.highlightedItems.values()];
1842
+ const sortedData = await this.sortedData;
1825
1843
  for (const item of selectedRows) {
1826
- const rowIndex = this.sortedData.indexOf(item);
1844
+ const rowIndex = sortedData.indexOf(item);
1827
1845
  if (rowIndex == -1) {
1828
- // eslint-disable-next-line no-debugger
1829
- debugger;
1846
+ console.warn(`row index for highlighted row data not found`);
1847
+ continue;
1830
1848
  }
1831
1849
  indices.set(item, rowIndex);
1832
1850
  }
@@ -1835,22 +1853,22 @@ export class TableContext {
1835
1853
  const rowLength = selectedRows.length;
1836
1854
  for (let rowIndex = 0; rowIndex < rowLength; rowIndex++) {
1837
1855
  const item = selectedRows[rowIndex];
1838
- const key = this.selectionExtractor(item);
1856
+ const key = await this.selectionExtractor(item);
1839
1857
  selectedCells[rowIndex] = [];
1840
1858
  const targetRow = selectedCells[rowIndex];
1841
1859
  const colLength = affectedColumns.length;
1842
1860
  for (let colIndex = 0; colIndex < colLength; colIndex++) {
1843
1861
  const columnDef = affectedColumns[colIndex];
1844
1862
  if (columnDef instanceof RowSelectionDef) {
1845
- targetRow.push(key !== undefined && this.selectedItems.has(key) ? 'true' : 'false');
1863
+ targetRow.push(this.selectedItems.has(key) ? 'true' : 'false');
1846
1864
  continue;
1847
1865
  }
1848
1866
  if (uncopyableColumns.has(columnDef.columnType)) {
1849
1867
  continue;
1850
1868
  }
1851
- const x = (await columnDef.getDisplayValue?.(item, this.sortedData.lastIndexOf(item))) ||
1869
+ const x = (await columnDef.getDisplayValue?.(item, sortedData.lastIndexOf(item))) ||
1852
1870
  ('accessorFn' in columnDef &&
1853
- (await columnDef.accessorFn?.(item, this.sortedData.indexOf(item))));
1871
+ (await columnDef.accessorFn?.(item, sortedData.indexOf(item))));
1854
1872
  if (x && typeof x === 'string') {
1855
1873
  targetRow.push(x);
1856
1874
  continue;
@@ -1878,10 +1896,10 @@ export class TableContext {
1878
1896
  const { row: startRowIndexId, column: startColumnIndex } = this.focusStart;
1879
1897
  const { row: endRowIndexId, column: endColumnIndex } = this.focusEnd;
1880
1898
  // const model = this._currentPageData;
1881
- const model = this.paginationRowModel;
1899
+ const model = await this.paginationRowModel;
1882
1900
  const startRowIndex = model.rows.findIndex((row) => row.visibleIndex === startRowIndexId);
1883
1901
  const endRowIndex = model.rows.findIndex((row) => row.visibleIndex === endRowIndexId);
1884
- if (!this._currentPageData.length || startRowIndex == -1 || endRowIndex == -1) {
1902
+ if (!(await this.currentPageData).length || startRowIndex == -1 || endRowIndex == -1) {
1885
1903
  throw new Error(`copy was missing one of the two indices. First: ${startRowIndex}, second: ${endRowIndex}`);
1886
1904
  }
1887
1905
  const minRowIndex = Math.min(startRowIndex, endRowIndex);
@@ -1906,24 +1924,25 @@ export class TableContext {
1906
1924
  // 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
1925
  const selectedCells = [];
1908
1926
  const rowLength = selectedRows.length;
1927
+ const sortedData = await this.sortedData;
1909
1928
  for (let rowIndex = 0; rowIndex < rowLength; rowIndex++) {
1910
1929
  const item = selectedRows[rowIndex];
1911
- const key = this.selectionExtractor(item);
1930
+ const key = await this.selectionExtractor(item);
1912
1931
  selectedCells[rowIndex] = [];
1913
1932
  const targetRow = selectedCells[rowIndex];
1914
1933
  const colLength = affectedColumns.length;
1915
1934
  for (let colIndex = 0; colIndex < colLength; colIndex++) {
1916
1935
  const columnDef = affectedColumns[colIndex];
1917
1936
  if (columnDef instanceof RowSelectionDef) {
1918
- targetRow.push(key !== undefined && this.selectedItems.has(key) ? 'true' : 'false');
1937
+ targetRow.push(this.selectedItems.has(key) ? 'true' : 'false');
1919
1938
  continue;
1920
1939
  }
1921
1940
  if (uncopyableColumns.has(columnDef.columnType)) {
1922
1941
  continue;
1923
1942
  }
1924
- const x = (await columnDef.getDisplayValue?.(item, this.sortedData.lastIndexOf(item))) ||
1943
+ const x = (await columnDef.getDisplayValue?.(item, sortedData.lastIndexOf(item))) ||
1925
1944
  ('accessorFn' in columnDef &&
1926
- (await columnDef.accessorFn?.(item, this.sortedData.indexOf(item))));
1945
+ (await columnDef.accessorFn?.(item, sortedData.indexOf(item))));
1927
1946
  if (x && typeof x === 'string') {
1928
1947
  targetRow.push(x);
1929
1948
  continue;
@@ -2207,6 +2226,22 @@ export class TableContext {
2207
2226
  };
2208
2227
  });
2209
2228
  }
2229
+ async filteringLoop(currentTimer, abortController, settled, startTime) {
2230
+ for (;;) {
2231
+ if (currentTimer !== this.filterTimer) {
2232
+ if (this.debug) {
2233
+ console.log(`aborting due to stale data`);
2234
+ }
2235
+ abortController.abort('stale data');
2236
+ return;
2237
+ }
2238
+ if (settled.value) {
2239
+ console.log(`iteration ${currentTimer} finished ${Date.now() - startTime}ms`);
2240
+ return;
2241
+ }
2242
+ await tick();
2243
+ }
2244
+ }
2210
2245
  }
2211
2246
  // #region static functions
2212
2247
  function areDefsEquivalent(newColumnDefs, oldColumnDefs) {