@genesislcap/grid-pro 14.483.1-alpha-aaddab2.0 → 14.483.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/custom-elements.json +327 -7
- package/dist/dts/datasource/server-side.datasource.d.ts.map +1 -1
- package/dist/dts/datasource/server-side.resource-base.d.ts +23 -2
- package/dist/dts/datasource/server-side.resource-base.d.ts.map +1 -1
- package/dist/dts/datasource/server-side.resource-dataserver.d.ts +32 -1
- package/dist/dts/datasource/server-side.resource-dataserver.d.ts.map +1 -1
- package/dist/dts/datasource/server-side.resource-reqrep.d.ts +1 -1
- package/dist/dts/datasource/server-side.resource-reqrep.d.ts.map +1 -1
- package/dist/esm/datasource/server-side.datasource.js +13 -2
- package/dist/esm/datasource/server-side.resource-base.js +193 -135
- package/dist/esm/datasource/server-side.resource-dataserver.js +284 -28
- package/dist/esm/datasource/server-side.resource-reqrep.js +11 -5
- package/package.json +14 -14
|
@@ -10,6 +10,19 @@ import { BaseServerSideDatasource } from './server-side.resource-base';
|
|
|
10
10
|
export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
11
11
|
constructor(options) {
|
|
12
12
|
super(options);
|
|
13
|
+
/**
|
|
14
|
+
* Blocks awaiting stream messages. Settled blocks remove themselves; destroy() cancels
|
|
15
|
+
* (fails) the rest so AG Grid's concurrent-request slots are always released.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
this.pendingBlocks = new Set();
|
|
19
|
+
/**
|
|
20
|
+
* Highest absolute row index already handed to AG Grid this session (non-pagination).
|
|
21
|
+
* Live DELETEs below this watermark must not remove cache entries - see
|
|
22
|
+
* handleCurrentStreamLoad.
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
this.deliveredRowCount = 0;
|
|
13
26
|
this.createDataserverStreamFunc = options.createDataserverStreamFunc;
|
|
14
27
|
}
|
|
15
28
|
refreshDatasource(params) {
|
|
@@ -18,18 +31,32 @@ export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
|
18
31
|
});
|
|
19
32
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
33
|
var _a;
|
|
34
|
+
this.cancelAllPendingBlocks();
|
|
21
35
|
(_a = this.dataserverStreamSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
22
36
|
this.dataserverStreamSubscription = undefined;
|
|
23
37
|
this.dataserverStream = undefined;
|
|
38
|
+
this.deliveredRowCount = 0;
|
|
24
39
|
yield _super.refreshDatasource.call(this, params);
|
|
25
40
|
});
|
|
26
41
|
}
|
|
27
42
|
getRows(params) {
|
|
28
43
|
return __awaiter(this, void 0, void 0, function* () {
|
|
29
44
|
var _a, _b;
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
|
|
45
|
+
// setupFiltering()/setupSorting() return true when they triggered a refresh: the
|
|
46
|
+
// datasource was re-initialized and AG Grid's SSRM cache purged, so getRows() is
|
|
47
|
+
// re-invoked with fresh params and this invocation is superseded. It must still resolve
|
|
48
|
+
// via params.fail() - AG Grid caps concurrent requests and only frees a slot on
|
|
49
|
+
// success()/fail(); a silent return leaks the slot until the grid stops issuing
|
|
50
|
+
// getRows() entirely. fail() is safe here: the purge already destroyed the cache this
|
|
51
|
+
// request belonged to.
|
|
52
|
+
if (yield this.setupFiltering(params)) {
|
|
53
|
+
params.fail();
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (yield this.setupSorting(params)) {
|
|
57
|
+
params.fail();
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
33
60
|
if (this.pagination && !this.isNewPageSize && this.currentSequenceId > 0) {
|
|
34
61
|
const requestFilter = JSON.stringify((_a = params.request.filterModel) !== null && _a !== void 0 ? _a : {});
|
|
35
62
|
const currentFilter = JSON.stringify((_b = this.currentFilterModel) !== null && _b !== void 0 ? _b : {});
|
|
@@ -41,7 +68,20 @@ export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
|
41
68
|
if (!this.dataserverStream) {
|
|
42
69
|
this.dataserverStream = yield this.createDataserverStreamFunc(this.resourceParams);
|
|
43
70
|
}
|
|
71
|
+
const blockStartRow = Number.isFinite(Number(params.request.startRow))
|
|
72
|
+
? Number(params.request.startRow)
|
|
73
|
+
: 0;
|
|
74
|
+
const blockEndRow = Number.isFinite(Number(params.request.endRow))
|
|
75
|
+
? Number(params.request.endRow)
|
|
76
|
+
: blockStartRow + Number(this.maxRows);
|
|
77
|
+
// Infinite scroll keeps a session-cumulative row cache (see handleCurrentStreamLoad);
|
|
78
|
+
// when it already covers this block, or the stream ended, no further stream messages
|
|
79
|
+
// will arrive for this request - resolve it synchronously from the cache.
|
|
80
|
+
const blockAlreadyCovered = !this.pagination &&
|
|
81
|
+
this.currentSequenceId >= 1 &&
|
|
82
|
+
(this.rowData.size >= blockEndRow || !this.moreRows);
|
|
44
83
|
if (this.currentSequenceId >= 1 &&
|
|
84
|
+
!blockAlreadyCovered &&
|
|
45
85
|
(this.moreRows || params.request.startRow >= Number(this.maxRows))) {
|
|
46
86
|
if (this.pagination) {
|
|
47
87
|
const startRow = Number.isFinite(Number(params.request.startRow))
|
|
@@ -58,16 +98,96 @@ export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
|
58
98
|
this.connect.getMoreRows(this.sourceRef, viewNumber);
|
|
59
99
|
}
|
|
60
100
|
}
|
|
101
|
+
// One shared stream subscription for the session; each getRows() registers a pending
|
|
102
|
+
// block instead of subscribing again (.unsubscribe() would send DATA_LOGOFF and kill
|
|
103
|
+
// the whole server-side session).
|
|
61
104
|
let applyResult = true;
|
|
62
|
-
|
|
105
|
+
const clearSafetyTimer = (timer) => {
|
|
106
|
+
if (timer !== undefined) {
|
|
107
|
+
clearTimeout(timer);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
const pendingBlock = { handle: () => { }, cancel: () => { } };
|
|
111
|
+
const settleBlock = () => {
|
|
112
|
+
this.pendingBlocks.delete(pendingBlock);
|
|
113
|
+
};
|
|
114
|
+
const resolveBlock = (timer) => {
|
|
115
|
+
if (!applyResult) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
applyResult = false;
|
|
119
|
+
clearSafetyTimer(timer);
|
|
120
|
+
settleBlock();
|
|
121
|
+
if (!this.pagination) {
|
|
122
|
+
this.deliveredRowCount = Math.max(this.deliveredRowCount, blockEndRow);
|
|
123
|
+
}
|
|
124
|
+
const allRows = Array.from(this.rowData.values());
|
|
125
|
+
const successRowData = {
|
|
126
|
+
// Non-pagination: deliver only this block's slice of the cache - AG Grid SSRM
|
|
127
|
+
// expects exactly the rows for its startRow..endRow range.
|
|
128
|
+
rowData: this.pagination ? allRows : allRows.slice(blockStartRow, blockEndRow),
|
|
129
|
+
};
|
|
130
|
+
successRowData.rowCount = this.getCorrectRowCount(params);
|
|
131
|
+
this.lastSuccessRowData = successRowData;
|
|
132
|
+
params.success(successRowData);
|
|
133
|
+
this.notifyNoDataAvailableIfEmpty(params, successRowData);
|
|
134
|
+
};
|
|
135
|
+
const failBlock = (timer) => {
|
|
136
|
+
if (!applyResult) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
applyResult = false;
|
|
140
|
+
clearSafetyTimer(timer);
|
|
141
|
+
settleBlock();
|
|
142
|
+
params.fail();
|
|
143
|
+
};
|
|
144
|
+
if (blockAlreadyCovered) {
|
|
145
|
+
resolveBlock();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
// Safety valve: never leave a block pending forever if the stream goes quiet - resolve
|
|
149
|
+
// short with the accumulated rows so AG Grid ends the dataset there.
|
|
150
|
+
const safetyTimer = setTimeout(() => {
|
|
151
|
+
if (applyResult) {
|
|
152
|
+
logger.warn(`SSRM block ${blockStartRow}-${blockEndRow} for ${this.resourceName} timed out waiting for a full batch; resolving with ${this.rowData.size} accumulated row(s).`);
|
|
153
|
+
resolveBlock(safetyTimer);
|
|
154
|
+
}
|
|
155
|
+
}, DataserverServerSideDatasource.BLOCK_RESOLVE_TIMEOUT_MS);
|
|
156
|
+
pendingBlock.cancel = () => failBlock(safetyTimer);
|
|
157
|
+
pendingBlock.handle = (dataserverResult) => {
|
|
63
158
|
var _a;
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
159
|
+
const messageType = dataserverResult === null || dataserverResult === void 0 ? void 0 : dataserverResult.MESSAGE_TYPE;
|
|
160
|
+
if (messageType &&
|
|
161
|
+
(messageType === MessageType.LOGOFF_ACK || messageType === MessageType.MSG_NACK)) {
|
|
162
|
+
if (this.errorHandlerFunc) {
|
|
163
|
+
const errorMessage = messageType === MessageType.LOGOFF_ACK
|
|
164
|
+
? `Connection lost to ${this.resourceName}`
|
|
165
|
+
: `Authentication failed for ${this.resourceName}`;
|
|
166
|
+
this.errorHandlerFunc(errorMessage, 'connection');
|
|
167
|
+
}
|
|
168
|
+
failBlock(safetyTimer);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (this.pagination) {
|
|
172
|
+
const incomingRowCount = (_a = dataserverResult === null || dataserverResult === void 0 ? void 0 : dataserverResult.ROW) === null || _a === void 0 ? void 0 : _a.length;
|
|
173
|
+
const shouldApply = applyResult || (incomingRowCount > 0 && this.rowData.size === 0);
|
|
174
|
+
if (!shouldApply) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// Paginated mode keeps the original behaviour: each message resolves the request
|
|
178
|
+
// (page swap).
|
|
67
179
|
DOM.queueUpdate(() => __awaiter(this, void 0, void 0, function* () {
|
|
68
180
|
var _a, _b;
|
|
181
|
+
if (!applyResult && !(incomingRowCount > 0 && this.rowData.size === 0)) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
// Claim the block synchronously, before the await below, so a concurrently queued
|
|
185
|
+
// update sees applyResult === false and bails - and so applyResult is never
|
|
186
|
+
// reassigned based on a value read before an await (require-atomic-updates).
|
|
187
|
+
applyResult = false;
|
|
188
|
+
clearSafetyTimer(safetyTimer);
|
|
69
189
|
// TODO: this is a bit of hack, due GSF not returning a different ROWS_COUNT when there is a CRITERIA_MATCH
|
|
70
|
-
if (this.resourceParams.CRITERIA_MATCH && this.
|
|
190
|
+
if (this.resourceParams.CRITERIA_MATCH && !this.criteriaRowCountResolved) {
|
|
71
191
|
const updatedInfo = yield this.connect.snapshot(this.resourceName, {
|
|
72
192
|
MAX_ROWS: this.maxView,
|
|
73
193
|
MAX_VIEW: this.maxView,
|
|
@@ -79,18 +199,95 @@ export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
|
79
199
|
this.clientRowsCount = 0;
|
|
80
200
|
}
|
|
81
201
|
else {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
202
|
+
// ROWS_COUNT ignores CRITERIA_MATCH and ROW.length is capped at page size;
|
|
203
|
+
// Math.max may over-report (self-corrects when the stream ends) but never
|
|
204
|
+
// under-reports, which would make AG Grid stop requesting blocks.
|
|
205
|
+
const rowsCount = (_a = updatedInfo.ROWS_COUNT) !== null && _a !== void 0 ? _a : 0;
|
|
206
|
+
const rowLength = (_b = updatedInfo.ROW) === null || _b === void 0 ? void 0 : _b.length;
|
|
207
|
+
this.serverRowsCount =
|
|
208
|
+
rowLength !== undefined ? Math.max(rowsCount, rowLength) : rowsCount;
|
|
209
|
+
this.criteriaRowCountResolved = true;
|
|
85
210
|
}
|
|
86
211
|
}
|
|
87
212
|
this.applyServerSideData(params, dataserverResult);
|
|
88
|
-
|
|
213
|
+
settleBlock();
|
|
89
214
|
}));
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (!applyResult) {
|
|
218
|
+
return;
|
|
90
219
|
}
|
|
91
|
-
|
|
220
|
+
// Infinite scroll accumulation runs once in dispatchStreamMessage(); here we only
|
|
221
|
+
// decide whether this block is ready to resolve.
|
|
222
|
+
if (this.currentSequenceId === 0 && !(dataserverResult === null || dataserverResult === void 0 ? void 0 : dataserverResult.ROW) && !this.moreRows) {
|
|
223
|
+
// First response carries no rows - the criteria matches nothing; resolve as
|
|
224
|
+
// empty instead of waiting for the timeout.
|
|
225
|
+
applyResult = false;
|
|
226
|
+
clearSafetyTimer(safetyTimer);
|
|
227
|
+
settleBlock();
|
|
228
|
+
this.completeEmptyResult(params);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (this.rowData.size >= blockEndRow || !this.moreRows) {
|
|
232
|
+
DOM.queueUpdate(() => resolveBlock(safetyTimer));
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
this.pendingBlocks.add(pendingBlock);
|
|
236
|
+
this.ensureStreamSubscription();
|
|
92
237
|
});
|
|
93
238
|
}
|
|
239
|
+
/** @internal */
|
|
240
|
+
cancelAllPendingBlocks() {
|
|
241
|
+
const blocks = Array.from(this.pendingBlocks);
|
|
242
|
+
this.pendingBlocks.clear();
|
|
243
|
+
for (const block of blocks) {
|
|
244
|
+
block.cancel();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Lazily attaches the single stream subscription for this datasource session.
|
|
249
|
+
* @internal
|
|
250
|
+
*/
|
|
251
|
+
ensureStreamSubscription() {
|
|
252
|
+
if (this.dataserverStreamSubscription) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
this.dataserverStreamSubscription = this.dataserverStream.subscribe((dataserverResult) => this.dispatchStreamMessage(dataserverResult));
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Fan-out: accumulate shared infinite-scroll state once, then notify each pending block.
|
|
259
|
+
* @internal
|
|
260
|
+
*/
|
|
261
|
+
dispatchStreamMessage(dataserverResult) {
|
|
262
|
+
var _a;
|
|
263
|
+
const messageType = dataserverResult === null || dataserverResult === void 0 ? void 0 : dataserverResult.MESSAGE_TYPE;
|
|
264
|
+
if (messageType &&
|
|
265
|
+
(messageType === MessageType.LOGOFF_ACK || messageType === MessageType.MSG_NACK)) {
|
|
266
|
+
for (const block of this.pendingBlocks) {
|
|
267
|
+
block.handle(dataserverResult);
|
|
268
|
+
}
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (!this.pagination) {
|
|
272
|
+
if ((dataserverResult === null || dataserverResult === void 0 ? void 0 : dataserverResult.MORE_ROWS) !== undefined) {
|
|
273
|
+
this.moreRows = dataserverResult.MORE_ROWS;
|
|
274
|
+
}
|
|
275
|
+
if (dataserverResult === null || dataserverResult === void 0 ? void 0 : dataserverResult.ROW) {
|
|
276
|
+
const nextMessage = dataServerResultFilter(dataserverResult, this.rowId);
|
|
277
|
+
this.handleCurrentStreamLoad(nextMessage);
|
|
278
|
+
this.currentSequenceId = dataserverResult.SEQUENCE_ID;
|
|
279
|
+
if (this.currentSequenceId === 1) {
|
|
280
|
+
this.sourceRef = dataserverResult.SOURCE_REF;
|
|
281
|
+
if (this.serverRowsCount === 0) {
|
|
282
|
+
this.serverRowsCount = (_a = dataserverResult.ROWS_COUNT) !== null && _a !== void 0 ? _a : this.rowData.size;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
for (const block of this.pendingBlocks) {
|
|
288
|
+
block.handle(dataserverResult);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
94
291
|
applyServerSideData(params, result) {
|
|
95
292
|
var _a;
|
|
96
293
|
const messageType = result.MESSAGE_TYPE;
|
|
@@ -108,7 +305,7 @@ export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
|
108
305
|
}
|
|
109
306
|
this.moreRows = result.MORE_ROWS;
|
|
110
307
|
if (result.ROW) {
|
|
111
|
-
const nextMessage = dataServerResultFilter(result);
|
|
308
|
+
const nextMessage = dataServerResultFilter(result, this.rowId);
|
|
112
309
|
this.handleCurrentStreamLoad(nextMessage);
|
|
113
310
|
}
|
|
114
311
|
else {
|
|
@@ -134,10 +331,9 @@ export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
|
134
331
|
if (this.serverRowsCount === 0) {
|
|
135
332
|
this.serverRowsCount = (_a = result.ROWS_COUNT) !== null && _a !== void 0 ? _a : this.rowData.size;
|
|
136
333
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
334
|
+
// Deliberately not overriding serverRowsCount with ROW.length under CRITERIA_MATCH:
|
|
335
|
+
// ROW.length is just the first batch's size and clobbered the corrected count from
|
|
336
|
+
// the snapshot() workaround in getRows().
|
|
141
337
|
}
|
|
142
338
|
const successRowData = {
|
|
143
339
|
rowData: Array.from(this.rowData.values()),
|
|
@@ -153,7 +349,7 @@ export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
|
153
349
|
*/
|
|
154
350
|
setupSorting(params) {
|
|
155
351
|
return __awaiter(this, void 0, void 0, function* () {
|
|
156
|
-
var _a;
|
|
352
|
+
var _a, _b, _c;
|
|
157
353
|
const toBeAppliedSortModel = params.request.sortModel;
|
|
158
354
|
if (((_a = this.currentSortModel) === null || _a === void 0 ? void 0 : _a.length) !== toBeAppliedSortModel.length ||
|
|
159
355
|
toBeAppliedSortModel.length > 0) {
|
|
@@ -163,31 +359,49 @@ export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
|
163
359
|
this.resourceParams.ORDER_BY = null;
|
|
164
360
|
this.resourceParams.REVERSE = null;
|
|
165
361
|
yield this.refreshDatasource(params);
|
|
166
|
-
return;
|
|
362
|
+
return true;
|
|
167
363
|
}
|
|
168
364
|
else if (toBeAppliedSortModel.length > 0) {
|
|
169
365
|
const coldIdBeingSorted = toBeAppliedSortModel[0].colId; // Not allowing multiple sorts by user
|
|
170
366
|
const sortTypeBeingApplied = toBeAppliedSortModel[0].sort;
|
|
171
367
|
const orderByAndToBeSortedColIds = this.getOrderByAndToBeSortedColIds(this.resourceIndexes, coldIdBeingSorted);
|
|
172
368
|
if (!orderByAndToBeSortedColIds) {
|
|
173
|
-
this.calculatedRowsCount = 0;
|
|
174
369
|
const availableIndexes = getAvailableIndexes(this.resourceIndexes);
|
|
175
370
|
const availableIndexFields = getAvailableIndexFields(this.resourceIndexes);
|
|
176
|
-
logger.warn(`The FIELD/column (${coldIdBeingSorted}) being sorted is not part of an INDEX, required for the [orderBy] operation. See https://learn.genesis.global/docs/database/data-types/index-entities/`);
|
|
371
|
+
logger.warn(`The FIELD/column (${coldIdBeingSorted}) being sorted is not part of an INDEX, required for the [orderBy] operation - ignoring this sort and loading unsorted data. See https://learn.genesis.global/docs/database/data-types/index-entities/`);
|
|
177
372
|
logger.debug('Available indexes:', availableIndexes);
|
|
178
373
|
logger.debug('Columns that can be sorted with the available indexes:', availableIndexFields);
|
|
179
|
-
|
|
180
|
-
|
|
374
|
+
// Ignore the un-sortable sort instead of failing - failing killed the entire
|
|
375
|
+
// first load when a restored workspace carried a sort on a non-indexed column.
|
|
376
|
+
const sortModelChanged = JSON.stringify(toBeAppliedSortModel) !== JSON.stringify(this.currentSortModel);
|
|
377
|
+
const hadPreviousSort = ((_c = (_b = this.currentSortModel) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0) > 0;
|
|
378
|
+
const hasActiveOrderBy = this.resourceParams.ORDER_BY != null || this.resourceParams.REVERSE != null;
|
|
379
|
+
// Remember the model so identical requests don't re-warn, and carry on unsorted.
|
|
380
|
+
this.currentSortModel = toBeAppliedSortModel;
|
|
381
|
+
// A previously applied (indexed) sort left ORDER_BY/REVERSE pointing at the old
|
|
382
|
+
// column; clear them and reload once so the grid shows genuinely unsorted data
|
|
383
|
+
// instead of the old column's order under the ignored new sort's header. Gated by
|
|
384
|
+
// hadPreviousSort so a first-load restored sort still just carries on (no extra
|
|
385
|
+
// reload), and by sortModelChanged so the post-refresh getRows() (same model) does
|
|
386
|
+
// not loop.
|
|
387
|
+
if (hadPreviousSort && sortModelChanged && hasActiveOrderBy) {
|
|
388
|
+
this.resourceParams.ORDER_BY = null;
|
|
389
|
+
this.resourceParams.REVERSE = null;
|
|
390
|
+
yield this.refreshDatasource(params);
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
return false;
|
|
181
394
|
}
|
|
182
395
|
else if (JSON.stringify(toBeAppliedSortModel) !== JSON.stringify(this.currentSortModel)) {
|
|
183
396
|
this.currentSortModel = toBeAppliedSortModel;
|
|
184
397
|
this.resourceParams.ORDER_BY = orderByAndToBeSortedColIds.orderBy;
|
|
185
398
|
this.resourceParams.REVERSE = sortTypeBeingApplied === 'desc' ? true : false;
|
|
186
399
|
yield this.refreshDatasource(params);
|
|
187
|
-
return;
|
|
400
|
+
return true;
|
|
188
401
|
}
|
|
189
402
|
}
|
|
190
403
|
}
|
|
404
|
+
return false;
|
|
191
405
|
});
|
|
192
406
|
}
|
|
193
407
|
destroy() {
|
|
@@ -196,21 +410,63 @@ export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
|
196
410
|
});
|
|
197
411
|
return __awaiter(this, void 0, void 0, function* () {
|
|
198
412
|
var _a;
|
|
413
|
+
this.cancelAllPendingBlocks();
|
|
199
414
|
this.dataserverStream = undefined;
|
|
200
415
|
(_a = this.dataserverStreamSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
201
416
|
this.dataserverStreamSubscription = undefined;
|
|
417
|
+
this.deliveredRowCount = 0;
|
|
202
418
|
yield _super.destroy.call(this);
|
|
203
419
|
});
|
|
204
420
|
}
|
|
205
421
|
handleCurrentStreamLoad(result) {
|
|
206
|
-
var _a, _b;
|
|
422
|
+
var _a, _b, _c, _d, _e;
|
|
207
423
|
if (!result)
|
|
208
424
|
return;
|
|
209
|
-
|
|
425
|
+
// Pagination replaces the buffer per message (page swap); infinite scroll accumulates a
|
|
426
|
+
// session-cumulative cache, as GSF splits batches across messages and later batches
|
|
427
|
+
// append. Map preserves insertion order, so the cache can be sliced by block range.
|
|
428
|
+
const rows = this.pagination ? new Map() : new Map(this.rowData);
|
|
210
429
|
(_a = result.inserts) === null || _a === void 0 ? void 0 : _a.forEach((insertData) => {
|
|
211
430
|
rows.set(insertData[this.rowId], insertData);
|
|
212
431
|
});
|
|
213
|
-
|
|
432
|
+
// Live QUERY_UPDATE messages can arrive while a block is pending: MODIFY rows may be
|
|
433
|
+
// partial, so merge into the cached row instead of clobbering it; DELETE rows drop out.
|
|
434
|
+
(_b = result.updates) === null || _b === void 0 ? void 0 : _b.forEach((updateData) => {
|
|
435
|
+
const key = updateData === null || updateData === void 0 ? void 0 : updateData[this.rowId];
|
|
436
|
+
if (key === undefined) {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
const existing = rows.get(key);
|
|
440
|
+
rows.set(key, existing ? Object.assign(Object.assign({}, existing), updateData) : updateData);
|
|
441
|
+
});
|
|
442
|
+
(_c = result.deletes) === null || _c === void 0 ? void 0 : _c.forEach((deleteData) => {
|
|
443
|
+
const key = deleteData === null || deleteData === void 0 ? void 0 : deleteData[this.rowId];
|
|
444
|
+
if (key === undefined) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
// Rows already handed to AG Grid sit at fixed absolute indices; removing them from
|
|
448
|
+
// the cumulative cache would shift slice() offsets for later blocks.
|
|
449
|
+
if (!this.pagination && this.deliveredRowCount > 0) {
|
|
450
|
+
let index = 0;
|
|
451
|
+
for (const mapKey of rows.keys()) {
|
|
452
|
+
if (mapKey === key) {
|
|
453
|
+
if (index < this.deliveredRowCount) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
458
|
+
index += 1;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
rows.delete(key);
|
|
462
|
+
});
|
|
463
|
+
this.clientRowsCount += (_e = (_d = result.inserts) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0;
|
|
214
464
|
this.rowData = rows;
|
|
215
465
|
}
|
|
216
466
|
}
|
|
467
|
+
/**
|
|
468
|
+
* Max time a non-paginated SSRM block may stay pending before the safety valve in
|
|
469
|
+
* getRows() resolves it with the rows accumulated so far.
|
|
470
|
+
* @internal
|
|
471
|
+
*/
|
|
472
|
+
DataserverServerSideDatasource.BLOCK_RESOLVE_TIMEOUT_MS = 10000;
|
|
@@ -41,9 +41,14 @@ export class ReqRepServerSideDatasource extends BaseServerSideDatasource {
|
|
|
41
41
|
}
|
|
42
42
|
getRows(params) {
|
|
43
43
|
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
if (yield this.setupFiltering(params)) {
|
|
45
|
+
params.fail();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (yield this.setupSorting(params)) {
|
|
49
|
+
params.fail();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
47
52
|
if (this.pagination && !this.isNewPageSize && this.currentSequenceId > 0) {
|
|
48
53
|
params.success(this.lastSuccessRowData);
|
|
49
54
|
return;
|
|
@@ -255,7 +260,7 @@ export class ReqRepServerSideDatasource extends BaseServerSideDatasource {
|
|
|
255
260
|
this.currentSortModel = null;
|
|
256
261
|
this.resourceParams.DETAILS.ORDER_BY = undefined;
|
|
257
262
|
yield this.refreshDatasource(params);
|
|
258
|
-
return;
|
|
263
|
+
return true;
|
|
259
264
|
}
|
|
260
265
|
else if (toBeAppliedSortModel.length > 0) {
|
|
261
266
|
const coldIdBeingSorted = toBeAppliedSortModel[0].colId; // Not allowing multiple sorts by user
|
|
@@ -266,10 +271,11 @@ export class ReqRepServerSideDatasource extends BaseServerSideDatasource {
|
|
|
266
271
|
this.resourceParams.DETAILS.ORDER_BY =
|
|
267
272
|
coldIdBeingSorted + (sortTypeBeingApplied === 'desc' ? ' DESC' : ' ASC'); // Use the column directly
|
|
268
273
|
yield this.refreshDatasource(params);
|
|
269
|
-
return;
|
|
274
|
+
return true;
|
|
270
275
|
}
|
|
271
276
|
}
|
|
272
277
|
}
|
|
278
|
+
return false;
|
|
273
279
|
});
|
|
274
280
|
}
|
|
275
281
|
refreshDatasource(params) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genesislcap/grid-pro",
|
|
3
3
|
"description": "Genesis Foundation AG Grid",
|
|
4
|
-
"version": "14.483.
|
|
4
|
+
"version": "14.483.2",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "SEE LICENSE IN license.txt",
|
|
7
7
|
"main": "dist/esm/index.js",
|
|
@@ -40,20 +40,20 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@genesislcap/foundation-testing": "14.483.
|
|
44
|
-
"@genesislcap/genx": "14.483.
|
|
45
|
-
"@genesislcap/rollup-builder": "14.483.
|
|
46
|
-
"@genesislcap/ts-builder": "14.483.
|
|
47
|
-
"@genesislcap/uvu-playwright-builder": "14.483.
|
|
48
|
-
"@genesislcap/vite-builder": "14.483.
|
|
49
|
-
"@genesislcap/webpack-builder": "14.483.
|
|
43
|
+
"@genesislcap/foundation-testing": "14.483.2",
|
|
44
|
+
"@genesislcap/genx": "14.483.2",
|
|
45
|
+
"@genesislcap/rollup-builder": "14.483.2",
|
|
46
|
+
"@genesislcap/ts-builder": "14.483.2",
|
|
47
|
+
"@genesislcap/uvu-playwright-builder": "14.483.2",
|
|
48
|
+
"@genesislcap/vite-builder": "14.483.2",
|
|
49
|
+
"@genesislcap/webpack-builder": "14.483.2"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@genesislcap/foundation-comms": "14.483.
|
|
53
|
-
"@genesislcap/foundation-criteria": "14.483.
|
|
54
|
-
"@genesislcap/foundation-logger": "14.483.
|
|
55
|
-
"@genesislcap/foundation-ui": "14.483.
|
|
56
|
-
"@genesislcap/foundation-utils": "14.483.
|
|
52
|
+
"@genesislcap/foundation-comms": "14.483.2",
|
|
53
|
+
"@genesislcap/foundation-criteria": "14.483.2",
|
|
54
|
+
"@genesislcap/foundation-logger": "14.483.2",
|
|
55
|
+
"@genesislcap/foundation-ui": "14.483.2",
|
|
56
|
+
"@genesislcap/foundation-utils": "14.483.2",
|
|
57
57
|
"@microsoft/fast-colors": "5.3.1",
|
|
58
58
|
"@microsoft/fast-components": "2.30.6",
|
|
59
59
|
"@microsoft/fast-element": "1.14.0",
|
|
@@ -91,5 +91,5 @@
|
|
|
91
91
|
"require": "./dist/react.cjs"
|
|
92
92
|
}
|
|
93
93
|
},
|
|
94
|
-
"gitHead": "
|
|
94
|
+
"gitHead": "a4347351b733c1f31b234a7f2a668f6b8166723b"
|
|
95
95
|
}
|