@lowdefy/blocks-table 0.0.0-experimental-20260929110023

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 (590) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +12 -0
  3. package/dist/blocks/Table/Table.js +25 -0
  4. package/dist/blocks/Table/Table.lazy.js +33 -0
  5. package/dist/blocks/Table/TableFallback.js +35 -0
  6. package/dist/blocks/Table/e2e.js +47 -0
  7. package/dist/blocks/Table/gallery.yaml +836 -0
  8. package/dist/blocks/Table/meta.js +964 -0
  9. package/dist/blocks/Table/tests/Table.e2e.yaml +434 -0
  10. package/dist/blocks/Table/tests/TableFeatures.e2e.yaml +291 -0
  11. package/dist/blocks/Table/tests/TableLinkTarget.e2e.yaml +25 -0
  12. package/dist/blocks/Table/tests/TableParity.e2e.yaml +101 -0
  13. package/dist/blocks/Table/tests/bulk.e2e.yaml +271 -0
  14. package/dist/blocks/Table/tests/deals.yaml +30 -0
  15. package/dist/blocks/Table/tests/deals_columns.yaml +37 -0
  16. package/dist/blocks/Table/tests/editing.e2e.yaml +501 -0
  17. package/dist/blocks/Table/tests/expandable.e2e.yaml +87 -0
  18. package/dist/blocks/Table/tests/filtering.e2e.yaml +251 -0
  19. package/dist/blocks/Table/tests/grouping.e2e.yaml +272 -0
  20. package/dist/blocks/Table/tests/grouping_deals.yaml +24 -0
  21. package/dist/blocks/Table/tests/grouping_deals_columns.yaml +32 -0
  22. package/dist/blocks/Table/tests/headerMenu.e2e.yaml +134 -0
  23. package/dist/blocks/Table/tests/parity_properties.yaml +144 -0
  24. package/dist/blocks/Table/tests/people.yaml +39 -0
  25. package/dist/blocks/Table/tests/people_columns.yaml +22 -0
  26. package/dist/blocks/Table/tests/polish.e2e.yaml +372 -0
  27. package/dist/blocks/Table/tests/server-mongodb.e2e.yaml +169 -0
  28. package/dist/blocks/Table/tests/server.e2e.yaml +267 -0
  29. package/dist/blocks/Table/tests/toolbar.e2e.yaml +140 -0
  30. package/dist/blocks/Table/tests/tree.e2e.yaml +245 -0
  31. package/dist/blocks/Table/tests/views.e2e.yaml +235 -0
  32. package/dist/blocks/TableInput/TableInput.js +24 -0
  33. package/dist/blocks/TableInput/TableInput.lazy.js +17 -0
  34. package/dist/blocks/TableInput/TableInputRoot.js +65 -0
  35. package/dist/blocks/TableInput/e2e.js +16 -0
  36. package/dist/blocks/TableInput/gallery.yaml +153 -0
  37. package/dist/blocks/TableInput/meta.js +93 -0
  38. package/dist/blocks/TableInput/tests/TableInput.e2e.yaml +272 -0
  39. package/dist/blocks.js +16 -0
  40. package/dist/core/Body.js +112 -0
  41. package/dist/core/Cell.js +86 -0
  42. package/dist/core/Chevron.js +32 -0
  43. package/dist/core/EmptyState.js +32 -0
  44. package/dist/core/Grid.js +219 -0
  45. package/dist/core/GroupHeaderRow.js +81 -0
  46. package/dist/core/HeaderCell.js +58 -0
  47. package/dist/core/HeaderRow.js +76 -0
  48. package/dist/core/HeaderTitle.js +49 -0
  49. package/dist/core/LazyCell.js +71 -0
  50. package/dist/core/LoadingRows.js +38 -0
  51. package/dist/core/RenderProbeContext.js +19 -0
  52. package/dist/core/Row.js +98 -0
  53. package/dist/core/SkeletonRow.js +42 -0
  54. package/dist/core/SummaryRow.js +86 -0
  55. package/dist/core/TableRoot.js +195 -0
  56. package/dist/core/aggregateShortLabels.js +25 -0
  57. package/dist/core/applyLayoutVars.js +22 -0
  58. package/dist/core/buildGroupSegments.js +36 -0
  59. package/dist/core/collectBodyOverlays.js +20 -0
  60. package/dist/core/collectCellLeads.js +21 -0
  61. package/dist/core/collectClaimedViewKeys.js +26 -0
  62. package/dist/core/collectGridHandlers.js +29 -0
  63. package/dist/core/collectHeaderParts.js +20 -0
  64. package/dist/core/collectRowRenderers.js +21 -0
  65. package/dist/core/collectSliceDefinitions.js +29 -0
  66. package/dist/core/computeLayout.js +133 -0
  67. package/dist/core/createAccessor.js +39 -0
  68. package/dist/core/createApi.js +86 -0
  69. package/dist/core/createCellActivity.js +47 -0
  70. package/dist/core/createColumnDefs.js +42 -0
  71. package/dist/core/createFeatureActions.js +24 -0
  72. package/dist/core/createFeatureSet.js +39 -0
  73. package/dist/core/createInitialState.js +63 -0
  74. package/dist/core/createKeyIndex.js +26 -0
  75. package/dist/core/createMethodStubs.js +30 -0
  76. package/dist/core/createSliceHandlers.js +26 -0
  77. package/dist/core/createStableCoreRowModel.js +91 -0
  78. package/dist/core/createTanstackFeatures.js +24 -0
  79. package/dist/core/createTextMeasure.js +106 -0
  80. package/dist/core/densityHeights.js +20 -0
  81. package/dist/core/deriveValue.js +53 -0
  82. package/dist/core/dispatchGridEvent.js +21 -0
  83. package/dist/core/distributeFlex.js +28 -0
  84. package/dist/core/getCellFit.js +34 -0
  85. package/dist/core/getHeaderCellProps.js +21 -0
  86. package/dist/core/getHeaderLevels.js +50 -0
  87. package/dist/core/getRecordCount.js +23 -0
  88. package/dist/core/getSummaryLabel.js +35 -0
  89. package/dist/core/getValueSignature.js +26 -0
  90. package/dist/core/isDataItem.js +21 -0
  91. package/dist/core/isDefaultViewColumns.js +36 -0
  92. package/dist/core/isRowEqual.js +40 -0
  93. package/dist/core/isSameSignature.js +19 -0
  94. package/dist/core/lazyCellTypes.js +33 -0
  95. package/dist/core/lazyComponent.js +30 -0
  96. package/dist/core/loadOptionalFeature.js +35 -0
  97. package/dist/core/normalizeViewColumn.js +29 -0
  98. package/dist/core/pickViewPart.js +23 -0
  99. package/dist/core/renderRegion.js +21 -0
  100. package/dist/core/resolveMountValue.js +31 -0
  101. package/dist/core/resolveViewColumns.js +65 -0
  102. package/dist/core/someColumnConfig.js +30 -0
  103. package/dist/core/stabilizeData.js +90 -0
  104. package/dist/core/table.css +557 -0
  105. package/dist/core/useFeatureData.js +35 -0
  106. package/dist/core/useFeatureFragments.js +55 -0
  107. package/dist/core/useFeatureItems.js +78 -0
  108. package/dist/core/useFeatureMethods.js +29 -0
  109. package/dist/core/useFeatureRows.js +36 -0
  110. package/dist/core/useFeatureSet.js +54 -0
  111. package/dist/core/useForeignKeys.js +38 -0
  112. package/dist/core/useGridFeatures.js +26 -0
  113. package/dist/core/useStableConfig.js +34 -0
  114. package/dist/core/useSummary.js +73 -0
  115. package/dist/core/useTableConfig.js +189 -0
  116. package/dist/core/useTableState.js +150 -0
  117. package/dist/core/useViewportSize.js +40 -0
  118. package/dist/e2e.js +16 -0
  119. package/dist/features/bulk/BulkBar.js +46 -0
  120. package/dist/features/bulk/bulk.css +57 -0
  121. package/dist/features/bulk/bulkFeature.js +28 -0
  122. package/dist/features/bulk/countSelection.js +27 -0
  123. package/dist/features/bulk/createSelectAllMatching.js +43 -0
  124. package/dist/features/bulk/useBulkBar.js +42 -0
  125. package/dist/features/clipboard/clipboardFeature.js +24 -0
  126. package/dist/features/clipboard/createPasteCells.js +61 -0
  127. package/dist/features/clipboard/getCopyText.js +57 -0
  128. package/dist/features/clipboard/handleCopyKeyDown.js +37 -0
  129. package/dist/features/clipboard/parseTsv.js +70 -0
  130. package/dist/features/clipboard/pasteFeature.js +26 -0
  131. package/dist/features/clipboard/planPaste.js +101 -0
  132. package/dist/features/clipboard/serializeTsv.js +25 -0
  133. package/dist/features/clipboard/usePasteListener.js +45 -0
  134. package/dist/features/columnManager/ColumnManager.js +253 -0
  135. package/dist/features/columnManager/ColumnManagerPopover.js +37 -0
  136. package/dist/features/columnManager/DragHandleIcon.js +39 -0
  137. package/dist/features/columnManager/LazyColumnManagerPopover.js +19 -0
  138. package/dist/features/columnManager/applyManagerRegions.js +43 -0
  139. package/dist/features/columnManager/boundaryIds.js +21 -0
  140. package/dist/features/columnManager/buildManagerSequence.js +38 -0
  141. package/dist/features/columnManager/columnManager.css +155 -0
  142. package/dist/features/columnManager/columnManagerFeature.js +37 -0
  143. package/dist/features/columnManager/createCloseColumnManager.js +21 -0
  144. package/dist/features/columnManager/createOpenColumnManager.js +21 -0
  145. package/dist/features/columnManager/createResetColumns.js +43 -0
  146. package/dist/features/columnManager/getColumnManagerMenuItems.js +26 -0
  147. package/dist/features/columnManager/getListRoom.js +31 -0
  148. package/dist/features/columnManager/getManagerEntries.js +31 -0
  149. package/dist/features/columnManager/moveSequenceEntry.js +25 -0
  150. package/dist/features/columnManager/sequenceToRegions.js +38 -0
  151. package/dist/features/columnManager/snapListHeight.js +35 -0
  152. package/dist/features/columnManager/updateScrollHints.js +23 -0
  153. package/dist/features/columnManager/useColumnManager.js +36 -0
  154. package/dist/features/density/densityFeature.js +39 -0
  155. package/dist/features/density/densityToValue.js +23 -0
  156. package/dist/features/density/getViewWrapColumn.js +53 -0
  157. package/dist/features/density/initDensity.js +27 -0
  158. package/dist/features/density/initWrap.js +23 -0
  159. package/dist/features/editing/AddRowButton.js +28 -0
  160. package/dist/features/editing/CellEditor.js +284 -0
  161. package/dist/features/editing/EditMarker.js +38 -0
  162. package/dist/features/editing/EditingLayer.js +148 -0
  163. package/dist/features/editing/RowControlsCell.js +89 -0
  164. package/dist/features/editing/RowControlsHeader.js +18 -0
  165. package/dist/features/editing/SelectedTag.js +33 -0
  166. package/dist/features/editing/addChangeRow.js +34 -0
  167. package/dist/features/editing/applyChangeUpdates.js +28 -0
  168. package/dist/features/editing/applyChanges.js +90 -0
  169. package/dist/features/editing/applyMoveOverlay.js +44 -0
  170. package/dist/features/editing/applyMoveToChanges.js +66 -0
  171. package/dist/features/editing/applyOverlay.js +41 -0
  172. package/dist/features/editing/coerceCellValue.js +187 -0
  173. package/dist/features/editing/collectRawColumns.js +38 -0
  174. package/dist/features/editing/computeEditTargets.js +108 -0
  175. package/dist/features/editing/computeRowMove.js +78 -0
  176. package/dist/features/editing/createAddRow.js +68 -0
  177. package/dist/features/editing/createCancelEdit.js +29 -0
  178. package/dist/features/editing/createCommitEdit.js +124 -0
  179. package/dist/features/editing/createDeleteRow.js +39 -0
  180. package/dist/features/editing/createEditSpecs.js +80 -0
  181. package/dist/features/editing/createEmptyChanges.js +23 -0
  182. package/dist/features/editing/createMoveRow.js +65 -0
  183. package/dist/features/editing/createNewRow.js +32 -0
  184. package/dist/features/editing/createResetChanges.js +29 -0
  185. package/dist/features/editing/createSaveCellEdit.js +113 -0
  186. package/dist/features/editing/createSaveRowMove.js +90 -0
  187. package/dist/features/editing/createStartEdit.js +57 -0
  188. package/dist/features/editing/createStepHistory.js +33 -0
  189. package/dist/features/editing/createUndoStack.js +67 -0
  190. package/dist/features/editing/createValueStore.js +34 -0
  191. package/dist/features/editing/createWriteCell.js +34 -0
  192. package/dist/features/editing/createWriteChanges.js +43 -0
  193. package/dist/features/editing/editing.css +223 -0
  194. package/dist/features/editing/editingFeature.js +66 -0
  195. package/dist/features/editing/findCellByKey.js +23 -0
  196. package/dist/features/editing/findInvalidCells.js +41 -0
  197. package/dist/features/editing/findNextEditableCell.js +54 -0
  198. package/dist/features/editing/focusCell.js +28 -0
  199. package/dist/features/editing/fromDateValue.js +29 -0
  200. package/dist/features/editing/fromEditorDraft.js +45 -0
  201. package/dist/features/editing/generateRowKey.js +25 -0
  202. package/dist/features/editing/getDataGap.js +28 -0
  203. package/dist/features/editing/getEditOptions.js +33 -0
  204. package/dist/features/editing/getEditorKind.js +36 -0
  205. package/dist/features/editing/getEventError.js +24 -0
  206. package/dist/features/editing/getKeyField.js +23 -0
  207. package/dist/features/editing/getReorderBlock.js +33 -0
  208. package/dist/features/editing/handleEditDoubleClick.js +34 -0
  209. package/dist/features/editing/handleEditKeyDown.js +123 -0
  210. package/dist/features/editing/handleRowControlsClick.js +29 -0
  211. package/dist/features/editing/handleRowDragPointerDown.js +95 -0
  212. package/dist/features/editing/isCellEditable.js +20 -0
  213. package/dist/features/editing/isPrintableKey.js +22 -0
  214. package/dist/features/editing/isSameTargets.js +19 -0
  215. package/dist/features/editing/matchOption.js +21 -0
  216. package/dist/features/editing/needsEditing.js +26 -0
  217. package/dist/features/editing/normalizeChanges.js +37 -0
  218. package/dist/features/editing/positionBetween.js +30 -0
  219. package/dist/features/editing/pruneOverlay.js +39 -0
  220. package/dist/features/editing/removeChangeRow.js +48 -0
  221. package/dist/features/editing/reorderByKeys.js +34 -0
  222. package/dist/features/editing/rowControlsColumn.js +33 -0
  223. package/dist/features/editing/setChangeField.js +72 -0
  224. package/dist/features/editing/setRowField.js +23 -0
  225. package/dist/features/editing/sortByPosition.js +31 -0
  226. package/dist/features/editing/toDateValue.js +38 -0
  227. package/dist/features/editing/toEditorDraft.js +56 -0
  228. package/dist/features/editing/toSelectOptions.js +39 -0
  229. package/dist/features/editing/useEditingData.js +199 -0
  230. package/dist/features/editing/useEditingFragments.js +77 -0
  231. package/dist/features/editing/useEditingGrid.js +25 -0
  232. package/dist/features/editing/validateCellValue.js +25 -0
  233. package/dist/features/editing/valuesEqual.js +31 -0
  234. package/dist/features/editing/warnMissingEvent.js +23 -0
  235. package/dist/features/events/createActivateRow.js +54 -0
  236. package/dist/features/events/eventsFeature.js +35 -0
  237. package/dist/features/events/getBodyTarget.js +27 -0
  238. package/dist/features/events/getRowIndex.js +24 -0
  239. package/dist/features/events/handleAuxClick.js +38 -0
  240. package/dist/features/events/handlePointerDown.js +22 -0
  241. package/dist/features/events/handleRowClick.js +57 -0
  242. package/dist/features/events/handleRowDoubleClick.js +45 -0
  243. package/dist/features/events/isTextDrag.js +30 -0
  244. package/dist/features/events/openRowLink.js +29 -0
  245. package/dist/features/expandable/DetailRow.js +57 -0
  246. package/dist/features/expandable/ExpandToggle.js +34 -0
  247. package/dist/features/expandable/expandable.css +40 -0
  248. package/dist/features/expandable/expandableFeature.js +34 -0
  249. package/dist/features/expandable/handleExpandClick.js +25 -0
  250. package/dist/features/expandable/needsExpandable.js +20 -0
  251. package/dist/features/expandable/normalizeExpandable.js +52 -0
  252. package/dist/features/expandable/useExpandableItems.js +101 -0
  253. package/dist/features/expansion/createToggleRowExpanded.js +52 -0
  254. package/dist/features/expansion/expansionFeature.js +31 -0
  255. package/dist/features/expansion/getExpandedIds.js +26 -0
  256. package/dist/features/expansion/initExpanded.js +22 -0
  257. package/dist/features/export/buildCsv.js +39 -0
  258. package/dist/features/export/createExportCsv.js +59 -0
  259. package/dist/features/export/exportFeature.js +25 -0
  260. package/dist/features/export/toCsvField.js +20 -0
  261. package/dist/features/filtering/ChoiceFilter.js +30 -0
  262. package/dist/features/filtering/CloseIcon.js +29 -0
  263. package/dist/features/filtering/ColumnFilter.js +192 -0
  264. package/dist/features/filtering/ColumnFilterPopover.js +38 -0
  265. package/dist/features/filtering/DateFilter.js +80 -0
  266. package/dist/features/filtering/DraftInput.js +37 -0
  267. package/dist/features/filtering/DraftInputNumber.js +36 -0
  268. package/dist/features/filtering/FilterBuilder.js +45 -0
  269. package/dist/features/filtering/FilterGroup.js +116 -0
  270. package/dist/features/filtering/FilterIcon.js +26 -0
  271. package/dist/features/filtering/FilterIndicator.js +40 -0
  272. package/dist/features/filtering/FilterLeaf.js +86 -0
  273. package/dist/features/filtering/LazyColumnFilterPopover.js +19 -0
  274. package/dist/features/filtering/LazyFilterBuilder.js +19 -0
  275. package/dist/features/filtering/NumberFilter.js +43 -0
  276. package/dist/features/filtering/OptionsFilter.js +72 -0
  277. package/dist/features/filtering/RelativeDateEditor.js +90 -0
  278. package/dist/features/filtering/TextFilter.js +51 -0
  279. package/dist/features/filtering/ValueEditor.js +210 -0
  280. package/dist/features/filtering/buildColumnFilter.js +95 -0
  281. package/dist/features/filtering/changeLeafOperator.js +46 -0
  282. package/dist/features/filtering/createApplyFiltering.js +78 -0
  283. package/dist/features/filtering/createClearFilters.js +24 -0
  284. package/dist/features/filtering/createCloseColumnFilter.js +28 -0
  285. package/dist/features/filtering/createConditionFilteredRowModel.js +40 -0
  286. package/dist/features/filtering/createDefaultLeaf.js +31 -0
  287. package/dist/features/filtering/createOpenColumnFilter.js +25 -0
  288. package/dist/features/filtering/createRowTest.js +32 -0
  289. package/dist/features/filtering/createSearchMatcher.js +35 -0
  290. package/dist/features/filtering/createSetFilter.js +27 -0
  291. package/dist/features/filtering/createSetSearch.js +29 -0
  292. package/dist/features/filtering/createUpdateColumnFilter.js +29 -0
  293. package/dist/features/filtering/defaultRelativeDate.js +20 -0
  294. package/dist/features/filtering/filterRowModel.js +66 -0
  295. package/dist/features/filtering/filtering.css +151 -0
  296. package/dist/features/filtering/filteringFeature.js +82 -0
  297. package/dist/features/filtering/filteringToValue.js +23 -0
  298. package/dist/features/filtering/formatFilterDate.js +24 -0
  299. package/dist/features/filtering/getColumnConditions.js +24 -0
  300. package/dist/features/filtering/getConditionKeys.js +31 -0
  301. package/dist/features/filtering/getDistinctOptions.js +52 -0
  302. package/dist/features/filtering/getFilterKind.js +37 -0
  303. package/dist/features/filtering/getFilterResultKey.js +26 -0
  304. package/dist/features/filtering/getFilterResults.js +53 -0
  305. package/dist/features/filtering/getFilteredKeys.js +31 -0
  306. package/dist/features/filtering/getFilteringHeaderProps.js +22 -0
  307. package/dist/features/filtering/getFilteringMenuItems.js +42 -0
  308. package/dist/features/filtering/getFilteringTableOptions.js +33 -0
  309. package/dist/features/filtering/getGroupOperator.js +23 -0
  310. package/dist/features/filtering/getOperatorLabel.js +50 -0
  311. package/dist/features/filtering/getPlainTitle.js +26 -0
  312. package/dist/features/filtering/getSearchColumns.js +23 -0
  313. package/dist/features/filtering/getSearchKey.js +19 -0
  314. package/dist/features/filtering/getSearchText.js +57 -0
  315. package/dist/features/filtering/getTopLevelConditions.js +25 -0
  316. package/dist/features/filtering/getValueShape.js +30 -0
  317. package/dist/features/filtering/handleFilterIndicatorClick.js +25 -0
  318. package/dist/features/filtering/initFilter.js +25 -0
  319. package/dist/features/filtering/initSearch.js +24 -0
  320. package/dist/features/filtering/isColumnCondition.js +22 -0
  321. package/dist/features/filtering/isCompleteLeaf.js +45 -0
  322. package/dist/features/filtering/isServerMode.js +21 -0
  323. package/dist/features/filtering/normalizeSearch.js +21 -0
  324. package/dist/features/filtering/parseColumnFilter.js +128 -0
  325. package/dist/features/filtering/parseFilterDate.js +24 -0
  326. package/dist/features/filtering/prepareFilterResult.js +63 -0
  327. package/dist/features/filtering/pruneCondition.js +35 -0
  328. package/dist/features/filtering/setColumnFilter.js +51 -0
  329. package/dist/features/filtering/textFilterOperators.js +26 -0
  330. package/dist/features/filtering/toRootGroup.js +34 -0
  331. package/dist/features/filtering/useDraft.js +65 -0
  332. package/dist/features/filtering/useFilteringState.js +32 -0
  333. package/dist/features/filtering/useSyncedState.js +45 -0
  334. package/dist/features/grouping/GroupCell.js +72 -0
  335. package/dist/features/grouping/GroupCheckbox.js +38 -0
  336. package/dist/features/grouping/GroupLabel.js +73 -0
  337. package/dist/features/grouping/GroupRow.js +103 -0
  338. package/dist/features/grouping/StickyGroupRow.js +136 -0
  339. package/dist/features/grouping/buildGroupTree.js +138 -0
  340. package/dist/features/grouping/buildStickyLevels.js +35 -0
  341. package/dist/features/grouping/countGroupSelection.js +26 -0
  342. package/dist/features/grouping/createAggregateColumns.js +38 -0
  343. package/dist/features/grouping/createCollapseAllGroups.js +26 -0
  344. package/dist/features/grouping/createExpandAllGroups.js +23 -0
  345. package/dist/features/grouping/createGroupLevels.js +46 -0
  346. package/dist/features/grouping/createSetCollapsedGroups.js +27 -0
  347. package/dist/features/grouping/createSetGroup.js +35 -0
  348. package/dist/features/grouping/createSetGroupKeys.js +27 -0
  349. package/dist/features/grouping/createToggleGroup.js +38 -0
  350. package/dist/features/grouping/createToggleGroupSelected.js +49 -0
  351. package/dist/features/grouping/findGroupIndices.js +25 -0
  352. package/dist/features/grouping/flattenGroups.js +58 -0
  353. package/dist/features/grouping/getGroupLabel.js +34 -0
  354. package/dist/features/grouping/getStickyGroups.js +60 -0
  355. package/dist/features/grouping/groupRowsFeature.js +57 -0
  356. package/dist/features/grouping/grouping.css +128 -0
  357. package/dist/features/grouping/groupingFeature.js +48 -0
  358. package/dist/features/grouping/groupingHeaderMenuItems.js +44 -0
  359. package/dist/features/grouping/groupingToValue.js +26 -0
  360. package/dist/features/grouping/handleGroupClick.js +51 -0
  361. package/dist/features/grouping/handleGroupKeyDown.js +60 -0
  362. package/dist/features/grouping/initAggregates.js +36 -0
  363. package/dist/features/grouping/initCollapsedGroups.js +29 -0
  364. package/dist/features/grouping/initGrouping.js +34 -0
  365. package/dist/features/grouping/needsGroupRows.js +23 -0
  366. package/dist/features/grouping/orderGroups.js +49 -0
  367. package/dist/features/grouping/resolveAggregates.js +29 -0
  368. package/dist/features/grouping/toGroupIdentity.js +24 -0
  369. package/dist/features/grouping/toGroupKeys.js +24 -0
  370. package/dist/features/grouping/useGrouping.js +91 -0
  371. package/dist/features/headerMenu/HeaderMenuDropdown.js +86 -0
  372. package/dist/features/headerMenu/HeaderMenuTrigger.js +44 -0
  373. package/dist/features/headerMenu/LazyHeaderMenuDropdown.js +19 -0
  374. package/dist/features/headerMenu/MenuIcon.js +38 -0
  375. package/dist/features/headerMenu/collectHeaderMenuItems.js +69 -0
  376. package/dist/features/headerMenu/createAutosizeColumn.js +35 -0
  377. package/dist/features/headerMenu/createCloseHeaderMenu.js +28 -0
  378. package/dist/features/headerMenu/createOpenHeaderMenu.js +30 -0
  379. package/dist/features/headerMenu/focusHeaderControl.js +31 -0
  380. package/dist/features/headerMenu/freezeColumns.js +31 -0
  381. package/dist/features/headerMenu/getChromeMenuItems.js +144 -0
  382. package/dist/features/headerMenu/getVisibleOrder.js +19 -0
  383. package/dist/features/headerMenu/handleHeaderButtonPointerDown.js +27 -0
  384. package/dist/features/headerMenu/handleHeaderMenuClick.js +26 -0
  385. package/dist/features/headerMenu/handleHeaderMenuKeyDown.js +28 -0
  386. package/dist/features/headerMenu/headerMenu.css +122 -0
  387. package/dist/features/headerMenu/headerMenuFeature.js +46 -0
  388. package/dist/features/headerMenu/measureColumnWidth.js +51 -0
  389. package/dist/features/headerMenu/pinColumn.js +27 -0
  390. package/dist/features/headerMenu/sectionOrder.js +25 -0
  391. package/dist/features/headerMenu/useHeaderMenuState.js +27 -0
  392. package/dist/features/index.js +149 -0
  393. package/dist/features/keyboard/findCellElement.js +21 -0
  394. package/dist/features/keyboard/getNextCell.js +74 -0
  395. package/dist/features/keyboard/handleGridFocus.js +31 -0
  396. package/dist/features/keyboard/handleGridKeyDown.js +72 -0
  397. package/dist/features/keyboard/isCellRendered.js +22 -0
  398. package/dist/features/keyboard/keyboardFeature.js +26 -0
  399. package/dist/features/keyboard/useKeyboard.js +84 -0
  400. package/dist/features/lazyCells/getBodyRowKey.js +19 -0
  401. package/dist/features/lazyCells/handlePointerLeave.js +21 -0
  402. package/dist/features/lazyCells/handlePointerOver.js +22 -0
  403. package/dist/features/lazyCells/handleRowBlur.js +22 -0
  404. package/dist/features/lazyCells/handleRowFocus.js +26 -0
  405. package/dist/features/lazyCells/lazyCellsFeature.js +33 -0
  406. package/dist/features/lazyCells/useFastScroll.js +57 -0
  407. package/dist/features/ordering/getColumnClientBounds.js +32 -0
  408. package/dist/features/ordering/handleReorderPointerDown.js +137 -0
  409. package/dist/features/ordering/initColumnOrder.js +18 -0
  410. package/dist/features/ordering/moveKeys.js +27 -0
  411. package/dist/features/ordering/orderingFeature.js +35 -0
  412. package/dist/features/pagination/TablePagination.js +31 -0
  413. package/dist/features/pagination/initPageSize.js +28 -0
  414. package/dist/features/pagination/paginationFeature.js +36 -0
  415. package/dist/features/pagination/paginationToValue.js +24 -0
  416. package/dist/features/pagination/usePager.js +32 -0
  417. package/dist/features/pagination/usePagination.js +58 -0
  418. package/dist/features/pinning/initColumnPinning.js +21 -0
  419. package/dist/features/pinning/pinningFeature.js +33 -0
  420. package/dist/features/pinning/pinningToViewColumn.js +24 -0
  421. package/dist/features/queue/createAfterRowAction.js +40 -0
  422. package/dist/features/queue/findNextRowId.js +26 -0
  423. package/dist/features/queue/findRowAction.js +77 -0
  424. package/dist/features/queue/handleRowActionKey.js +44 -0
  425. package/dist/features/queue/queueFeature.js +27 -0
  426. package/dist/features/selection/SelectAllHeader.js +40 -0
  427. package/dist/features/selection/SelectCell.js +30 -0
  428. package/dist/features/selection/countSelectedRows.js +31 -0
  429. package/dist/features/selection/createClearSelection.js +29 -0
  430. package/dist/features/selection/createToggleAllRowsSelected.js +60 -0
  431. package/dist/features/selection/createToggleRowSelected.js +86 -0
  432. package/dist/features/selection/getRawRowKey.js +23 -0
  433. package/dist/features/selection/getSelectAllExcept.js +23 -0
  434. package/dist/features/selection/getSelectAllState.js +42 -0
  435. package/dist/features/selection/handleSelectionClick.js +30 -0
  436. package/dist/features/selection/initRowSelection.js +36 -0
  437. package/dist/features/selection/initSelectionMode.js +19 -0
  438. package/dist/features/selection/initSelectionView.js +35 -0
  439. package/dist/features/selection/isSelectAllValue.js +19 -0
  440. package/dist/features/selection/isSelectionViewCurrent.js +22 -0
  441. package/dist/features/selection/notifySelectionChange.js +32 -0
  442. package/dist/features/selection/pruneRowSelection.js +26 -0
  443. package/dist/features/selection/selectionFeature.js +69 -0
  444. package/dist/features/selection/selectionToValue.js +48 -0
  445. package/dist/features/selection/useSelection.js +77 -0
  446. package/dist/features/serverData/buildServerItems.js +109 -0
  447. package/dist/features/serverData/createBlockCache.js +205 -0
  448. package/dist/features/serverData/createRefresh.js +23 -0
  449. package/dist/features/serverData/createServerStore.js +360 -0
  450. package/dist/features/serverData/getBlockRange.js +29 -0
  451. package/dist/features/serverData/getListKey.js +20 -0
  452. package/dist/features/serverData/getNeededBlocks.js +45 -0
  453. package/dist/features/serverData/needsServerData.js +20 -0
  454. package/dist/features/serverData/normalizeServerData.js +41 -0
  455. package/dist/features/serverData/pickServerView.js +43 -0
  456. package/dist/features/serverData/readFetchResult.js +36 -0
  457. package/dist/features/serverData/serverData.css +21 -0
  458. package/dist/features/serverData/serverDataFeature.js +38 -0
  459. package/dist/features/serverData/serverRangeFeature.js +22 -0
  460. package/dist/features/serverData/useServerData.js +48 -0
  461. package/dist/features/serverData/useServerItems.js +35 -0
  462. package/dist/features/serverData/useServerRange.js +35 -0
  463. package/dist/features/serverData/useServerView.js +70 -0
  464. package/dist/features/sizing/ResizeHandle.js +24 -0
  465. package/dist/features/sizing/handleResizePointerDown.js +66 -0
  466. package/dist/features/sizing/initColumnSizing.js +23 -0
  467. package/dist/features/sizing/sizingFeature.js +39 -0
  468. package/dist/features/sizing/sizingToViewColumn.js +24 -0
  469. package/dist/features/sorting/SortIndicator.js +37 -0
  470. package/dist/features/sorting/buildSortKeys.js +52 -0
  471. package/dist/features/sorting/collectSortKeys.js +30 -0
  472. package/dist/features/sorting/createClearSort.js +21 -0
  473. package/dist/features/sorting/createIndexSortedRowModel.js +33 -0
  474. package/dist/features/sorting/createSetSort.js +43 -0
  475. package/dist/features/sorting/createSortKeyCollector.js +59 -0
  476. package/dist/features/sorting/createToggleSort.js +42 -0
  477. package/dist/features/sorting/getCachedSortKeys.js +19 -0
  478. package/dist/features/sorting/getSortHeaderProps.js +25 -0
  479. package/dist/features/sorting/getSortKeys.js +38 -0
  480. package/dist/features/sorting/handleSortClick.js +27 -0
  481. package/dist/features/sorting/initSorting.js +37 -0
  482. package/dist/features/sorting/isNumericSortType.js +21 -0
  483. package/dist/features/sorting/prepareSortKeys.js +92 -0
  484. package/dist/features/sorting/rankSortKeys.js +33 -0
  485. package/dist/features/sorting/setCachedSortKeys.js +24 -0
  486. package/dist/features/sorting/sortInSlices.js +69 -0
  487. package/dist/features/sorting/sortIndices.js +40 -0
  488. package/dist/features/sorting/sortKeysCache.js +19 -0
  489. package/dist/features/sorting/sortRowModel.js +84 -0
  490. package/dist/features/sorting/sortingFeature.js +62 -0
  491. package/dist/features/sorting/sortingToValue.js +27 -0
  492. package/dist/features/sorting/toFloatSortKeys.js +24 -0
  493. package/dist/features/sorting/yieldToMain.js +27 -0
  494. package/dist/features/toolbar/ColumnTitle.js +28 -0
  495. package/dist/features/toolbar/DensityToggle.js +53 -0
  496. package/dist/features/toolbar/FilterButton.js +56 -0
  497. package/dist/features/toolbar/GroupButton.js +51 -0
  498. package/dist/features/toolbar/OptionsQuickFilter.js +72 -0
  499. package/dist/features/toolbar/QuickFilter.js +46 -0
  500. package/dist/features/toolbar/RecordCount.js +27 -0
  501. package/dist/features/toolbar/SaveViewAs.js +66 -0
  502. package/dist/features/toolbar/SortButton.js +94 -0
  503. package/dist/features/toolbar/Toolbar.js +88 -0
  504. package/dist/features/toolbar/ToolbarCount.js +25 -0
  505. package/dist/features/toolbar/ToolbarIcon.js +28 -0
  506. package/dist/features/toolbar/ToolbarList.js +100 -0
  507. package/dist/features/toolbar/ToolbarSearch.js +63 -0
  508. package/dist/features/toolbar/ViewActions.js +41 -0
  509. package/dist/features/toolbar/ViewTabLabel.js +39 -0
  510. package/dist/features/toolbar/ViewTabMenu.js +48 -0
  511. package/dist/features/toolbar/ViewTabs.js +44 -0
  512. package/dist/features/toolbar/countConditions.js +25 -0
  513. package/dist/features/toolbar/formatRecordCount.js +19 -0
  514. package/dist/features/toolbar/getQuickFilterValues.js +25 -0
  515. package/dist/features/toolbar/getRootConditions.js +25 -0
  516. package/dist/features/toolbar/handleToolbarKeyDown.js +28 -0
  517. package/dist/features/toolbar/isDefaultSorting.js +26 -0
  518. package/dist/features/toolbar/isQuickFilterLeaf.js +20 -0
  519. package/dist/features/toolbar/moveItem.js +25 -0
  520. package/dist/features/toolbar/needsToolbar.js +21 -0
  521. package/dist/features/toolbar/normalizeToolbar.js +61 -0
  522. package/dist/features/toolbar/setQuickFilterValues.js +35 -0
  523. package/dist/features/toolbar/toolbar.css +185 -0
  524. package/dist/features/toolbar/toolbarFeature.js +27 -0
  525. package/dist/features/toolbar/useToolbar.js +41 -0
  526. package/dist/features/toolbar/validateQuickFilters.js +28 -0
  527. package/dist/features/transactions/applyTransactionToRows.js +56 -0
  528. package/dist/features/transactions/createApplyTransaction.js +26 -0
  529. package/dist/features/transactions/normalizeTransaction.js +49 -0
  530. package/dist/features/transactions/transactionsFeature.js +24 -0
  531. package/dist/features/transactions/useTransactionData.js +44 -0
  532. package/dist/features/tree/TreeToggle.js +39 -0
  533. package/dist/features/tree/buildTreeIndex.js +60 -0
  534. package/dist/features/tree/buildTreeItems.js +96 -0
  535. package/dist/features/tree/flattenTreeData.js +45 -0
  536. package/dist/features/tree/getDescendantIds.js +28 -0
  537. package/dist/features/tree/handleTreeClick.js +25 -0
  538. package/dist/features/tree/handleTreeKeyDown.js +58 -0
  539. package/dist/features/tree/needsTree.js +20 -0
  540. package/dist/features/tree/normalizeTree.js +41 -0
  541. package/dist/features/tree/rowNeedsChildren.js +25 -0
  542. package/dist/features/tree/tree.css +55 -0
  543. package/dist/features/tree/treeFeature.js +35 -0
  544. package/dist/features/tree/useTreeData.js +33 -0
  545. package/dist/features/tree/useTreeItems.js +61 -0
  546. package/dist/features/views/compactView.js +30 -0
  547. package/dist/features/views/createViewsApi.js +74 -0
  548. package/dist/features/views/decodeViewParam.js +30 -0
  549. package/dist/features/views/encodeViewParam.js +25 -0
  550. package/dist/features/views/findActiveView.js +23 -0
  551. package/dist/features/views/getStorageKey.js +20 -0
  552. package/dist/features/views/getViewKey.js +27 -0
  553. package/dist/features/views/getViewSliceDeps.js +27 -0
  554. package/dist/features/views/isViewDirty.js +34 -0
  555. package/dist/features/views/mountViewValue.js +36 -0
  556. package/dist/features/views/needsViews.js +23 -0
  557. package/dist/features/views/normalizePersist.js +27 -0
  558. package/dist/features/views/normalizeViews.js +41 -0
  559. package/dist/features/views/notifyViewSelect.js +29 -0
  560. package/dist/features/views/readMountPayload.js +31 -0
  561. package/dist/features/views/readPersistedView.js +45 -0
  562. package/dist/features/views/sanitizePersistedView.js +49 -0
  563. package/dist/features/views/stableStringify.js +27 -0
  564. package/dist/features/views/useViews.js +136 -0
  565. package/dist/features/views/viewKeys.js +28 -0
  566. package/dist/features/views/viewsFeature.js +26 -0
  567. package/dist/features/views/writePersistedView.js +42 -0
  568. package/dist/features/virtualization/computeRowOffsets.js +29 -0
  569. package/dist/features/virtualization/computeWindow.js +92 -0
  570. package/dist/features/virtualization/createScrollToRow.js +36 -0
  571. package/dist/features/virtualization/firstIndexAbove.js +30 -0
  572. package/dist/features/virtualization/getMeasureKey.js +23 -0
  573. package/dist/features/virtualization/isMeasuredColumn.js +20 -0
  574. package/dist/features/virtualization/isSameRange.js +18 -0
  575. package/dist/features/virtualization/positionedRowsFeature.js +22 -0
  576. package/dist/features/virtualization/scrollToCell.js +49 -0
  577. package/dist/features/virtualization/shiftRowOffsets.js +35 -0
  578. package/dist/features/virtualization/usePositionedRows.js +37 -0
  579. package/dist/features/virtualization/useRowOffsets.js +123 -0
  580. package/dist/features/virtualization/useScrollWindow.js +114 -0
  581. package/dist/features/virtualization/useTanstackRowWindow.js +43 -0
  582. package/dist/features/virtualization/useVirtualization.js +64 -0
  583. package/dist/features/virtualization/virtualizationFeature.js +24 -0
  584. package/dist/features/virtualization/writeScrollEdges.js +33 -0
  585. package/dist/features/visibility/initColumnVisibility.js +22 -0
  586. package/dist/features/visibility/visibilityFeature.js +31 -0
  587. package/dist/features/visibility/visibilityToViewColumn.js +20 -0
  588. package/dist/metas.js +16 -0
  589. package/dist/types.js +17 -0
  590. package/package.json +91 -0
@@ -0,0 +1,205 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import getBlockRange from './getBlockRange.js';
16
+ function getBlockId({ listKey, index }) {
17
+ return `${listKey}#${index}`;
18
+ }
19
+ // Rows of one server view, in blocks of `blockSize` per list (the root list and each expanded
20
+ // group's list). Blocks are evicted least recently used beyond `maxBlocks` loaded blocks, never
21
+ // one the caller still needs (`keep`) or one that is loading.
22
+ //
23
+ // `generation` counts invalidations. A load records the generation it started in and its
24
+ // response is only accepted if nothing invalidated the cache since (triggerEvent cannot be
25
+ // aborted, so stale responses are ignored instead). An invalidated block keeps its rows on screen
26
+ // until its reload lands.
27
+ function createBlockCache({ blockSize, maxBlocks }) {
28
+ const lists = new Map();
29
+ // Map iteration order is insertion order: touching a block re-inserts it, so the first entry
30
+ // is always the least recently used.
31
+ const blocks = new Map();
32
+ let generation = 0;
33
+ let loadedCount = 0;
34
+ function getList(listKey) {
35
+ let list = lists.get(listKey);
36
+ if (!list) {
37
+ list = {
38
+ total: null,
39
+ aggregates: null,
40
+ error: null
41
+ };
42
+ lists.set(listKey, list);
43
+ }
44
+ return list;
45
+ }
46
+ function evict(keep) {
47
+ for (const [id, block] of blocks){
48
+ if (loadedCount <= maxBlocks) return;
49
+ if (block.status !== 'loaded' || keep?.has(id)) continue;
50
+ blocks.delete(id);
51
+ loadedCount -= 1;
52
+ }
53
+ }
54
+ function setStatus(block, status) {
55
+ if (block.status === 'loaded') loadedCount -= 1;
56
+ if (status === 'loaded') loadedCount += 1;
57
+ block.status = status;
58
+ }
59
+ const cache = {
60
+ blockSize,
61
+ getBlockId,
62
+ get generation () {
63
+ return generation;
64
+ },
65
+ get loadedCount () {
66
+ return loadedCount;
67
+ },
68
+ getTotal (listKey) {
69
+ return lists.get(listKey)?.total ?? null;
70
+ },
71
+ getAggregates (listKey) {
72
+ return lists.get(listKey)?.aggregates ?? null;
73
+ },
74
+ getError (listKey) {
75
+ return lists.get(listKey)?.error ?? null;
76
+ },
77
+ hasList (listKey) {
78
+ return lists.has(listKey);
79
+ },
80
+ getBlock (listKey, index) {
81
+ return blocks.get(getBlockId({
82
+ listKey,
83
+ index
84
+ }));
85
+ },
86
+ getRow (listKey, rowIndex) {
87
+ const block = blocks.get(getBlockId({
88
+ listKey,
89
+ index: Math.floor(rowIndex / blockSize)
90
+ }));
91
+ return block?.rows?.[rowIndex % blockSize];
92
+ },
93
+ touch (listKey, index) {
94
+ const id = getBlockId({
95
+ listKey,
96
+ index
97
+ });
98
+ const block = blocks.get(id);
99
+ if (!block) return;
100
+ blocks.delete(id);
101
+ blocks.set(id, block);
102
+ },
103
+ // A block needs a load when it is missing or from an earlier generation. A block loading in
104
+ // this generation, or one that failed in it, does not (a refresh retries failures).
105
+ needsLoad (listKey, index) {
106
+ const block = blocks.get(getBlockId({
107
+ listKey,
108
+ index
109
+ }));
110
+ return !block || block.generation !== generation;
111
+ },
112
+ getMissingBlocks ({ listKey, startRow, endRow }) {
113
+ const { first, last } = getBlockRange({
114
+ startRow,
115
+ endRow,
116
+ blockSize,
117
+ total: cache.getTotal(listKey)
118
+ });
119
+ const missing = [];
120
+ for(let index = first; index <= last; index++){
121
+ if (cache.needsLoad(listKey, index)) missing.push(index);
122
+ }
123
+ return missing;
124
+ },
125
+ startLoad (listKey, index) {
126
+ getList(listKey);
127
+ const id = getBlockId({
128
+ listKey,
129
+ index
130
+ });
131
+ let block = blocks.get(id);
132
+ if (!block) {
133
+ block = {
134
+ listKey,
135
+ index,
136
+ status: 'loading',
137
+ rows: null,
138
+ generation
139
+ };
140
+ blocks.set(id, block);
141
+ } else {
142
+ // An invalidated block keeps its rows (and status) on screen while it reloads.
143
+ block.generation = generation;
144
+ if (block.status !== 'loaded') setStatus(block, 'loading');
145
+ block.reloading = true;
146
+ }
147
+ return {
148
+ generation
149
+ };
150
+ },
151
+ finishLoad ({ listKey, index, generation: loadGeneration, rows, total, aggregates, keep }) {
152
+ if (loadGeneration !== generation) return false;
153
+ const block = blocks.get(getBlockId({
154
+ listKey,
155
+ index
156
+ }));
157
+ if (!block || block.generation !== loadGeneration) return false;
158
+ block.rows = rows;
159
+ block.reloading = false;
160
+ setStatus(block, 'loaded');
161
+ const list = getList(listKey);
162
+ list.total = total;
163
+ list.aggregates = aggregates ?? null;
164
+ list.error = null;
165
+ cache.touch(listKey, index);
166
+ evict(keep);
167
+ return true;
168
+ },
169
+ failLoad ({ listKey, index, generation: loadGeneration, error }) {
170
+ if (loadGeneration !== generation) return false;
171
+ const block = blocks.get(getBlockId({
172
+ listKey,
173
+ index
174
+ }));
175
+ if (!block || block.generation !== loadGeneration) return false;
176
+ block.reloading = false;
177
+ if (block.status !== 'loaded') setStatus(block, 'error');
178
+ getList(listKey).error = error;
179
+ return true;
180
+ },
181
+ invalidate () {
182
+ generation += 1;
183
+ },
184
+ // Visits the loaded rows of every list: `fn(rows, block)`.
185
+ forEachLoaded (fn) {
186
+ blocks.forEach((block)=>{
187
+ if (block.rows) fn(block.rows, block);
188
+ });
189
+ },
190
+ // Replaces a loaded block's rows (a transaction); `total` changes with removed rows.
191
+ setBlockRows ({ listKey, index, rows }) {
192
+ const block = blocks.get(getBlockId({
193
+ listKey,
194
+ index
195
+ }));
196
+ if (block) block.rows = rows;
197
+ },
198
+ adjustTotal (listKey, delta) {
199
+ const list = lists.get(listKey);
200
+ if (list && typeof list.total === 'number') list.total = Math.max(0, list.total + delta);
201
+ }
202
+ };
203
+ return cache;
204
+ }
205
+ export default createBlockCache;
@@ -0,0 +1,23 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ // Block method `refresh()`: in server mode, purges the block cache and refetches the visible
16
+ // blocks (rows stay on screen until they land). In client mode `data` is the app's, so there is
17
+ // nothing to refetch.
18
+ function createRefresh(api) {
19
+ return function refresh() {
20
+ api.serverStore?.refresh();
21
+ };
22
+ }
23
+ export default createRefresh;
@@ -0,0 +1,360 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import applyTransactionToRows from '../transactions/applyTransactionToRows.js';
16
+ import buildServerItems from './buildServerItems.js';
17
+ import createBlockCache from './createBlockCache.js';
18
+ import getBlockRange from './getBlockRange.js';
19
+ import getListKey from './getListKey.js';
20
+ import getNeededBlocks from './getNeededBlocks.js';
21
+ import readFetchResult from './readFetchResult.js';
22
+ const ROOT = getListKey([]);
23
+ // Range changes faster than this (rows per millisecond, about 2000px/s at 40px rows) are a fast
24
+ // scroll or a scrollbar jump: loads wait until the range settles.
25
+ const FAST_ROWS_PER_MS = 0.05;
26
+ const SETTLE_MS = 120;
27
+ // Server mode's data source (D9). It owns the block cache of the current view, fetches blocks
28
+ // through the table's internal `__tableFetch` event, and keeps the previous view's cache on
29
+ // screen (dimmed) until the new view's first block lands. React subscribes to `version`.
30
+ function createServerStore({ api, server }) {
31
+ const { blockSize, maxBlocks } = server;
32
+ const listeners = new Set();
33
+ const store = {
34
+ cache: createBlockCache({
35
+ blockSize,
36
+ maxBlocks
37
+ }),
38
+ previous: null,
39
+ view: null,
40
+ viewKey: null,
41
+ groupKey: null,
42
+ selected: undefined,
43
+ expandedGroups: new Set(),
44
+ segments: [],
45
+ visible: new Set(),
46
+ lastRange: null,
47
+ timer: null,
48
+ version: 0,
49
+ requestCount: 0,
50
+ loadedRows: {
51
+ version: -1,
52
+ rows: [],
53
+ indices: new Map()
54
+ },
55
+ itemCache: new WeakMap()
56
+ };
57
+ function notify() {
58
+ store.version += 1;
59
+ listeners.forEach((listener)=>listener());
60
+ }
61
+ // The cache on screen: the current view's, or the previous view's until the first block of
62
+ // the current one lands.
63
+ function getDisplayCache() {
64
+ if (store.previous && store.cache.getTotal(ROOT) === null && !store.cache.getError(ROOT)) {
65
+ return store.previous;
66
+ }
67
+ return store.cache;
68
+ }
69
+ function fetchBlock({ listKey, groupPath, index }) {
70
+ const { cache } = store;
71
+ if (!cache.needsLoad(listKey, index)) return;
72
+ const { generation } = cache.startLoad(listKey, index);
73
+ const isGroupLevel = groupPath.length < (store.view.group ?? []).length;
74
+ store.requestCount += 1;
75
+ const event = {
76
+ startRow: index * blockSize,
77
+ endRow: (index + 1) * blockSize,
78
+ view: store.view,
79
+ groupPath,
80
+ selected: store.selected
81
+ };
82
+ Promise.resolve(api.methods.triggerEvent({
83
+ name: '__tableFetch',
84
+ event
85
+ })).then((result)=>{
86
+ // A later view has its own cache: this response belongs to a superseded view.
87
+ if (cache !== store.cache) return;
88
+ if (result?.success !== true) {
89
+ if (cache.failLoad({
90
+ listKey,
91
+ index,
92
+ generation,
93
+ error: result?.error ?? true
94
+ })) notify();
95
+ return;
96
+ }
97
+ let read;
98
+ try {
99
+ read = readFetchResult({
100
+ result,
101
+ isGroupLevel
102
+ });
103
+ } catch (error) {
104
+ cache.failLoad({
105
+ listKey,
106
+ index,
107
+ generation,
108
+ error
109
+ });
110
+ notify();
111
+ throw error;
112
+ }
113
+ const accepted = cache.finishLoad({
114
+ listKey,
115
+ index,
116
+ generation,
117
+ rows: read.entries,
118
+ total: read.total,
119
+ aggregates: read.aggregates,
120
+ keep: store.visible
121
+ });
122
+ if (!accepted) return;
123
+ if (listKey === ROOT) store.previous = null;
124
+ notify();
125
+ });
126
+ }
127
+ function loadVisible() {
128
+ store.timer = null;
129
+ const range = store.lastRange;
130
+ if (!range || !store.view) return;
131
+ let needed;
132
+ if (getDisplayCache() !== store.cache) {
133
+ // The items on screen belong to the previous view; only the new root list maps to them.
134
+ const { first, last } = getBlockRange({
135
+ startRow: range.rowStart,
136
+ endRow: range.rowEnd,
137
+ blockSize
138
+ });
139
+ needed = [];
140
+ for(let index = first; index <= last; index++){
141
+ needed.push({
142
+ listKey: ROOT,
143
+ groupPath: [],
144
+ index
145
+ });
146
+ }
147
+ } else {
148
+ needed = getNeededBlocks({
149
+ segments: store.segments,
150
+ rowStart: range.rowStart,
151
+ rowEnd: range.rowEnd,
152
+ blockSize
153
+ });
154
+ }
155
+ store.visible = new Set(needed.map((block)=>store.cache.getBlockId(block)));
156
+ needed.forEach((block)=>{
157
+ store.cache.touch(block.listKey, block.index);
158
+ fetchBlock(block);
159
+ });
160
+ }
161
+ Object.assign(store, {
162
+ subscribe (listener) {
163
+ listeners.add(listener);
164
+ return ()=>listeners.delete(listener);
165
+ },
166
+ isLoading () {
167
+ const display = getDisplayCache();
168
+ return display.getTotal(ROOT) === null && !display.getError(ROOT);
169
+ },
170
+ isPending () {
171
+ return getDisplayCache() !== store.cache;
172
+ },
173
+ getAggregates () {
174
+ return getDisplayCache().getAggregates(ROOT);
175
+ },
176
+ getTotal () {
177
+ return getDisplayCache().getTotal(ROOT);
178
+ },
179
+ // The rows the view matches (the toolbar's record count). A grouped view's root list holds
180
+ // groups, whose counts add up to the rows; before the first block lands it is null.
181
+ getRecordCount () {
182
+ const display = getDisplayCache();
183
+ const total = display.getTotal(ROOT);
184
+ if (total === null || (store.view?.group ?? []).length === 0) return total;
185
+ let count = 0;
186
+ display.forEachLoaded((entries, block)=>{
187
+ if (block.listKey !== ROOT) return;
188
+ entries.forEach((entry)=>{
189
+ count += entry.count;
190
+ });
191
+ });
192
+ return count;
193
+ },
194
+ // The view the request receives: `{ sort, filter, search, group, aggregates }`. A new view
195
+ // gets a new cache and starts from the top; the old rows stay until its first block lands.
196
+ setView ({ view, viewKey }) {
197
+ if (viewKey === store.viewKey) return;
198
+ const initial = store.viewKey === null;
199
+ const groupKey = JSON.stringify(view.group ?? []);
200
+ if (groupKey !== store.groupKey) store.expandedGroups = new Set();
201
+ store.groupKey = groupKey;
202
+ store.view = view;
203
+ store.viewKey = viewKey;
204
+ if (!initial) {
205
+ if (getDisplayCache() === store.cache) store.previous = store.cache;
206
+ store.cache = createBlockCache({
207
+ blockSize,
208
+ maxBlocks
209
+ });
210
+ const scroller = api.scrollerRef.current;
211
+ if (scroller) scroller.scrollTop = 0;
212
+ store.lastRange = null;
213
+ }
214
+ fetchBlock({
215
+ listKey: ROOT,
216
+ groupPath: [],
217
+ index: 0
218
+ });
219
+ notify();
220
+ },
221
+ onRange ({ rowStart, rowEnd }) {
222
+ const now = performance.now();
223
+ const last = store.lastRange;
224
+ if (last && last.rowStart === rowStart && last.rowEnd === rowEnd) {
225
+ // The same range with new items under it (a block landed, a group opened). A fast scroll
226
+ // still waiting to settle keeps waiting: loading here would load every position a
227
+ // landing block happens to find the scroll at.
228
+ if (!store.timer) loadVisible();
229
+ return;
230
+ }
231
+ const velocity = last ? Math.abs(rowStart - last.rowStart) / Math.max(1, now - last.time) : 0;
232
+ store.lastRange = {
233
+ rowStart,
234
+ rowEnd,
235
+ time: now
236
+ };
237
+ if (store.timer) clearTimeout(store.timer);
238
+ if (velocity <= FAST_ROWS_PER_MS) {
239
+ loadVisible();
240
+ return;
241
+ }
242
+ store.timer = setTimeout(loadVisible, SETTLE_MS);
243
+ },
244
+ buildItems ({ rowsById, getId }) {
245
+ const built = buildServerItems({
246
+ blockCache: getDisplayCache(),
247
+ groupKeys: (store.view?.group ?? []).map((entry)=>entry.key),
248
+ expandedGroups: store.expandedGroups,
249
+ rowsById,
250
+ getId,
251
+ itemCache: store.itemCache
252
+ });
253
+ store.segments = built.segments;
254
+ return built;
255
+ },
256
+ // Leaf rows of the cache on screen, for TanStack (selection, row lookup, events), and each
257
+ // one's index in its list on the server.
258
+ getLoadedRows () {
259
+ if (store.loadedRows.version === store.version) return store.loadedRows.rows;
260
+ const levels = (store.view?.group ?? []).length;
261
+ const display = getDisplayCache();
262
+ const rows = [];
263
+ const indices = new Map();
264
+ display.forEachLoaded((blockRows, block)=>{
265
+ if (JSON.parse(block.listKey).length < levels) return;
266
+ blockRows.forEach((row, offset)=>{
267
+ rows.push(row);
268
+ indices.set(String(api.config.getKey(row)), block.index * display.blockSize + offset);
269
+ });
270
+ });
271
+ store.loadedRows = {
272
+ version: store.version,
273
+ rows,
274
+ indices
275
+ };
276
+ return rows;
277
+ },
278
+ getRowIndex (rowKey) {
279
+ store.getLoadedRows();
280
+ return store.loadedRows.indices.get(String(rowKey)) ?? null;
281
+ },
282
+ toggleGroup ({ key, expanded }) {
283
+ const next = expanded ?? !store.expandedGroups.has(key);
284
+ if (next === store.expandedGroups.has(key)) return;
285
+ if (next) {
286
+ store.expandedGroups.add(key);
287
+ fetchBlock({
288
+ listKey: key,
289
+ groupPath: JSON.parse(key),
290
+ index: 0
291
+ });
292
+ } else {
293
+ store.expandedGroups.delete(key);
294
+ }
295
+ notify();
296
+ },
297
+ collapseAllGroups () {
298
+ if (store.expandedGroups.size === 0) return false;
299
+ store.expandedGroups = new Set();
300
+ notify();
301
+ return true;
302
+ },
303
+ // Purges the cache: every block reloads when it is next visible, the visible ones now. Rows
304
+ // stay on screen until their reload lands.
305
+ refresh () {
306
+ store.cache.invalidate();
307
+ if (store.timer) clearTimeout(store.timer);
308
+ fetchBlock({
309
+ listKey: ROOT,
310
+ groupPath: [],
311
+ index: 0
312
+ });
313
+ loadVisible();
314
+ notify();
315
+ },
316
+ // Updates merge into loaded rows in place. Removed rows leave their block at once; adds and
317
+ // removes shift the server's row positions, so the cache is invalidated and the visible
318
+ // blocks reload.
319
+ applyTransaction (transaction) {
320
+ const changed = {
321
+ added: transaction.add.length,
322
+ updated: 0,
323
+ removed: 0
324
+ };
325
+ const levels = (store.view?.group ?? []).length;
326
+ store.cache.forEachLoaded((rows, block)=>{
327
+ if (JSON.parse(block.listKey).length < levels) return;
328
+ const result = applyTransactionToRows({
329
+ rows,
330
+ transaction: {
331
+ ...transaction,
332
+ add: []
333
+ },
334
+ getKey: api.config.getKey
335
+ });
336
+ if (result.changed.updated === 0 && result.changed.removed === 0) return;
337
+ changed.updated += result.changed.updated;
338
+ changed.removed += result.changed.removed;
339
+ store.cache.setBlockRows({
340
+ listKey: block.listKey,
341
+ index: block.index,
342
+ rows: result.rows
343
+ });
344
+ store.cache.adjustTotal(block.listKey, -result.changed.removed);
345
+ });
346
+ if (transaction.add.length > 0 || changed.removed > 0) {
347
+ store.refresh();
348
+ } else {
349
+ notify();
350
+ }
351
+ return changed;
352
+ },
353
+ dispose () {
354
+ if (store.timer) clearTimeout(store.timer);
355
+ listeners.clear();
356
+ }
357
+ });
358
+ return store;
359
+ }
360
+ export default createServerStore;
@@ -0,0 +1,29 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ // The block indexes that hold rows `startRow` (inclusive) to `endRow` (exclusive), clipped to
16
+ // `total` when it is known. `first > last` when the range is empty.
17
+ function getBlockRange({ startRow, endRow, blockSize, total }) {
18
+ const end = typeof total === 'number' ? Math.min(endRow, total) : endRow;
19
+ const start = Math.max(0, startRow);
20
+ if (end <= start) return {
21
+ first: 0,
22
+ last: -1
23
+ };
24
+ return {
25
+ first: Math.floor(start / blockSize),
26
+ last: Math.floor((end - 1) / blockSize)
27
+ };
28
+ }
29
+ export default getBlockRange;
@@ -0,0 +1,20 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ // A server list is the rows (or groups) under one group path; the root list has path []. The key
16
+ // is also the group item's key, so an expanded group's key names its child list.
17
+ function getListKey(groupPath) {
18
+ return JSON.stringify(groupPath);
19
+ }
20
+ export default getListKey;
@@ -0,0 +1,45 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import getBlockRange from './getBlockRange.js';
16
+ // The blocks behind display items `rowStart` to `rowEnd` (exclusive). `segments` map runs of
17
+ // display items to the list rows they show: `{ itemStart, length, listKey, groupPath,
18
+ // listStart }`, in item order.
19
+ function getNeededBlocks({ segments, rowStart, rowEnd, blockSize }) {
20
+ const needed = [];
21
+ const seen = new Set();
22
+ segments.forEach((segment)=>{
23
+ const segmentEnd = segment.itemStart + segment.length;
24
+ if (segmentEnd <= rowStart || segment.itemStart >= rowEnd) return;
25
+ const from = Math.max(rowStart, segment.itemStart) - segment.itemStart + segment.listStart;
26
+ const to = Math.min(rowEnd, segmentEnd) - segment.itemStart + segment.listStart;
27
+ const { first, last } = getBlockRange({
28
+ startRow: from,
29
+ endRow: to,
30
+ blockSize
31
+ });
32
+ for(let index = first; index <= last; index++){
33
+ const id = `${segment.listKey}#${index}`;
34
+ if (seen.has(id)) continue;
35
+ seen.add(id);
36
+ needed.push({
37
+ listKey: segment.listKey,
38
+ groupPath: segment.groupPath,
39
+ index
40
+ });
41
+ }
42
+ });
43
+ return needed;
44
+ }
45
+ export default getNeededBlocks;