@memberjunction/core 5.33.0 → 5.34.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/dist/generic/baseEngine.d.ts +41 -5
- package/dist/generic/baseEngine.d.ts.map +1 -1
- package/dist/generic/baseEngine.js +84 -23
- package/dist/generic/baseEngine.js.map +1 -1
- package/dist/generic/baseEntity.d.ts +17 -1
- package/dist/generic/baseEntity.d.ts.map +1 -1
- package/dist/generic/baseEntity.js +26 -4
- package/dist/generic/baseEntity.js.map +1 -1
- package/dist/generic/databaseProviderBase.js +2 -2
- package/dist/generic/databaseProviderBase.js.map +1 -1
- package/dist/generic/entityInfo.d.ts +72 -0
- package/dist/generic/entityInfo.d.ts.map +1 -1
- package/dist/generic/entityInfo.js +75 -0
- package/dist/generic/entityInfo.js.map +1 -1
- package/dist/generic/localCacheManager.d.ts +37 -0
- package/dist/generic/localCacheManager.d.ts.map +1 -1
- package/dist/generic/localCacheManager.js +112 -3
- package/dist/generic/localCacheManager.js.map +1 -1
- package/dist/generic/providerBase.d.ts.map +1 -1
- package/dist/generic/providerBase.js +23 -3
- package/dist/generic/providerBase.js.map +1 -1
- package/dist/views/runView.d.ts +101 -0
- package/dist/views/runView.d.ts.map +1 -1
- package/dist/views/runView.js +72 -0
- package/dist/views/runView.js.map +1 -1
- package/package.json +3 -3
- package/readme.md +55 -1
package/dist/views/runView.js
CHANGED
|
@@ -1,4 +1,54 @@
|
|
|
1
1
|
import { MJGlobal } from '@memberjunction/global';
|
|
2
|
+
/**
|
|
3
|
+
* Thrown by {@link RunView} / RunViews when `AfterKey` is provided but cannot be honored.
|
|
4
|
+
*
|
|
5
|
+
* See the keyset-pagination guide for caller patterns. The most common case is `CompositePK`:
|
|
6
|
+
* an entity with a composite primary key cannot use keyset pagination in v1 — callers should
|
|
7
|
+
* either iterate with OFFSET-based `StartRow` (acceptable for small result sets) or restructure
|
|
8
|
+
* the workload around a single-PK projection.
|
|
9
|
+
*
|
|
10
|
+
* @since v5.x
|
|
11
|
+
*/
|
|
12
|
+
export class AfterKeyNotSupportedError extends Error {
|
|
13
|
+
constructor(EntityName, Reason, message) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.EntityName = EntityName;
|
|
16
|
+
this.Reason = Reason;
|
|
17
|
+
this.name = 'AfterKeyNotSupportedError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Orderable SQL types that can be used as the primary key column for keyset pagination.
|
|
22
|
+
*
|
|
23
|
+
* Excludes types where `WHERE pk > @last` is either unsupported or semantically meaningless
|
|
24
|
+
* (`xml`, `sql_variant`, large binary types, etc.). In practice every reasonable primary key
|
|
25
|
+
* type is on this list — this is defensive against exotic future PKs, not a real constraint
|
|
26
|
+
* for any standard MJ entity.
|
|
27
|
+
*
|
|
28
|
+
* Case-insensitive comparison via the helper {@link IsKeysetPaginationOrderableType}.
|
|
29
|
+
*/
|
|
30
|
+
export const KEYSET_PAGINATION_ORDERABLE_PK_TYPES = [
|
|
31
|
+
'uniqueidentifier',
|
|
32
|
+
'int', 'bigint', 'smallint', 'tinyint',
|
|
33
|
+
'decimal', 'numeric', 'money', 'smallmoney',
|
|
34
|
+
'float', 'real', 'double precision',
|
|
35
|
+
'char', 'varchar', 'nchar', 'nvarchar', 'text', 'ntext',
|
|
36
|
+
'date', 'datetime', 'datetime2', 'datetimeoffset', 'smalldatetime', 'time',
|
|
37
|
+
'bit',
|
|
38
|
+
// PostgreSQL native names that may appear in EntityField.Type when running on PG
|
|
39
|
+
'uuid', 'integer', 'bigserial', 'serial', 'numeric', 'character varying', 'character', 'timestamp', 'timestamp with time zone', 'timestamp without time zone', 'boolean'
|
|
40
|
+
];
|
|
41
|
+
/**
|
|
42
|
+
* Returns true if the given SQL type name is acceptable as a keyset-pagination PK column.
|
|
43
|
+
* Comparison is case-insensitive and trims any precision/scale parens (e.g. `nvarchar(255)` → `nvarchar`).
|
|
44
|
+
*/
|
|
45
|
+
export function IsKeysetPaginationOrderableType(sqlTypeName) {
|
|
46
|
+
if (!sqlTypeName)
|
|
47
|
+
return false;
|
|
48
|
+
// Strip parameterization like "nvarchar(255)" or "decimal(10, 2)"
|
|
49
|
+
const normalized = sqlTypeName.replace(/\s*\([^)]*\)\s*$/, '').trim().toLowerCase();
|
|
50
|
+
return KEYSET_PAGINATION_ORDERABLE_PK_TYPES.includes(normalized);
|
|
51
|
+
}
|
|
2
52
|
/**
|
|
3
53
|
* Parameters for running either a stored or dynamic view.
|
|
4
54
|
* A stored view is a view that is saved in the database and can be run either by ID or Name.
|
|
@@ -50,6 +100,8 @@ export class RunViewParams {
|
|
|
50
100
|
return false;
|
|
51
101
|
if (a.StartRow !== b.StartRow)
|
|
52
102
|
return false;
|
|
103
|
+
if (!RunViewParams.afterKeyEqual(a.AfterKey, b.AfterKey))
|
|
104
|
+
return false;
|
|
53
105
|
if (a.ForceAuditLog !== b.ForceAuditLog)
|
|
54
106
|
return false;
|
|
55
107
|
if (a.AuditLogDescription !== b.AuditLogDescription)
|
|
@@ -87,6 +139,26 @@ export class RunViewParams {
|
|
|
87
139
|
}
|
|
88
140
|
return true;
|
|
89
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Helper method to compare two AfterKey (CompositeKey) values for equality.
|
|
144
|
+
* Two AfterKeys are equal if they contain the same key/value pairs (order-insensitive).
|
|
145
|
+
*/
|
|
146
|
+
static afterKeyEqual(a, b) {
|
|
147
|
+
if (a === b)
|
|
148
|
+
return true;
|
|
149
|
+
if (!a || !b)
|
|
150
|
+
return false;
|
|
151
|
+
const aPairs = a.KeyValuePairs ?? [];
|
|
152
|
+
const bPairs = b.KeyValuePairs ?? [];
|
|
153
|
+
if (aPairs.length !== bPairs.length)
|
|
154
|
+
return false;
|
|
155
|
+
for (const pair of aPairs) {
|
|
156
|
+
const match = bPairs.find(p => p.FieldName === pair.FieldName);
|
|
157
|
+
if (!match || match.Value !== pair.Value)
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
90
162
|
/**
|
|
91
163
|
* Helper method to compare two AggregateExpression arrays for equality
|
|
92
164
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runView.js","sourceRoot":"","sources":["../../src/views/runView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAc,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"runView.js","sourceRoot":"","sources":["../../src/views/runView.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.34.1",
|
|
5
5
|
"description": "MemberJunction: Core Library including Metadata, Application, Entity Retrieval and Manipulation, and Utilities",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"vitest": "^3.1.1"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@memberjunction/global": "5.
|
|
30
|
-
"@memberjunction/sql-dialect": "5.
|
|
29
|
+
"@memberjunction/global": "5.34.1",
|
|
30
|
+
"@memberjunction/sql-dialect": "5.34.1",
|
|
31
31
|
"rxjs": "^7.8.2",
|
|
32
32
|
"zod": "~3.24.4",
|
|
33
33
|
"debug": "^4.4.3"
|
package/readme.md
CHANGED
|
@@ -555,6 +555,59 @@ const result = await rv.RunView<OrderEntity>({
|
|
|
555
555
|
// Aggregate results are in result.AggregateResults[]
|
|
556
556
|
```
|
|
557
557
|
|
|
558
|
+
#### Keyset (Seek) Pagination — `AfterKey`
|
|
559
|
+
|
|
560
|
+
For background jobs and bulk processing that iterate through *all* records of a large entity, use `AfterKey` instead of `StartRow`. Keyset pagination stays **O(log N) per page** regardless of depth — `StartRow`/OFFSET pagination becomes progressively slower as the offset grows.
|
|
561
|
+
|
|
562
|
+
```typescript
|
|
563
|
+
import { CompositeKey } from '@memberjunction/core';
|
|
564
|
+
|
|
565
|
+
let lastSeenKey: CompositeKey | undefined; // undefined => first page
|
|
566
|
+
|
|
567
|
+
while (true) {
|
|
568
|
+
const result = await rv.RunView({
|
|
569
|
+
EntityName: 'Tax Returns',
|
|
570
|
+
ExtraFilter: 'AddressLine1 IS NOT NULL',
|
|
571
|
+
AfterKey: lastSeenKey,
|
|
572
|
+
MaxRows: 500,
|
|
573
|
+
ResultType: 'entity_object'
|
|
574
|
+
}, contextUser);
|
|
575
|
+
|
|
576
|
+
if (!result.Success || result.Results.length === 0) break;
|
|
577
|
+
for (const r of result.Results) { /* process */ }
|
|
578
|
+
if (result.Results.length < 500) break; // partial page = end of data
|
|
579
|
+
|
|
580
|
+
const last = result.Results[result.Results.length - 1];
|
|
581
|
+
lastSeenKey = CompositeKey.FromID(last.ID);
|
|
582
|
+
}
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
**Constraints** (throw `AfterKeyNotSupportedError` on violation):
|
|
586
|
+
- Entity must have a **single-column primary key** on a comparable type.
|
|
587
|
+
- `OrderBy`, if set, must reference only the PK column (any `ASC`/`DESC` direction).
|
|
588
|
+
- Cannot be combined with non-zero `StartRow`.
|
|
589
|
+
|
|
590
|
+
Keyset queries automatically bypass the server cache (read + write) — each call uses a different seek key, so caching them is pure overhead.
|
|
591
|
+
|
|
592
|
+
UI grid pagination (a few hundred pages of a few hundred rows) should stay on `StartRow` — keyset isn't necessary there. See **[KEYSET_PAGINATION_GUIDE.md](../../guides/KEYSET_PAGINATION_GUIDE.md)** for the full pattern, validation rules, and reference implementations.
|
|
593
|
+
|
|
594
|
+
```typescript
|
|
595
|
+
// Defensive: catch the framework's typed error if you want to fall back to OFFSET
|
|
596
|
+
import { AfterKeyNotSupportedError } from '@memberjunction/core';
|
|
597
|
+
|
|
598
|
+
try {
|
|
599
|
+
await rv.RunView({ EntityName: 'SomeEntity', AfterKey: key, MaxRows: 500 }, user);
|
|
600
|
+
} catch (e) {
|
|
601
|
+
if (e instanceof AfterKeyNotSupportedError && e.Reason === 'CompositePK') {
|
|
602
|
+
// entity has composite PK — fall back to StartRow-based iteration
|
|
603
|
+
} else {
|
|
604
|
+
throw e;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
Helper: `IsKeysetPaginationOrderableType(sqlTypeName)` — returns true if a column type is acceptable as a keyset PK (essentially all standard SQL types; defensively rejects exotics like `xml`/`sql_variant`/`varbinary`).
|
|
610
|
+
|
|
558
611
|
#### ResultType and Fields Optimization
|
|
559
612
|
|
|
560
613
|
```typescript
|
|
@@ -592,7 +645,8 @@ const countResult = await rv.RunView({
|
|
|
592
645
|
| `Fields` | `string[]` | Field names to return (simple mode only) |
|
|
593
646
|
| `UserSearchString` | `string` | User search term |
|
|
594
647
|
| `MaxRows` | `number` | Maximum rows to return |
|
|
595
|
-
| `StartRow` | `number` | Row offset
|
|
648
|
+
| `StartRow` | `number` | Row offset (OFFSET-based pagination). Use for UI grids. For deep iteration over large tables, prefer `AfterKey`. |
|
|
649
|
+
| `AfterKey` | `CompositeKey` | Keyset (seek) pagination cursor — O(log N) per page regardless of depth. Requires single-column PK. Throws `AfterKeyNotSupportedError` on incompatible entities. See [KEYSET_PAGINATION_GUIDE.md](../../guides/KEYSET_PAGINATION_GUIDE.md). |
|
|
596
650
|
| `ResultType` | `'simple' \| 'entity_object' \| 'count_only'` | Result format |
|
|
597
651
|
| `IgnoreMaxRows` | `boolean` | Bypass entity MaxRows setting |
|
|
598
652
|
| `SaveViewResults` | `boolean` | Store run results for future exclusion |
|