@proteinjs/db-ui 1.7.1 → 1.8.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,30 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.8.1](https://github.com/proteinjs/db/compare/@proteinjs/db-ui@1.8.0...@proteinjs/db-ui@1.8.1) (2026-08-13)
7
+
8
+ **Note:** Version bump only for package @proteinjs/db-ui
9
+
10
+
11
+
12
+
13
+
14
+ # [1.8.0](https://github.com/proteinjs/db/compare/@proteinjs/db-ui@1.7.1...@proteinjs/db-ui@1.8.0) (2026-08-13)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * **ci:** db-ui rides @proteinjs/ui 4.6.0 — the Cursor* exports QueryCursorLoader imports ([540de28](https://github.com/proteinjs/db/commit/540de28b992eb6dadf8ca7a5f0f706394485aeba))
20
+
21
+
22
+ ### Features
23
+
24
+ * QueryCursorLoader — cursor windows over the QueryBuilder machinery ([f45f3b3](https://github.com/proteinjs/db/commit/f45f3b32edae7c0e232574bd319522c277238116))
25
+
26
+
27
+
28
+
29
+
6
30
  ## [1.6.1](https://github.com/proteinjs/db/compare/@proteinjs/db-ui@1.6.0...@proteinjs/db-ui@1.6.1) (2026-08-08)
7
31
 
8
32
  **Note:** Version bump only for package @proteinjs/db-ui
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Brent Bahry
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,OAAO,gBAAgB,CAAC;AACxB,OAAO,iBAAiB,CAAC;AACzB,OAAO,qBAAqB,CAAC;AAC7B,OAAO,eAAe,CAAC;AACvB,OAAO,eAAe,CAAC;AACvB,OAAO,uBAAuB,CAAC;AAC/B,OAAO,eAAe,CAAC;AACvB,OAAO,iBAAiB,CAAC;AACzB,OAAO,QAAQ,CAAC;AAChB,OAAO,OAAO,CAAC;AACf,OAAO,QAAQ,CAAC;AAChB,OAAO,MAAM,CAAC;AAqCd,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,OAAO,gBAAgB,CAAC;AACxB,OAAO,iBAAiB,CAAC;AACzB,OAAO,qBAAqB,CAAC;AAC7B,OAAO,eAAe,CAAC;AACvB,OAAO,eAAe,CAAC;AACvB,OAAO,uBAAuB,CAAC;AAC/B,OAAO,eAAe,CAAC;AACvB,OAAO,iBAAiB,CAAC;AACzB,OAAO,QAAQ,CAAC;AAChB,OAAO,OAAO,CAAC;AACf,OAAO,QAAQ,CAAC;AAChB,OAAO,MAAM,CAAC;AAuCd,cAAc,UAAU,CAAC"}
@@ -28,8 +28,9 @@ require("react");
28
28
  require("string");
29
29
  require("uuid");
30
30
  /** Generate Source Graph */
31
- var sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"@proteinjs/db-ui/QueryTableLoader\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"QueryTableLoader\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/table/QueryTableLoader.ts\",\"qualifiedName\":\"@proteinjs/db-ui/QueryTableLoader\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"rowCountQb\",\"type\":{\"packageName\":\"\",\"name\":\"QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"paginationQb\",\"type\":{\"packageName\":\"\",\"name\":\"QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"reactQueryKeys\",\"type\":{\"packageName\":\"\",\"name\":\"TableLoader<T>['reactQueryKeys']\",\"filePath\":null,\"qualifiedName\":\"/TableLoader<T>['reactQueryKeys']\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"table\",\"type\":{\"packageName\":\"\",\"name\":\"Table<T>\",\"filePath\":null,\"qualifiedName\":\"/Table<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"query\",\"type\":{\"packageName\":\"\",\"name\":\"Query<T>\",\"filePath\":null,\"qualifiedName\":\"/Query<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"sort\",\"type\":{\"packageName\":\"\",\"name\":\"SortCriteria<T>[]\",\"filePath\":null,\"qualifiedName\":\"/SortCriteria<T>[]\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"queryOptions\",\"type\":{\"packageName\":\"\",\"name\":\"QueryOptions<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryOptions<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"}],\"methods\":[{\"name\":\"load\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<RowWindow<T>>\",\"filePath\":null,\"qualifiedName\":\"/Promise<RowWindow<T>>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"startIndex\",\"type\":{\"packageName\":\"\",\"name\":\"number\",\"filePath\":null,\"qualifiedName\":\"/number\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"endIndex\",\"type\":{\"packageName\":\"\",\"name\":\"number\",\"filePath\":null,\"qualifiedName\":\"/number\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"skipRowCount\",\"type\":{\"packageName\":\"\",\"name\":\"boolean\",\"filePath\":null,\"qualifiedName\":\"/boolean\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[\"/T extends Record\"],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"TableLoader\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/TableLoader\",\"properties\":[],\"methods\":[],\"typeParameters\":[\"/T\"],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/ui/TableLoader\"},{\"v\":\"@proteinjs/db-ui/RecordFormCustomization\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"RecordFormCustomization\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/form/RecordFormCustomization.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/RecordFormCustomization\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"table\",\"type\":{\"packageName\":\"\",\"name\":\"Table<any>\",\"filePath\":null,\"qualifiedName\":\"/Table<any>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"getFormButtons\",\"returnType\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"record\",\"type\":{\"packageName\":\"\",\"name\":\"any\",\"filePath\":null,\"qualifiedName\":\"/any\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"defaultFormButtons\",\"type\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"getFieldLayout\",\"returnType\":{\"packageName\":\"\",\"name\":\"string[] | string[][]\",\"filePath\":null,\"qualifiedName\":\"/string[] | string[][]\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"record\",\"type\":{\"packageName\":\"\",\"name\":\"any\",\"filePath\":null,\"qualifiedName\":\"/any\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"defaultFieldLayout\",\"type\":{\"packageName\":\"\",\"name\":\"string[] | string[][]\",\"filePath\":null,\"qualifiedName\":\"/string[] | string[][]\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/reflection\",\"name\":\"Loadable\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/reflection/Loadable\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/reflection/Loadable\"},{\"v\":\"@proteinjs/db-ui/hashGeneratorPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"hashGeneratorPage\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/pages/HashGeneratorPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/hashGeneratorPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/ui/Page\"},{\"v\":\"@proteinjs/db-ui/recordFormPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"recordFormPage\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/pages/RecordFormPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/recordFormPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/recordTablePage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"recordTablePage\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/pages/RecordTablePage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/recordTablePage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/tablesPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"tablesPage\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/pages/TablesPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/tablesPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/uuidGeneratorPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"uuidGeneratorPage\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/pages/UuidGeneratorPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/uuidGeneratorPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/SpecificTableProps\"},{\"v\":\"@proteinjs/db-ui/MigrationRecordFormCustomization\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"MigrationRecordFormCustomization\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/form/customizations/MigrationRecordFormCustomization.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/MigrationRecordFormCustomization\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"table\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"getFormButtons\",\"returnType\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"migration\",\"type\":{\"packageName\":\"@proteinjs/db\",\"name\":\"Migration\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/db/Migration\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"defaultFormButtons\",\"type\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[],\"directParentClasses\":[{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"RecordFormCustomization\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/db-ui/RecordFormCustomization\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParentInterfaces\":[],\"directParentClasses\":[]}],\"sourceType\":2}}],\"edges\":[{\"v\":\"@proteinjs/db-ui/QueryTableLoader\",\"w\":\"@proteinjs/ui/TableLoader\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/db-ui/RecordFormCustomization\",\"w\":\"@proteinjs/reflection/Loadable\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/db-ui/hashGeneratorPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/recordFormPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/recordTablePage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/tablesPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/uuidGeneratorPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/MigrationRecordFormCustomization\",\"w\":\"@proteinjs/db-ui/RecordFormCustomization\",\"value\":\"extends class\"}]}";
31
+ var sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"@proteinjs/db-ui/QueryCursorLoader\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"QueryCursorLoader\",\"filePath\":\"/home/runner/work/db/db/packages/ui/src/table/QueryCursorLoader.ts\",\"qualifiedName\":\"@proteinjs/db-ui/QueryCursorLoader\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"reactQueryKeys\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"ReactQueryKeys\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/ReactQueryKeys\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"sort\",\"type\":{\"packageName\":\"\",\"name\":\"SortCriteria<T>[]\",\"filePath\":null,\"qualifiedName\":\"/SortCriteria<T>[]\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"table\",\"type\":{\"packageName\":\"\",\"name\":\"Table<T>\",\"filePath\":null,\"qualifiedName\":\"/Table<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"createQuery\",\"type\":{\"packageName\":\"\",\"name\":\"() => QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/() => QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"queryOptions\",\"type\":{\"packageName\":\"\",\"name\":\"QueryOptions<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryOptions<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"}],\"methods\":[{\"name\":\"loadWindow\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<CursorWindow<T>>\",\"filePath\":null,\"qualifiedName\":\"/Promise<CursorWindow<T>>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"cursor\",\"type\":{\"packageName\":\"\",\"name\":\"CursorValue | null\",\"filePath\":null,\"qualifiedName\":\"/CursorValue | null\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"windowSize\",\"type\":{\"packageName\":\"\",\"name\":\"number\",\"filePath\":null,\"qualifiedName\":\"/number\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"buildWindowQuery\",\"returnType\":{\"packageName\":\"\",\"name\":\"QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"cursor\",\"type\":{\"packageName\":\"\",\"name\":\"CursorValue | null\",\"filePath\":null,\"qualifiedName\":\"/CursorValue | null\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"windowSize\",\"type\":{\"packageName\":\"\",\"name\":\"number\",\"filePath\":null,\"qualifiedName\":\"/number\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"deriveNextCursor\",\"returnType\":{\"packageName\":\"\",\"name\":\"CursorValue | null\",\"filePath\":null,\"qualifiedName\":\"/CursorValue | null\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"rows\",\"type\":{\"packageName\":\"\",\"name\":\"T[]\",\"filePath\":null,\"qualifiedName\":\"/T[]\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"windowSize\",\"type\":{\"packageName\":\"\",\"name\":\"number\",\"filePath\":null,\"qualifiedName\":\"/number\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[\"/T extends Record\"],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"CursorLoader\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/CursorLoader\",\"properties\":[],\"methods\":[],\"typeParameters\":[\"/T\"],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/ui/CursorLoader\"},{\"v\":\"@proteinjs/db-ui/QueryTableLoader\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"QueryTableLoader\",\"filePath\":\"/home/runner/work/db/db/packages/ui/src/table/QueryTableLoader.ts\",\"qualifiedName\":\"@proteinjs/db-ui/QueryTableLoader\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"rowCountQb\",\"type\":{\"packageName\":\"\",\"name\":\"QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"paginationQb\",\"type\":{\"packageName\":\"\",\"name\":\"QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"reactQueryKeys\",\"type\":{\"packageName\":\"\",\"name\":\"TableLoader<T>['reactQueryKeys']\",\"filePath\":null,\"qualifiedName\":\"/TableLoader<T>['reactQueryKeys']\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"table\",\"type\":{\"packageName\":\"\",\"name\":\"Table<T>\",\"filePath\":null,\"qualifiedName\":\"/Table<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"query\",\"type\":{\"packageName\":\"\",\"name\":\"Query<T>\",\"filePath\":null,\"qualifiedName\":\"/Query<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"sort\",\"type\":{\"packageName\":\"\",\"name\":\"SortCriteria<T>[]\",\"filePath\":null,\"qualifiedName\":\"/SortCriteria<T>[]\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"queryOptions\",\"type\":{\"packageName\":\"\",\"name\":\"QueryOptions<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryOptions<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"}],\"methods\":[{\"name\":\"load\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<RowWindow<T>>\",\"filePath\":null,\"qualifiedName\":\"/Promise<RowWindow<T>>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"startIndex\",\"type\":{\"packageName\":\"\",\"name\":\"number\",\"filePath\":null,\"qualifiedName\":\"/number\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"endIndex\",\"type\":{\"packageName\":\"\",\"name\":\"number\",\"filePath\":null,\"qualifiedName\":\"/number\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"skipRowCount\",\"type\":{\"packageName\":\"\",\"name\":\"boolean\",\"filePath\":null,\"qualifiedName\":\"/boolean\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[\"/T extends Record\"],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"TableLoader\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/TableLoader\",\"properties\":[],\"methods\":[],\"typeParameters\":[\"/T\"],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/ui/TableLoader\"},{\"v\":\"@proteinjs/db-ui/RecordFormCustomization\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"RecordFormCustomization\",\"filePath\":\"/home/runner/work/db/db/packages/ui/src/form/RecordFormCustomization.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/RecordFormCustomization\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"table\",\"type\":{\"packageName\":\"\",\"name\":\"Table<any>\",\"filePath\":null,\"qualifiedName\":\"/Table<any>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"getFormButtons\",\"returnType\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"record\",\"type\":{\"packageName\":\"\",\"name\":\"any\",\"filePath\":null,\"qualifiedName\":\"/any\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"defaultFormButtons\",\"type\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"getFieldLayout\",\"returnType\":{\"packageName\":\"\",\"name\":\"string[] | string[][]\",\"filePath\":null,\"qualifiedName\":\"/string[] | string[][]\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"record\",\"type\":{\"packageName\":\"\",\"name\":\"any\",\"filePath\":null,\"qualifiedName\":\"/any\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"defaultFieldLayout\",\"type\":{\"packageName\":\"\",\"name\":\"string[] | string[][]\",\"filePath\":null,\"qualifiedName\":\"/string[] | string[][]\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/reflection\",\"name\":\"Loadable\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/reflection/Loadable\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/reflection/Loadable\"},{\"v\":\"@proteinjs/db-ui/hashGeneratorPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"hashGeneratorPage\",\"filePath\":\"/home/runner/work/db/db/packages/ui/src/pages/HashGeneratorPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/hashGeneratorPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/ui/Page\"},{\"v\":\"@proteinjs/db-ui/recordFormPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"recordFormPage\",\"filePath\":\"/home/runner/work/db/db/packages/ui/src/pages/RecordFormPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/recordFormPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/recordTablePage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"recordTablePage\",\"filePath\":\"/home/runner/work/db/db/packages/ui/src/pages/RecordTablePage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/recordTablePage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/tablesPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"tablesPage\",\"filePath\":\"/home/runner/work/db/db/packages/ui/src/pages/TablesPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/tablesPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/uuidGeneratorPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"uuidGeneratorPage\",\"filePath\":\"/home/runner/work/db/db/packages/ui/src/pages/UuidGeneratorPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/uuidGeneratorPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/SpecificTableProps\"},{\"v\":\"@proteinjs/db-ui/MigrationRecordFormCustomization\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"MigrationRecordFormCustomization\",\"filePath\":\"/home/runner/work/db/db/packages/ui/src/form/customizations/MigrationRecordFormCustomization.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/MigrationRecordFormCustomization\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"table\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"getFormButtons\",\"returnType\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"migration\",\"type\":{\"packageName\":\"@proteinjs/db\",\"name\":\"Migration\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/db/Migration\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"defaultFormButtons\",\"type\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[],\"directParentClasses\":[{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"RecordFormCustomization\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/db-ui/RecordFormCustomization\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParentInterfaces\":[],\"directParentClasses\":[]}],\"sourceType\":2}}],\"edges\":[{\"v\":\"@proteinjs/db-ui/QueryCursorLoader\",\"w\":\"@proteinjs/ui/CursorLoader\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/db-ui/QueryTableLoader\",\"w\":\"@proteinjs/ui/TableLoader\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/db-ui/RecordFormCustomization\",\"w\":\"@proteinjs/reflection/Loadable\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/db-ui/hashGeneratorPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/recordFormPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/recordTablePage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/tablesPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/uuidGeneratorPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/MigrationRecordFormCustomization\",\"w\":\"@proteinjs/db-ui/RecordFormCustomization\",\"value\":\"extends class\"}]}";
32
32
  /** Generate Source Links */
33
+ var QueryCursorLoader_1 = require("../src/table/QueryCursorLoader");
33
34
  var QueryTableLoader_1 = require("../src/table/QueryTableLoader");
34
35
  var RecordFormCustomization_1 = require("../src/form/RecordFormCustomization");
35
36
  var HashGeneratorPage_1 = require("../src/pages/HashGeneratorPage");
@@ -39,6 +40,7 @@ var TablesPage_1 = require("../src/pages/TablesPage");
39
40
  var UuidGeneratorPage_1 = require("../src/pages/UuidGeneratorPage");
40
41
  var MigrationRecordFormCustomization_1 = require("../src/form/customizations/MigrationRecordFormCustomization");
41
42
  var sourceLinks = {
43
+ '@proteinjs/db-ui/QueryCursorLoader': QueryCursorLoader_1.QueryCursorLoader,
42
44
  '@proteinjs/db-ui/QueryTableLoader': QueryTableLoader_1.QueryTableLoader,
43
45
  '@proteinjs/db-ui/RecordFormCustomization': RecordFormCustomization_1.RecordFormCustomization,
44
46
  '@proteinjs/db-ui/hashGeneratorPage': HashGeneratorPage_1.hashGeneratorPage,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,0BAAwB;AACxB,2BAAyB;AACzB,+BAA6B;AAC7B,yBAAuB;AACvB,yBAAuB;AACvB,iCAA+B;AAC/B,yBAAuB;AACvB,2BAAyB;AACzB,kBAAgB;AAChB,iBAAe;AACf,kBAAgB;AAChB,gBAAc;AAGd,4BAA4B;AAE5B,IAAM,WAAW,GAAG,06XAA06X,CAAC;AAG/7X,4BAA4B;AAE5B,kEAAiE;AACjE,+EAA8E;AAC9E,oEAAmE;AACnE,8DAA6D;AAC7D,gEAA+D;AAC/D,sDAAqD;AACrD,oEAAmE;AACnE,gHAA+G;AAE/G,IAAM,WAAW,GAAG;IACnB,mCAAmC,EAAE,mCAAgB;IACrD,0CAA0C,EAAE,iDAAuB;IACnE,oCAAoC,EAAE,qCAAiB;IACvD,iCAAiC,EAAE,+BAAc;IACjD,kCAAkC,EAAE,iCAAe;IACnD,6BAA6B,EAAE,uBAAU;IACzC,oCAAoC,EAAE,qCAAiB;IACvD,mDAAmD,EAAE,mEAAgC;CACrF,CAAC;AAGF,kCAAkC;AAElC,oDAAyD;AACzD,6BAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAGjD,2CAAyB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,0BAAwB;AACxB,2BAAyB;AACzB,+BAA6B;AAC7B,yBAAuB;AACvB,yBAAuB;AACvB,iCAA+B;AAC/B,yBAAuB;AACvB,2BAAyB;AACzB,kBAAgB;AAChB,iBAAe;AACf,kBAAgB;AAChB,gBAAc;AAGd,4BAA4B;AAE5B,IAAM,WAAW,GAAG,+zfAA+zf,CAAC;AAGp1f,4BAA4B;AAE5B,oEAAmE;AACnE,kEAAiE;AACjE,+EAA8E;AAC9E,oEAAmE;AACnE,8DAA6D;AAC7D,gEAA+D;AAC/D,sDAAqD;AACrD,oEAAmE;AACnE,gHAA+G;AAE/G,IAAM,WAAW,GAAG;IACnB,oCAAoC,EAAE,qCAAiB;IACvD,mCAAmC,EAAE,mCAAgB;IACrD,0CAA0C,EAAE,iDAAuB;IACnE,oCAAoC,EAAE,qCAAiB;IACvD,iCAAiC,EAAE,+BAAc;IACjD,kCAAkC,EAAE,iCAAe;IACnD,6BAA6B,EAAE,uBAAU;IACzC,oCAAoC,EAAE,qCAAiB;IACvD,mDAAmD,EAAE,mEAAgC;CACrF,CAAC;AAGF,kCAAkC;AAElC,oDAAyD;AACzD,6BAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAGjD,2CAAyB"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './src/table/RecordTable';
2
2
  export * from './src/table/QueryTableLoader';
3
+ export * from './src/table/QueryCursorLoader';
3
4
  export * from './src/form/RecordForm';
4
5
  export * from './src/form/RecordFormCustomization';
5
6
  export * from './src/pages/RecordTablePage';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,oCAAoC,CAAC;AACnD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,oCAAoC,CAAC;AACnD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./src/table/RecordTable"), exports);
18
18
  __exportStar(require("./src/table/QueryTableLoader"), exports);
19
+ __exportStar(require("./src/table/QueryCursorLoader"), exports);
19
20
  __exportStar(require("./src/form/RecordForm"), exports);
20
21
  __exportStar(require("./src/form/RecordFormCustomization"), exports);
21
22
  __exportStar(require("./src/pages/RecordTablePage"), exports);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0DAAwC;AACxC,+DAA6C;AAC7C,wDAAsC;AACtC,qEAAmD;AACnD,8DAA4C;AAC5C,6DAA2C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0DAAwC;AACxC,+DAA6C;AAC7C,gEAA8C;AAC9C,wDAAsC;AACtC,qEAAmD;AACnD,8DAA4C;AAC5C,6DAA2C"}
@@ -0,0 +1,33 @@
1
+ import { QueryBuilder, QueryOptions, Record, SortCriteria, Table } from '@proteinjs/db';
2
+ import { CursorLoader, CursorValue, CursorWindow, ReactQueryKeys } from '@proteinjs/ui';
3
+ /**
4
+ * `CursorLoader` over the same QueryBuilder machinery as `QueryTableLoader`: each window
5
+ * applies `cursorField < cursor` (`>` for an ascending sort) plus `paginate(0, windowSize)`
6
+ * on a fresh build of the base query, so rows created or removed while paging can never
7
+ * shift the window frame. The cursor field and direction derive from the PRIMARY sort
8
+ * criterion.
9
+ *
10
+ * `dataKey` is the table name — table-level invalidation (`useTableMutation`) reaches every
11
+ * cursor query over it; `dataQueryKey` is the serialized query + sort.
12
+ */
13
+ export declare class QueryCursorLoader<T extends Record> implements CursorLoader<T> {
14
+ private table;
15
+ private createQuery;
16
+ private queryOptions?;
17
+ reactQueryKeys: ReactQueryKeys;
18
+ private sort;
19
+ /**
20
+ * @param table the table to load windows from
21
+ * @param createQuery factory producing a FRESH conditions-only QueryBuilder per call —
22
+ * builders are mutable, so every window builds its own to hang the cursor condition,
23
+ * sort, and pagination on
24
+ * @param sort the sort criteria to apply to every window; the primary criterion is the
25
+ * cursor axis
26
+ * @param queryOptions query options passed through to every window query
27
+ */
28
+ constructor(table: Table<T>, createQuery: () => QueryBuilder<T>, sort?: SortCriteria<T>[], queryOptions?: QueryOptions<T> | undefined);
29
+ loadWindow(cursor: CursorValue | null, windowSize: number): Promise<CursorWindow<T>>;
30
+ private buildWindowQuery;
31
+ private deriveNextCursor;
32
+ }
33
+ //# sourceMappingURL=QueryCursorLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryCursorLoader.d.ts","sourceRoot":"","sources":["../../../src/table/QueryCursorLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAS,MAAM,eAAe,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAExF;;;;;;;;;GASG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAE,YAAW,YAAY,CAAC,CAAC,CAAC;IAcvE,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,WAAW;IAEnB,OAAO,CAAC,YAAY,CAAC;IAhBvB,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAoB;IAEhC;;;;;;;;OAQG;gBAEO,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,WAAW,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,EAC1C,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EAChB,YAAY,CAAC,6BAAiB;IASlC,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAM1F,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,gBAAgB;CAWzB"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.QueryCursorLoader = void 0;
40
+ var db_1 = require("@proteinjs/db");
41
+ /**
42
+ * `CursorLoader` over the same QueryBuilder machinery as `QueryTableLoader`: each window
43
+ * applies `cursorField < cursor` (`>` for an ascending sort) plus `paginate(0, windowSize)`
44
+ * on a fresh build of the base query, so rows created or removed while paging can never
45
+ * shift the window frame. The cursor field and direction derive from the PRIMARY sort
46
+ * criterion.
47
+ *
48
+ * `dataKey` is the table name — table-level invalidation (`useTableMutation`) reaches every
49
+ * cursor query over it; `dataQueryKey` is the serialized query + sort.
50
+ */
51
+ var QueryCursorLoader = /** @class */ (function () {
52
+ /**
53
+ * @param table the table to load windows from
54
+ * @param createQuery factory producing a FRESH conditions-only QueryBuilder per call —
55
+ * builders are mutable, so every window builds its own to hang the cursor condition,
56
+ * sort, and pagination on
57
+ * @param sort the sort criteria to apply to every window; the primary criterion is the
58
+ * cursor axis
59
+ * @param queryOptions query options passed through to every window query
60
+ */
61
+ function QueryCursorLoader(table, createQuery, sort, queryOptions) {
62
+ this.table = table;
63
+ this.createQuery = createQuery;
64
+ this.queryOptions = queryOptions;
65
+ this.sort = sort ? sort : [{ field: 'created', desc: true }];
66
+ this.reactQueryKeys = {
67
+ dataKey: this.table.name,
68
+ dataQueryKey: JSON.stringify({ query: this.createQuery(), sort: this.sort }),
69
+ };
70
+ }
71
+ QueryCursorLoader.prototype.loadWindow = function (cursor, windowSize) {
72
+ return __awaiter(this, void 0, void 0, function () {
73
+ var qb, rows;
74
+ return __generator(this, function (_a) {
75
+ switch (_a.label) {
76
+ case 0:
77
+ qb = this.buildWindowQuery(cursor, windowSize);
78
+ return [4 /*yield*/, (0, db_1.getDb)().query(this.table, qb, this.queryOptions)];
79
+ case 1:
80
+ rows = _a.sent();
81
+ return [2 /*return*/, { rows: rows, nextCursor: this.deriveNextCursor(rows, windowSize) }];
82
+ }
83
+ });
84
+ });
85
+ };
86
+ QueryCursorLoader.prototype.buildWindowQuery = function (cursor, windowSize) {
87
+ var qb = this.createQuery();
88
+ var primarySort = this.sort[0];
89
+ if (cursor !== null) {
90
+ qb.condition({
91
+ field: primarySort.field,
92
+ operator: primarySort.desc ? '<' : '>',
93
+ value: cursor,
94
+ });
95
+ }
96
+ return qb.sort(this.sort).paginate({ start: 0, end: windowSize });
97
+ };
98
+ QueryCursorLoader.prototype.deriveNextCursor = function (rows, windowSize) {
99
+ // A short window means the data set is exhausted; a full one implies more may exist —
100
+ // the next (short or empty) window settles it.
101
+ if (rows.length < windowSize) {
102
+ return null;
103
+ }
104
+ // NULL cursor-field rows collect at the tail under the sort, and a null tail can't
105
+ // anchor a cursor: the data set's dated rows are exhausted, so paging stops here.
106
+ var tail = rows[rows.length - 1][this.sort[0].field];
107
+ return tail == null ? null : tail;
108
+ };
109
+ return QueryCursorLoader;
110
+ }());
111
+ exports.QueryCursorLoader = QueryCursorLoader;
112
+ //# sourceMappingURL=QueryCursorLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryCursorLoader.js","sourceRoot":"","sources":["../../../src/table/QueryCursorLoader.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oCAA+F;AAG/F;;;;;;;;;GASG;AACH;IAIE;;;;;;;;OAQG;IACH,2BACU,KAAe,EACf,WAAkC,EAC1C,IAAwB,EAChB,YAA8B;QAH9B,UAAK,GAAL,KAAK,CAAU;QACf,gBAAW,GAAX,WAAW,CAAuB;QAElC,iBAAY,GAAZ,YAAY,CAAkB;QAEtC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAoB,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,cAAc,GAAG;YACpB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YACxB,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;SAC7E,CAAC;IACJ,CAAC;IAEK,sCAAU,GAAhB,UAAiB,MAA0B,EAAE,UAAkB;;;;;;wBACvD,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;wBACxC,qBAAM,IAAA,UAAK,GAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,EAAA;;wBAA7D,IAAI,GAAG,SAAsD;wBACnE,sBAAO,EAAE,IAAI,MAAA,EAAE,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,EAAC;;;;KACtE;IAEO,4CAAgB,GAAxB,UAAyB,MAA0B,EAAE,UAAkB;QACrE,IAAM,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC9B,IAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,IAAI,EAAE;YACnB,EAAE,CAAC,SAAS,CAAC;gBACX,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;gBACtC,KAAK,EAAE,MAAoB;aAC5B,CAAC,CAAC;SACJ;QACD,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;IACpE,CAAC;IAEO,4CAAgB,GAAxB,UAAyB,IAAS,EAAE,UAAkB;QACpD,sFAAsF;QACtF,+CAA+C;QAC/C,IAAI,IAAI,CAAC,MAAM,GAAG,UAAU,EAAE;YAC5B,OAAO,IAAI,CAAC;SACb;QACD,mFAAmF;QACnF,kFAAkF;QAClF,IAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACvD,OAAO,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,IAA+B,CAAC;IAChE,CAAC;IACH,wBAAC;AAAD,CAAC,AAxDD,IAwDC;AAxDY,8CAAiB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=QueryCursorLoader.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryCursorLoader.test.d.ts","sourceRoot":"","sources":["../../test/QueryCursorLoader.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ /**
54
+ * QueryCursorLoader (src/table/QueryCursorLoader.ts) at the pure level: react-query key
55
+ * derivation, cursor threading into the window query, and next-cursor derivation — including
56
+ * the null-tail exhaustion rule (NULL cursor-field rows collect at the tail under the sort;
57
+ * a null tail can't anchor a cursor, so paging stops). Window queries are inspected through
58
+ * the QueryBuilder graph; loadWindow's db round-trip is exercised with a stubbed getDb.
59
+ */
60
+ var moment_1 = __importDefault(require("moment"));
61
+ var stagedRows = { rows: [] };
62
+ var queries = [];
63
+ var stubDb = {
64
+ query: function (_table, qb) { return __awaiter(void 0, void 0, void 0, function () {
65
+ return __generator(this, function (_a) {
66
+ queries.push(qb);
67
+ return [2 /*return*/, stagedRows.rows];
68
+ });
69
+ }); },
70
+ };
71
+ jest.mock('@proteinjs/db', function () { return (__assign(__assign({}, jest.requireActual('@proteinjs/db')), { getDb: function () { return stubDb; } })); });
72
+ var db_1 = require("@proteinjs/db");
73
+ var QueryCursorLoader_1 = require("../src/table/QueryCursorLoader");
74
+ var table = { name: 'test_content' };
75
+ var sort = [{ field: 'lastActivityAt', desc: true }];
76
+ var createQuery = function () { return new db_1.QueryBuilder(table.name); };
77
+ var internals = function (loader) { return loader; };
78
+ var graphNodes = function (qb) { return qb.graph.nodes().map(function (id) { return qb.graph.node(id); }); };
79
+ var conditionNodes = function (qb) { return graphNodes(qb).filter(function (node) { return (node === null || node === void 0 ? void 0 : node.type) === 'CONDITION'; }); };
80
+ var paginationNode = function (qb) { return graphNodes(qb).find(function (node) { return (node === null || node === void 0 ? void 0 : node.type) === 'PAGINATION'; }); };
81
+ var sortNodes = function (qb) { return graphNodes(qb).filter(function (node) { return (node === null || node === void 0 ? void 0 : node.type) === 'SORT'; }); };
82
+ var dated = function (id, at) { return ({
83
+ id: id,
84
+ created: (0, moment_1.default)(),
85
+ updated: (0, moment_1.default)(),
86
+ lastActivityAt: at ? (0, moment_1.default)(at) : undefined,
87
+ }); };
88
+ beforeEach(function () {
89
+ stagedRows.rows = [];
90
+ queries.length = 0;
91
+ });
92
+ describe('reactQueryKeys', function () {
93
+ it('names the data set after the table and the query after its serialized query + sort', function () {
94
+ var loader = new QueryCursorLoader_1.QueryCursorLoader(table, createQuery, sort);
95
+ expect(loader.reactQueryKeys.dataKey).toBe('test_content');
96
+ // Identical construction = identical identity (warm cache across remounts)...
97
+ var twin = new QueryCursorLoader_1.QueryCursorLoader(table, createQuery, sort);
98
+ expect(twin.reactQueryKeys.dataQueryKey).toBe(loader.reactQueryKeys.dataQueryKey);
99
+ // ...while a different query or sort is a different identity.
100
+ var narrowed = new QueryCursorLoader_1.QueryCursorLoader(table, function () { return createQuery().condition({ field: 'isPinned', operator: '=', value: true }); }, sort);
101
+ expect(narrowed.reactQueryKeys.dataQueryKey).not.toBe(loader.reactQueryKeys.dataQueryKey);
102
+ var resorted = new QueryCursorLoader_1.QueryCursorLoader(table, createQuery, [{ field: 'lastActivityAt', desc: false }]);
103
+ expect(resorted.reactQueryKeys.dataQueryKey).not.toBe(loader.reactQueryKeys.dataQueryKey);
104
+ });
105
+ });
106
+ describe('buildWindowQuery — cursor threading', function () {
107
+ it('the first window carries no cursor condition, only the sort and the window pagination', function () {
108
+ var loader = new QueryCursorLoader_1.QueryCursorLoader(table, createQuery, sort);
109
+ var qb = internals(loader).buildWindowQuery(null, 30);
110
+ expect(conditionNodes(qb)).toHaveLength(0);
111
+ expect(paginationNode(qb)).toMatchObject({ start: 0, end: 30 });
112
+ expect(sortNodes(qb)).toHaveLength(1);
113
+ expect(sortNodes(qb)[0].criteria).toMatchObject({ field: 'lastActivityAt', desc: true });
114
+ });
115
+ it('a cursor becomes `field < cursor` on the primary sort field for a descending sort', function () {
116
+ var loader = new QueryCursorLoader_1.QueryCursorLoader(table, createQuery, sort);
117
+ var cursor = (0, moment_1.default)('2026-08-10T12:00:00.000Z');
118
+ var qb = internals(loader).buildWindowQuery(cursor, 30);
119
+ var conditions = conditionNodes(qb);
120
+ expect(conditions).toHaveLength(1);
121
+ expect(conditions[0]).toMatchObject({ field: 'lastActivityAt', operator: '<' });
122
+ expect(conditions[0].value).toBe(cursor);
123
+ expect(paginationNode(qb)).toMatchObject({ start: 0, end: 30 });
124
+ });
125
+ it('an ascending primary sort flips the cursor operator to `>`', function () {
126
+ var loader = new QueryCursorLoader_1.QueryCursorLoader(table, createQuery, [{ field: 'lastActivityAt', desc: false }]);
127
+ var qb = internals(loader).buildWindowQuery(5, 10);
128
+ expect(conditionNodes(qb)[0]).toMatchObject({ field: 'lastActivityAt', operator: '>', value: 5 });
129
+ });
130
+ it('every window builds on a FRESH query — cursor conditions never accumulate across windows', function () {
131
+ var loader = new QueryCursorLoader_1.QueryCursorLoader(table, createQuery, sort);
132
+ internals(loader).buildWindowQuery((0, moment_1.default)('2026-08-10T12:00:00.000Z'), 30);
133
+ var second = internals(loader).buildWindowQuery((0, moment_1.default)('2026-08-01T12:00:00.000Z'), 30);
134
+ expect(conditionNodes(second)).toHaveLength(1);
135
+ });
136
+ });
137
+ describe('deriveNextCursor — exhaustion', function () {
138
+ var loader = new QueryCursorLoader_1.QueryCursorLoader(table, createQuery, sort);
139
+ it('a short window is exhausted', function () {
140
+ expect(internals(loader).deriveNextCursor([dated('a', '2026-08-10T12:00:00.000Z')], 3)).toBeNull();
141
+ expect(internals(loader).deriveNextCursor([], 3)).toBeNull();
142
+ });
143
+ it('a full window anchors the next cursor at its tail', function () {
144
+ var rows = [
145
+ dated('a', '2026-08-10T12:00:00.000Z'),
146
+ dated('b', '2026-08-09T12:00:00.000Z'),
147
+ dated('c', '2026-08-08T12:00:00.000Z'),
148
+ ];
149
+ var next = internals(loader).deriveNextCursor(rows, 3);
150
+ expect(next).toBe(rows[2].lastActivityAt);
151
+ });
152
+ it('a full window with a NULL cursor-field tail is exhausted (null rows collect at the tail; no anchor)', function () {
153
+ var rows = [dated('a', '2026-08-10T12:00:00.000Z'), dated('b', '2026-08-09T12:00:00.000Z'), dated('c', null)];
154
+ expect(internals(loader).deriveNextCursor(rows, 3)).toBeNull();
155
+ });
156
+ });
157
+ describe('loadWindow', function () {
158
+ it('returns the queried rows with the derived next cursor', function () { return __awaiter(void 0, void 0, void 0, function () {
159
+ var loader, rows, window;
160
+ return __generator(this, function (_a) {
161
+ switch (_a.label) {
162
+ case 0:
163
+ loader = new QueryCursorLoader_1.QueryCursorLoader(table, createQuery, sort);
164
+ rows = [
165
+ dated('a', '2026-08-10T12:00:00.000Z'),
166
+ dated('b', '2026-08-09T12:00:00.000Z'),
167
+ dated('c', '2026-08-08T12:00:00.000Z'),
168
+ ];
169
+ stagedRows.rows = rows;
170
+ return [4 /*yield*/, loader.loadWindow(null, 3)];
171
+ case 1:
172
+ window = _a.sent();
173
+ expect(window.rows).toBe(rows);
174
+ expect(window.nextCursor).toBe(rows[2].lastActivityAt);
175
+ // The executed query is the built window query: pagination sized to the window.
176
+ expect(queries).toHaveLength(1);
177
+ expect(paginationNode(queries[0])).toMatchObject({ start: 0, end: 3 });
178
+ return [2 /*return*/];
179
+ }
180
+ });
181
+ }); });
182
+ it('returns an exhausted window (null cursor) when the query comes back short', function () { return __awaiter(void 0, void 0, void 0, function () {
183
+ var loader, window;
184
+ return __generator(this, function (_a) {
185
+ switch (_a.label) {
186
+ case 0:
187
+ loader = new QueryCursorLoader_1.QueryCursorLoader(table, createQuery, sort);
188
+ stagedRows.rows = [dated('a', '2026-08-10T12:00:00.000Z')];
189
+ return [4 /*yield*/, loader.loadWindow((0, moment_1.default)('2026-08-11T12:00:00.000Z'), 3)];
190
+ case 1:
191
+ window = _a.sent();
192
+ expect(window.nextCursor).toBeNull();
193
+ return [2 /*return*/];
194
+ }
195
+ });
196
+ }); });
197
+ });
198
+ //# sourceMappingURL=QueryCursorLoader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryCursorLoader.test.js","sourceRoot":"","sources":["../../test/QueryCursorLoader.test.ts"],"names":[],"mappings":"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"}
@@ -13,14 +13,14 @@ import 'react';
13
13
  import 'string';
14
14
  import 'uuid';
15
15
 
16
-
17
16
  /** Generate Source Graph */
18
17
 
19
- const sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"@proteinjs/db-ui/QueryTableLoader\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"QueryTableLoader\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/table/QueryTableLoader.ts\",\"qualifiedName\":\"@proteinjs/db-ui/QueryTableLoader\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"rowCountQb\",\"type\":{\"packageName\":\"\",\"name\":\"QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"paginationQb\",\"type\":{\"packageName\":\"\",\"name\":\"QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"reactQueryKeys\",\"type\":{\"packageName\":\"\",\"name\":\"TableLoader<T>['reactQueryKeys']\",\"filePath\":null,\"qualifiedName\":\"/TableLoader<T>['reactQueryKeys']\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"table\",\"type\":{\"packageName\":\"\",\"name\":\"Table<T>\",\"filePath\":null,\"qualifiedName\":\"/Table<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"query\",\"type\":{\"packageName\":\"\",\"name\":\"Query<T>\",\"filePath\":null,\"qualifiedName\":\"/Query<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"sort\",\"type\":{\"packageName\":\"\",\"name\":\"SortCriteria<T>[]\",\"filePath\":null,\"qualifiedName\":\"/SortCriteria<T>[]\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"queryOptions\",\"type\":{\"packageName\":\"\",\"name\":\"QueryOptions<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryOptions<T>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"}],\"methods\":[{\"name\":\"load\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<RowWindow<T>>\",\"filePath\":null,\"qualifiedName\":\"/Promise<RowWindow<T>>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"startIndex\",\"type\":{\"packageName\":\"\",\"name\":\"number\",\"filePath\":null,\"qualifiedName\":\"/number\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"endIndex\",\"type\":{\"packageName\":\"\",\"name\":\"number\",\"filePath\":null,\"qualifiedName\":\"/number\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"skipRowCount\",\"type\":{\"packageName\":\"\",\"name\":\"boolean\",\"filePath\":null,\"qualifiedName\":\"/boolean\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[\"/T extends Record\"],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"TableLoader\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/TableLoader\",\"properties\":[],\"methods\":[],\"typeParameters\":[\"/T\"],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/ui/TableLoader\"},{\"v\":\"@proteinjs/db-ui/RecordFormCustomization\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"RecordFormCustomization\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/form/RecordFormCustomization.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/RecordFormCustomization\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"table\",\"type\":{\"packageName\":\"\",\"name\":\"Table<any>\",\"filePath\":null,\"qualifiedName\":\"/Table<any>\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"getFormButtons\",\"returnType\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"record\",\"type\":{\"packageName\":\"\",\"name\":\"any\",\"filePath\":null,\"qualifiedName\":\"/any\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"defaultFormButtons\",\"type\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"getFieldLayout\",\"returnType\":{\"packageName\":\"\",\"name\":\"string[] | string[][]\",\"filePath\":null,\"qualifiedName\":\"/string[] | string[][]\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"record\",\"type\":{\"packageName\":\"\",\"name\":\"any\",\"filePath\":null,\"qualifiedName\":\"/any\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"defaultFieldLayout\",\"type\":{\"packageName\":\"\",\"name\":\"string[] | string[][]\",\"filePath\":null,\"qualifiedName\":\"/string[] | string[][]\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/reflection\",\"name\":\"Loadable\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/reflection/Loadable\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/reflection/Loadable\"},{\"v\":\"@proteinjs/db-ui/hashGeneratorPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"hashGeneratorPage\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/pages/HashGeneratorPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/hashGeneratorPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/ui/Page\"},{\"v\":\"@proteinjs/db-ui/recordFormPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"recordFormPage\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/pages/RecordFormPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/recordFormPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/recordTablePage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"recordTablePage\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/pages/RecordTablePage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/recordTablePage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/tablesPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"tablesPage\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/pages/TablesPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/tablesPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/uuidGeneratorPage\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"uuidGeneratorPage\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/pages/UuidGeneratorPage.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/uuidGeneratorPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/db-ui/SpecificTableProps\"},{\"v\":\"@proteinjs/db-ui/MigrationRecordFormCustomization\",\"value\":{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"MigrationRecordFormCustomization\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/db/packages/ui/src/form/customizations/MigrationRecordFormCustomization.tsx\",\"qualifiedName\":\"@proteinjs/db-ui/MigrationRecordFormCustomization\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"table\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"getFormButtons\",\"returnType\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"migration\",\"type\":{\"packageName\":\"@proteinjs/db\",\"name\":\"Migration\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/db/Migration\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"defaultFormButtons\",\"type\":{\"packageName\":\"\",\"name\":\"FormButtons<any>\",\"filePath\":null,\"qualifiedName\":\"/FormButtons<any>\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[],\"directParentClasses\":[{\"packageName\":\"@proteinjs/db-ui\",\"name\":\"RecordFormCustomization\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/db-ui/RecordFormCustomization\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParentInterfaces\":[],\"directParentClasses\":[]}],\"sourceType\":2}}],\"edges\":[{\"v\":\"@proteinjs/db-ui/QueryTableLoader\",\"w\":\"@proteinjs/ui/TableLoader\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/db-ui/RecordFormCustomization\",\"w\":\"@proteinjs/reflection/Loadable\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/db-ui/hashGeneratorPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/recordFormPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/recordTablePage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/tablesPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/uuidGeneratorPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/db-ui/MigrationRecordFormCustomization\",\"w\":\"@proteinjs/db-ui/RecordFormCustomization\",\"value\":\"extends class\"}]}";
20
-
18
+ const sourceGraph =
19
+ '{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"@proteinjs/db-ui/QueryCursorLoader","value":{"packageName":"@proteinjs/db-ui","name":"QueryCursorLoader","filePath":"/home/runner/work/db/db/packages/ui/src/table/QueryCursorLoader.ts","qualifiedName":"@proteinjs/db-ui/QueryCursorLoader","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"reactQueryKeys","type":{"packageName":"@proteinjs/ui","name":"ReactQueryKeys","filePath":null,"qualifiedName":"@proteinjs/ui/ReactQueryKeys","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"sort","type":{"packageName":"","name":"SortCriteria<T>[]","filePath":null,"qualifiedName":"/SortCriteria<T>[]","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"table","type":{"packageName":"","name":"Table<T>","filePath":null,"qualifiedName":"/Table<T>","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"createQuery","type":{"packageName":"","name":"() => QueryBuilder<T>","filePath":null,"qualifiedName":"/() => QueryBuilder<T>","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"queryOptions","type":{"packageName":"","name":"QueryOptions<T>","filePath":null,"qualifiedName":"/QueryOptions<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"}],"methods":[{"name":"loadWindow","returnType":{"packageName":"","name":"Promise<CursorWindow<T>>","filePath":null,"qualifiedName":"/Promise<CursorWindow<T>>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"cursor","type":{"packageName":"","name":"CursorValue | null","filePath":null,"qualifiedName":"/CursorValue | null","typeParameters":null,"directParents":null}},{"name":"windowSize","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}}]},{"name":"buildWindowQuery","returnType":{"packageName":"","name":"QueryBuilder<T>","filePath":null,"qualifiedName":"/QueryBuilder<T>","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"cursor","type":{"packageName":"","name":"CursorValue | null","filePath":null,"qualifiedName":"/CursorValue | null","typeParameters":null,"directParents":null}},{"name":"windowSize","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}}]},{"name":"deriveNextCursor","returnType":{"packageName":"","name":"CursorValue | null","filePath":null,"qualifiedName":"/CursorValue | null","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"rows","type":{"packageName":"","name":"T[]","filePath":null,"qualifiedName":"/T[]","typeParameters":null,"directParents":null}},{"name":"windowSize","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}}]}],"typeParameters":["/T extends Record"],"directParentInterfaces":[{"packageName":"@proteinjs/ui","name":"CursorLoader","filePath":null,"qualifiedName":"@proteinjs/ui/CursorLoader","properties":[],"methods":[],"typeParameters":["/T"],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/ui/CursorLoader"},{"v":"@proteinjs/db-ui/QueryTableLoader","value":{"packageName":"@proteinjs/db-ui","name":"QueryTableLoader","filePath":"/home/runner/work/db/db/packages/ui/src/table/QueryTableLoader.ts","qualifiedName":"@proteinjs/db-ui/QueryTableLoader","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"rowCountQb","type":{"packageName":"","name":"QueryBuilder<T>","filePath":null,"qualifiedName":"/QueryBuilder<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"paginationQb","type":{"packageName":"","name":"QueryBuilder<T>","filePath":null,"qualifiedName":"/QueryBuilder<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"reactQueryKeys","type":{"packageName":"","name":"TableLoader<T>[\'reactQueryKeys\']","filePath":null,"qualifiedName":"/TableLoader<T>[\'reactQueryKeys\']","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"table","type":{"packageName":"","name":"Table<T>","filePath":null,"qualifiedName":"/Table<T>","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"query","type":{"packageName":"","name":"Query<T>","filePath":null,"qualifiedName":"/Query<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"sort","type":{"packageName":"","name":"SortCriteria<T>[]","filePath":null,"qualifiedName":"/SortCriteria<T>[]","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"queryOptions","type":{"packageName":"","name":"QueryOptions<T>","filePath":null,"qualifiedName":"/QueryOptions<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"}],"methods":[{"name":"load","returnType":{"packageName":"","name":"Promise<RowWindow<T>>","filePath":null,"qualifiedName":"/Promise<RowWindow<T>>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"startIndex","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}},{"name":"endIndex","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}},{"name":"skipRowCount","type":{"packageName":"","name":"boolean","filePath":null,"qualifiedName":"/boolean","typeParameters":null,"directParents":null}}]}],"typeParameters":["/T extends Record"],"directParentInterfaces":[{"packageName":"@proteinjs/ui","name":"TableLoader","filePath":null,"qualifiedName":"@proteinjs/ui/TableLoader","properties":[],"methods":[],"typeParameters":["/T"],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/ui/TableLoader"},{"v":"@proteinjs/db-ui/RecordFormCustomization","value":{"packageName":"@proteinjs/db-ui","name":"RecordFormCustomization","filePath":"/home/runner/work/db/db/packages/ui/src/form/RecordFormCustomization.tsx","qualifiedName":"@proteinjs/db-ui/RecordFormCustomization","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[{"name":"getFormButtons","returnType":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"record","type":{"packageName":"","name":"any","filePath":null,"qualifiedName":"/any","typeParameters":null,"directParents":null}},{"name":"defaultFormButtons","type":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null}}]},{"name":"getFieldLayout","returnType":{"packageName":"","name":"string[] | string[][]","filePath":null,"qualifiedName":"/string[] | string[][]","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"record","type":{"packageName":"","name":"any","filePath":null,"qualifiedName":"/any","typeParameters":null,"directParents":null}},{"name":"defaultFieldLayout","type":{"packageName":"","name":"string[] | string[][]","filePath":null,"qualifiedName":"/string[] | string[][]","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/reflection","name":"Loadable","filePath":null,"qualifiedName":"@proteinjs/reflection/Loadable","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/reflection/Loadable"},{"v":"@proteinjs/db-ui/hashGeneratorPage","value":{"packageName":"@proteinjs/db-ui","name":"hashGeneratorPage","filePath":"/home/runner/work/db/db/packages/ui/src/pages/HashGeneratorPage.tsx","qualifiedName":"@proteinjs/db-ui/hashGeneratorPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/ui/Page"},{"v":"@proteinjs/db-ui/recordFormPage","value":{"packageName":"@proteinjs/db-ui","name":"recordFormPage","filePath":"/home/runner/work/db/db/packages/ui/src/pages/RecordFormPage.tsx","qualifiedName":"@proteinjs/db-ui/recordFormPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/recordTablePage","value":{"packageName":"@proteinjs/db-ui","name":"recordTablePage","filePath":"/home/runner/work/db/db/packages/ui/src/pages/RecordTablePage.tsx","qualifiedName":"@proteinjs/db-ui/recordTablePage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/tablesPage","value":{"packageName":"@proteinjs/db-ui","name":"tablesPage","filePath":"/home/runner/work/db/db/packages/ui/src/pages/TablesPage.tsx","qualifiedName":"@proteinjs/db-ui/tablesPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/uuidGeneratorPage","value":{"packageName":"@proteinjs/db-ui","name":"uuidGeneratorPage","filePath":"/home/runner/work/db/db/packages/ui/src/pages/UuidGeneratorPage.tsx","qualifiedName":"@proteinjs/db-ui/uuidGeneratorPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/SpecificTableProps"},{"v":"@proteinjs/db-ui/MigrationRecordFormCustomization","value":{"packageName":"@proteinjs/db-ui","name":"MigrationRecordFormCustomization","filePath":"/home/runner/work/db/db/packages/ui/src/form/customizations/MigrationRecordFormCustomization.tsx","qualifiedName":"@proteinjs/db-ui/MigrationRecordFormCustomization","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"table","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[{"name":"getFormButtons","returnType":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"migration","type":{"packageName":"@proteinjs/db","name":"Migration","filePath":null,"qualifiedName":"@proteinjs/db/Migration","typeParameters":null,"directParents":null}},{"name":"defaultFormButtons","type":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[{"packageName":"@proteinjs/db-ui","name":"RecordFormCustomization","filePath":null,"qualifiedName":"@proteinjs/db-ui/RecordFormCustomization","isAbstract":false,"isStatic":false,"visibility":"public","properties":[],"methods":[],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}}],"edges":[{"v":"@proteinjs/db-ui/QueryCursorLoader","w":"@proteinjs/ui/CursorLoader","value":"implements interface"},{"v":"@proteinjs/db-ui/QueryTableLoader","w":"@proteinjs/ui/TableLoader","value":"implements interface"},{"v":"@proteinjs/db-ui/RecordFormCustomization","w":"@proteinjs/reflection/Loadable","value":"implements interface"},{"v":"@proteinjs/db-ui/hashGeneratorPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/recordFormPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/recordTablePage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/tablesPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/uuidGeneratorPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/MigrationRecordFormCustomization","w":"@proteinjs/db-ui/RecordFormCustomization","value":"extends class"}]}';
21
20
 
22
21
  /** Generate Source Links */
23
22
 
23
+ import { QueryCursorLoader } from '../src/table/QueryCursorLoader';
24
24
  import { QueryTableLoader } from '../src/table/QueryTableLoader';
25
25
  import { RecordFormCustomization } from '../src/form/RecordFormCustomization';
26
26
  import { hashGeneratorPage } from '../src/pages/HashGeneratorPage';
@@ -31,21 +31,20 @@ import { uuidGeneratorPage } from '../src/pages/UuidGeneratorPage';
31
31
  import { MigrationRecordFormCustomization } from '../src/form/customizations/MigrationRecordFormCustomization';
32
32
 
33
33
  const sourceLinks = {
34
- '@proteinjs/db-ui/QueryTableLoader': QueryTableLoader,
35
- '@proteinjs/db-ui/RecordFormCustomization': RecordFormCustomization,
36
- '@proteinjs/db-ui/hashGeneratorPage': hashGeneratorPage,
37
- '@proteinjs/db-ui/recordFormPage': recordFormPage,
38
- '@proteinjs/db-ui/recordTablePage': recordTablePage,
39
- '@proteinjs/db-ui/tablesPage': tablesPage,
40
- '@proteinjs/db-ui/uuidGeneratorPage': uuidGeneratorPage,
41
- '@proteinjs/db-ui/MigrationRecordFormCustomization': MigrationRecordFormCustomization,
34
+ '@proteinjs/db-ui/QueryCursorLoader': QueryCursorLoader,
35
+ '@proteinjs/db-ui/QueryTableLoader': QueryTableLoader,
36
+ '@proteinjs/db-ui/RecordFormCustomization': RecordFormCustomization,
37
+ '@proteinjs/db-ui/hashGeneratorPage': hashGeneratorPage,
38
+ '@proteinjs/db-ui/recordFormPage': recordFormPage,
39
+ '@proteinjs/db-ui/recordTablePage': recordTablePage,
40
+ '@proteinjs/db-ui/tablesPage': tablesPage,
41
+ '@proteinjs/db-ui/uuidGeneratorPage': uuidGeneratorPage,
42
+ '@proteinjs/db-ui/MigrationRecordFormCustomization': MigrationRecordFormCustomization,
42
43
  };
43
44
 
44
-
45
45
  /** Load Source Graph and Links */
46
46
 
47
47
  import { SourceRepository } from '@proteinjs/reflection';
48
48
  SourceRepository.merge(sourceGraph, sourceLinks);
49
49
 
50
-
51
- export * from '../index';
50
+ export * from '../index';
package/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './src/table/RecordTable';
2
2
  export * from './src/table/QueryTableLoader';
3
+ export * from './src/table/QueryCursorLoader';
3
4
  export * from './src/form/RecordForm';
4
5
  export * from './src/form/RecordFormCustomization';
5
6
  export * from './src/pages/RecordTablePage';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proteinjs/db-ui",
3
- "version": "1.7.1",
3
+ "version": "1.8.1",
4
4
  "description": "Db ui components",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -26,7 +26,7 @@
26
26
  "@emotion/styled": "11.11.0",
27
27
  "@mui/icons-material": "5.14.11",
28
28
  "@mui/material": "5.14.11",
29
- "@proteinjs/db": "^1.28.1",
29
+ "@proteinjs/db": "^1.29.1",
30
30
  "@proteinjs/reflection": "^1.1.12",
31
31
  "@proteinjs/ui": "^4.5.0",
32
32
  "@proteinjs/util": "^1.6.1",
@@ -52,5 +52,6 @@
52
52
  "typescript": "5.2.2"
53
53
  },
54
54
  "main": "./dist/generated/index.js",
55
- "types": "./dist/generated/index.d.ts"
55
+ "types": "./dist/generated/index.d.ts",
56
+ "gitHead": "c945fb49ea7db32eb5bf51630eff23f5df06560c"
56
57
  }
@@ -0,0 +1,70 @@
1
+ import { QueryBuilder, QueryOptions, Record, SortCriteria, Table, getDb } from '@proteinjs/db';
2
+ import { CursorLoader, CursorValue, CursorWindow, ReactQueryKeys } from '@proteinjs/ui';
3
+
4
+ /**
5
+ * `CursorLoader` over the same QueryBuilder machinery as `QueryTableLoader`: each window
6
+ * applies `cursorField < cursor` (`>` for an ascending sort) plus `paginate(0, windowSize)`
7
+ * on a fresh build of the base query, so rows created or removed while paging can never
8
+ * shift the window frame. The cursor field and direction derive from the PRIMARY sort
9
+ * criterion.
10
+ *
11
+ * `dataKey` is the table name — table-level invalidation (`useTableMutation`) reaches every
12
+ * cursor query over it; `dataQueryKey` is the serialized query + sort.
13
+ */
14
+ export class QueryCursorLoader<T extends Record> implements CursorLoader<T> {
15
+ reactQueryKeys: ReactQueryKeys;
16
+ private sort: SortCriteria<T>[];
17
+
18
+ /**
19
+ * @param table the table to load windows from
20
+ * @param createQuery factory producing a FRESH conditions-only QueryBuilder per call —
21
+ * builders are mutable, so every window builds its own to hang the cursor condition,
22
+ * sort, and pagination on
23
+ * @param sort the sort criteria to apply to every window; the primary criterion is the
24
+ * cursor axis
25
+ * @param queryOptions query options passed through to every window query
26
+ */
27
+ constructor(
28
+ private table: Table<T>,
29
+ private createQuery: () => QueryBuilder<T>,
30
+ sort?: SortCriteria<T>[],
31
+ private queryOptions?: QueryOptions<T>
32
+ ) {
33
+ this.sort = sort ? sort : [{ field: 'created' as keyof T, desc: true }];
34
+ this.reactQueryKeys = {
35
+ dataKey: this.table.name,
36
+ dataQueryKey: JSON.stringify({ query: this.createQuery(), sort: this.sort }),
37
+ };
38
+ }
39
+
40
+ async loadWindow(cursor: CursorValue | null, windowSize: number): Promise<CursorWindow<T>> {
41
+ const qb = this.buildWindowQuery(cursor, windowSize);
42
+ const rows = await getDb().query(this.table, qb, this.queryOptions);
43
+ return { rows, nextCursor: this.deriveNextCursor(rows, windowSize) };
44
+ }
45
+
46
+ private buildWindowQuery(cursor: CursorValue | null, windowSize: number): QueryBuilder<T> {
47
+ const qb = this.createQuery();
48
+ const primarySort = this.sort[0];
49
+ if (cursor !== null) {
50
+ qb.condition({
51
+ field: primarySort.field,
52
+ operator: primarySort.desc ? '<' : '>',
53
+ value: cursor as T[keyof T],
54
+ });
55
+ }
56
+ return qb.sort(this.sort).paginate({ start: 0, end: windowSize });
57
+ }
58
+
59
+ private deriveNextCursor(rows: T[], windowSize: number): CursorValue | null {
60
+ // A short window means the data set is exhausted; a full one implies more may exist —
61
+ // the next (short or empty) window settles it.
62
+ if (rows.length < windowSize) {
63
+ return null;
64
+ }
65
+ // NULL cursor-field rows collect at the tail under the sort, and a null tail can't
66
+ // anchor a cursor: the data set's dated rows are exhausted, so paging stops here.
67
+ const tail = rows[rows.length - 1][this.sort[0].field];
68
+ return tail == null ? null : (tail as unknown as CursorValue);
69
+ }
70
+ }
@@ -0,0 +1,166 @@
1
+ /**
2
+ * QueryCursorLoader (src/table/QueryCursorLoader.ts) at the pure level: react-query key
3
+ * derivation, cursor threading into the window query, and next-cursor derivation — including
4
+ * the null-tail exhaustion rule (NULL cursor-field rows collect at the tail under the sort;
5
+ * a null tail can't anchor a cursor, so paging stops). Window queries are inspected through
6
+ * the QueryBuilder graph; loadWindow's db round-trip is exercised with a stubbed getDb.
7
+ */
8
+ import moment from 'moment';
9
+
10
+ const stagedRows: { rows: unknown[] } = { rows: [] };
11
+ const queries: unknown[] = [];
12
+ const stubDb = {
13
+ query: async (_table: unknown, qb: unknown) => {
14
+ queries.push(qb);
15
+ return stagedRows.rows;
16
+ },
17
+ };
18
+
19
+ jest.mock('@proteinjs/db', () => ({
20
+ ...jest.requireActual('@proteinjs/db'),
21
+ getDb: () => stubDb,
22
+ }));
23
+
24
+ import { QueryBuilder, SortCriteria, Table } from '@proteinjs/db';
25
+ import { CursorValue } from '@proteinjs/ui';
26
+ import { QueryCursorLoader } from '../src/table/QueryCursorLoader';
27
+
28
+ type Row = {
29
+ id: string;
30
+ created: moment.Moment;
31
+ updated: moment.Moment;
32
+ lastActivityAt?: moment.Moment;
33
+ isPinned?: boolean;
34
+ };
35
+
36
+ const table = { name: 'test_content' } as Table<Row>;
37
+ const sort: SortCriteria<Row>[] = [{ field: 'lastActivityAt', desc: true }];
38
+ const createQuery = () => new QueryBuilder<Row>(table.name);
39
+
40
+ /** House pattern: private helpers reachable via a typed cast on the instance. */
41
+ type LoaderInternals = {
42
+ buildWindowQuery(cursor: CursorValue | null, windowSize: number): QueryBuilder<Row>;
43
+ deriveNextCursor(rows: Row[], windowSize: number): CursorValue | null;
44
+ };
45
+
46
+ const internals = (loader: QueryCursorLoader<Row>) => loader as unknown as LoaderInternals;
47
+
48
+ const graphNodes = (qb: QueryBuilder<Row>): any[] => qb.graph.nodes().map((id: string) => qb.graph.node(id));
49
+ const conditionNodes = (qb: QueryBuilder<Row>) => graphNodes(qb).filter((node) => node?.type === 'CONDITION');
50
+ const paginationNode = (qb: QueryBuilder<Row>) => graphNodes(qb).find((node) => node?.type === 'PAGINATION');
51
+ const sortNodes = (qb: QueryBuilder<Row>) => graphNodes(qb).filter((node) => node?.type === 'SORT');
52
+
53
+ const dated = (id: string, at: string | null): Row => ({
54
+ id,
55
+ created: moment(),
56
+ updated: moment(),
57
+ lastActivityAt: at ? moment(at) : undefined,
58
+ });
59
+
60
+ beforeEach(() => {
61
+ stagedRows.rows = [];
62
+ queries.length = 0;
63
+ });
64
+
65
+ describe('reactQueryKeys', () => {
66
+ it('names the data set after the table and the query after its serialized query + sort', () => {
67
+ const loader = new QueryCursorLoader<Row>(table, createQuery, sort);
68
+ expect(loader.reactQueryKeys.dataKey).toBe('test_content');
69
+ // Identical construction = identical identity (warm cache across remounts)...
70
+ const twin = new QueryCursorLoader<Row>(table, createQuery, sort);
71
+ expect(twin.reactQueryKeys.dataQueryKey).toBe(loader.reactQueryKeys.dataQueryKey);
72
+ // ...while a different query or sort is a different identity.
73
+ const narrowed = new QueryCursorLoader<Row>(
74
+ table,
75
+ () => createQuery().condition({ field: 'isPinned', operator: '=', value: true }),
76
+ sort
77
+ );
78
+ expect(narrowed.reactQueryKeys.dataQueryKey).not.toBe(loader.reactQueryKeys.dataQueryKey);
79
+ const resorted = new QueryCursorLoader<Row>(table, createQuery, [{ field: 'lastActivityAt', desc: false }]);
80
+ expect(resorted.reactQueryKeys.dataQueryKey).not.toBe(loader.reactQueryKeys.dataQueryKey);
81
+ });
82
+ });
83
+
84
+ describe('buildWindowQuery — cursor threading', () => {
85
+ it('the first window carries no cursor condition, only the sort and the window pagination', () => {
86
+ const loader = new QueryCursorLoader<Row>(table, createQuery, sort);
87
+ const qb = internals(loader).buildWindowQuery(null, 30);
88
+ expect(conditionNodes(qb)).toHaveLength(0);
89
+ expect(paginationNode(qb)).toMatchObject({ start: 0, end: 30 });
90
+ expect(sortNodes(qb)).toHaveLength(1);
91
+ expect(sortNodes(qb)[0].criteria).toMatchObject({ field: 'lastActivityAt', desc: true });
92
+ });
93
+
94
+ it('a cursor becomes `field < cursor` on the primary sort field for a descending sort', () => {
95
+ const loader = new QueryCursorLoader<Row>(table, createQuery, sort);
96
+ const cursor = moment('2026-08-10T12:00:00.000Z');
97
+ const qb = internals(loader).buildWindowQuery(cursor, 30);
98
+ const conditions = conditionNodes(qb);
99
+ expect(conditions).toHaveLength(1);
100
+ expect(conditions[0]).toMatchObject({ field: 'lastActivityAt', operator: '<' });
101
+ expect(conditions[0].value).toBe(cursor);
102
+ expect(paginationNode(qb)).toMatchObject({ start: 0, end: 30 });
103
+ });
104
+
105
+ it('an ascending primary sort flips the cursor operator to `>`', () => {
106
+ const loader = new QueryCursorLoader<Row>(table, createQuery, [{ field: 'lastActivityAt', desc: false }]);
107
+ const qb = internals(loader).buildWindowQuery(5, 10);
108
+ expect(conditionNodes(qb)[0]).toMatchObject({ field: 'lastActivityAt', operator: '>', value: 5 });
109
+ });
110
+
111
+ it('every window builds on a FRESH query — cursor conditions never accumulate across windows', () => {
112
+ const loader = new QueryCursorLoader<Row>(table, createQuery, sort);
113
+ internals(loader).buildWindowQuery(moment('2026-08-10T12:00:00.000Z'), 30);
114
+ const second = internals(loader).buildWindowQuery(moment('2026-08-01T12:00:00.000Z'), 30);
115
+ expect(conditionNodes(second)).toHaveLength(1);
116
+ });
117
+ });
118
+
119
+ describe('deriveNextCursor — exhaustion', () => {
120
+ const loader = new QueryCursorLoader<Row>(table, createQuery, sort);
121
+
122
+ it('a short window is exhausted', () => {
123
+ expect(internals(loader).deriveNextCursor([dated('a', '2026-08-10T12:00:00.000Z')], 3)).toBeNull();
124
+ expect(internals(loader).deriveNextCursor([], 3)).toBeNull();
125
+ });
126
+
127
+ it('a full window anchors the next cursor at its tail', () => {
128
+ const rows = [
129
+ dated('a', '2026-08-10T12:00:00.000Z'),
130
+ dated('b', '2026-08-09T12:00:00.000Z'),
131
+ dated('c', '2026-08-08T12:00:00.000Z'),
132
+ ];
133
+ const next = internals(loader).deriveNextCursor(rows, 3);
134
+ expect(next).toBe(rows[2].lastActivityAt);
135
+ });
136
+
137
+ it('a full window with a NULL cursor-field tail is exhausted (null rows collect at the tail; no anchor)', () => {
138
+ const rows = [dated('a', '2026-08-10T12:00:00.000Z'), dated('b', '2026-08-09T12:00:00.000Z'), dated('c', null)];
139
+ expect(internals(loader).deriveNextCursor(rows, 3)).toBeNull();
140
+ });
141
+ });
142
+
143
+ describe('loadWindow', () => {
144
+ it('returns the queried rows with the derived next cursor', async () => {
145
+ const loader = new QueryCursorLoader<Row>(table, createQuery, sort);
146
+ const rows = [
147
+ dated('a', '2026-08-10T12:00:00.000Z'),
148
+ dated('b', '2026-08-09T12:00:00.000Z'),
149
+ dated('c', '2026-08-08T12:00:00.000Z'),
150
+ ];
151
+ stagedRows.rows = rows;
152
+ const window = await loader.loadWindow(null, 3);
153
+ expect(window.rows).toBe(rows);
154
+ expect(window.nextCursor).toBe(rows[2].lastActivityAt);
155
+ // The executed query is the built window query: pagination sized to the window.
156
+ expect(queries).toHaveLength(1);
157
+ expect(paginationNode(queries[0] as QueryBuilder<Row>)).toMatchObject({ start: 0, end: 3 });
158
+ });
159
+
160
+ it('returns an exhausted window (null cursor) when the query comes back short', async () => {
161
+ const loader = new QueryCursorLoader<Row>(table, createQuery, sort);
162
+ stagedRows.rows = [dated('a', '2026-08-10T12:00:00.000Z')];
163
+ const window = await loader.loadWindow(moment('2026-08-11T12:00:00.000Z'), 3);
164
+ expect(window.nextCursor).toBeNull();
165
+ });
166
+ });