persian-data-grid 0.6.0 → 0.7.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/README.md +1 -1
- package/dist/{ERPTableGroupRow-PSAPAHGL.js → ERPTableGroupRow-E5Q6FYDS.js} +4 -4
- package/dist/{ERPTableGroupRow-PSAPAHGL.js.map → ERPTableGroupRow-E5Q6FYDS.js.map} +1 -1
- package/dist/{ERPTableGroupRow-J5Z2LRC5.cjs → ERPTableGroupRow-F2IPDYL5.cjs} +9 -9
- package/dist/{ERPTableGroupRow-J5Z2LRC5.cjs.map → ERPTableGroupRow-F2IPDYL5.cjs.map} +1 -1
- package/dist/{GridPlugin-CJCaYnlw.d.ts → GridPlugin-Bewn0X51.d.ts} +1 -1
- package/dist/{GridPlugin-oxhq8AsM.d.cts → GridPlugin-DewWufGZ.d.cts} +1 -1
- package/dist/{GridSession-Bc7UIawO.d.ts → GridSession-CeIfVFck.d.ts} +142 -9
- package/dist/{GridSession-B-9lLcoB.d.cts → GridSession-CmQn2RnL.d.cts} +142 -9
- package/dist/GridSyncService-3JQLEY65.cjs +12 -0
- package/dist/{GridSyncService-TAPAHABV.cjs.map → GridSyncService-3JQLEY65.cjs.map} +1 -1
- package/dist/GridSyncService-GECXGEKL.js +3 -0
- package/dist/{GridSyncService-KTLB4KP3.js.map → GridSyncService-GECXGEKL.js.map} +1 -1
- package/dist/{PdfRenderer-CBg7hWNS.d.cts → PdfRenderer-B9FJaCo_.d.cts} +1 -1
- package/dist/{PdfRenderer-1HFh6UeR.d.ts → PdfRenderer-bN7ca_Aj.d.ts} +1 -1
- package/dist/{UITableController-DU8RopUM.d.ts → UITableController-C71LXBiX.d.ts} +48 -2
- package/dist/{UITableController-Cuwq481K.d.cts → UITableController-CIwnHIw8.d.cts} +48 -2
- package/dist/{VazirmatnPdfRenderer-BCMpC1zy.d.cts → VazirmatnPdfRenderer-CpCqA-Wh.d.cts} +2 -2
- package/dist/{VazirmatnPdfRenderer-Dz_G-m3c.d.ts → VazirmatnPdfRenderer-D46smncn.d.ts} +2 -2
- package/dist/adapters/arian-erp.cjs +16 -4
- package/dist/adapters/arian-erp.cjs.map +1 -1
- package/dist/adapters/arian-erp.d.cts +3 -1
- package/dist/adapters/arian-erp.d.ts +3 -1
- package/dist/adapters/arian-erp.js +11 -3
- package/dist/adapters/arian-erp.js.map +1 -1
- package/dist/{applyImportedRows-BO6yxoAN.d.cts → applyImportedRows-C2fWYoPy.d.cts} +3 -3
- package/dist/{applyImportedRows-D4zVY8uD.d.ts → applyImportedRows-Cqh_N_0k.d.ts} +3 -3
- package/dist/{applyRowVisibilityHandler-LXCOGESZ.cjs → applyRowVisibilityHandler-Q64ZFC7A.cjs} +7 -6
- package/dist/applyRowVisibilityHandler-Q64ZFC7A.cjs.map +1 -0
- package/dist/{applyRowVisibilityHandler-KS6TMCBN.js → applyRowVisibilityHandler-ZLZXQEGY.js} +6 -5
- package/dist/applyRowVisibilityHandler-ZLZXQEGY.js.map +1 -0
- package/dist/callbackRemoteApi-BYLjmSI6.d.ts +51 -0
- package/dist/callbackRemoteApi-Cv26MmSD.d.cts +51 -0
- package/dist/{cellRenderContext-DB7V_mlu.d.ts → cellRenderContext-BaNh4qn_.d.ts} +2 -2
- package/dist/{cellRenderContext-DG5BOlxK.d.cts → cellRenderContext-DvngkptV.d.cts} +2 -2
- package/dist/{chunk-HTNJT2QU.js → chunk-27ALJSZP.js} +617 -104
- package/dist/chunk-27ALJSZP.js.map +1 -0
- package/dist/{chunk-KUBVDIF7.cjs → chunk-3HP3HQCW.cjs} +52 -17
- package/dist/chunk-3HP3HQCW.cjs.map +1 -0
- package/dist/{chunk-DXRCYW42.cjs → chunk-52LFOPXD.cjs} +43 -23
- package/dist/chunk-52LFOPXD.cjs.map +1 -0
- package/dist/{chunk-VVGYRZ7S.cjs → chunk-72IVAOTK.cjs} +4 -4
- package/dist/{chunk-VVGYRZ7S.cjs.map → chunk-72IVAOTK.cjs.map} +1 -1
- package/dist/{chunk-LJ7LMEXO.js → chunk-7GWV5HGO.js} +3 -3
- package/dist/{chunk-LJ7LMEXO.js.map → chunk-7GWV5HGO.js.map} +1 -1
- package/dist/{chunk-RM6ZWNT3.js → chunk-7T6AWRPU.js} +43 -23
- package/dist/chunk-7T6AWRPU.js.map +1 -0
- package/dist/{chunk-PXCHPZTP.cjs → chunk-CMQ4VLCW.cjs} +8 -7
- package/dist/{chunk-EHHHC5JV.js.map → chunk-CMQ4VLCW.cjs.map} +1 -1
- package/dist/chunk-E2J533UH.cjs +53 -0
- package/dist/chunk-E2J533UH.cjs.map +1 -0
- package/dist/chunk-F6EMC75A.cjs +34 -0
- package/dist/chunk-F6EMC75A.cjs.map +1 -0
- package/dist/chunk-GKE33FOJ.js +32 -0
- package/dist/chunk-GKE33FOJ.js.map +1 -0
- package/dist/{chunk-QQMU44KJ.js → chunk-HLOHWFOA.js} +52 -19
- package/dist/chunk-HLOHWFOA.js.map +1 -0
- package/dist/{chunk-633KP74Z.js → chunk-KCNTKYUY.js} +19 -2
- package/dist/chunk-KCNTKYUY.js.map +1 -0
- package/dist/{chunk-BLYVOV3G.cjs → chunk-LY27YAXE.cjs} +19 -2
- package/dist/chunk-LY27YAXE.cjs.map +1 -0
- package/dist/{chunk-EHHHC5JV.js → chunk-NB5GCGHL.js} +5 -4
- package/dist/chunk-NB5GCGHL.js.map +1 -0
- package/dist/{chunk-6XBXZPBW.js → chunk-NQUVAJQA.js} +3 -3
- package/dist/{chunk-6XBXZPBW.js.map → chunk-NQUVAJQA.js.map} +1 -1
- package/dist/chunk-SVO62ZV2.js +50 -0
- package/dist/chunk-SVO62ZV2.js.map +1 -0
- package/dist/{chunk-MU3RY46O.js → chunk-VBAZ77Q4.js} +3 -3
- package/dist/{chunk-MU3RY46O.js.map → chunk-VBAZ77Q4.js.map} +1 -1
- package/dist/{chunk-H2LESGMX.cjs → chunk-VSAFQTW5.cjs} +4 -4
- package/dist/{chunk-H2LESGMX.cjs.map → chunk-VSAFQTW5.cjs.map} +1 -1
- package/dist/{chunk-2BJCRYOS.cjs → chunk-VYJQ2HTA.cjs} +5 -5
- package/dist/{chunk-2BJCRYOS.cjs.map → chunk-VYJQ2HTA.cjs.map} +1 -1
- package/dist/{chunk-IIISFUW4.cjs → chunk-WTHTVKVI.cjs} +621 -108
- package/dist/chunk-WTHTVKVI.cjs.map +1 -0
- package/dist/{createEngineGridQuery-Mt1hc33m.d.ts → createEngineGridQuery-BBkud5oE.d.ts} +61 -6
- package/dist/{createEngineGridQuery-Dmq3i5v3.d.cts → createEngineGridQuery-D-fgO_jg.d.cts} +61 -6
- package/dist/date-picker-jalali.cjs +17 -17
- package/dist/date-picker-jalali.d.cts +3 -3
- package/dist/date-picker-jalali.d.ts +3 -3
- package/dist/date-picker-jalali.js +1 -1
- package/dist/headless.cjs +102 -102
- package/dist/headless.d.cts +13 -9
- package/dist/headless.d.ts +13 -9
- package/dist/headless.js +4 -4
- package/dist/index.cjs +440 -382
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -14
- package/dist/index.d.ts +34 -14
- package/dist/index.js +200 -143
- package/dist/index.js.map +1 -1
- package/dist/plugins/csv.cjs +3 -3
- package/dist/plugins/csv.d.cts +2 -2
- package/dist/plugins/csv.d.ts +2 -2
- package/dist/plugins/csv.js +2 -2
- package/dist/plugins/excel.cjs +11 -11
- package/dist/plugins/excel.d.cts +4 -4
- package/dist/plugins/excel.d.ts +4 -4
- package/dist/plugins/excel.js +3 -3
- package/dist/plugins/pdf/fonts/vazirmatn.cjs +6 -6
- package/dist/plugins/pdf/fonts/vazirmatn.d.cts +4 -4
- package/dist/plugins/pdf/fonts/vazirmatn.d.ts +4 -4
- package/dist/plugins/pdf/fonts/vazirmatn.js +3 -3
- package/dist/plugins/pdf.cjs +5 -5
- package/dist/plugins/pdf.d.cts +5 -5
- package/dist/plugins/pdf.d.ts +5 -5
- package/dist/plugins/pdf.js +2 -2
- package/dist/presence.d.cts +3 -3
- package/dist/presence.d.ts +3 -3
- package/dist/sync.cjs +2 -2
- package/dist/sync.d.cts +3 -3
- package/dist/sync.d.ts +3 -3
- package/dist/sync.js +1 -1
- package/package.json +3 -3
- package/dist/GridSyncService-KTLB4KP3.js +0 -3
- package/dist/GridSyncService-TAPAHABV.cjs +0 -12
- package/dist/applyRowVisibilityHandler-KS6TMCBN.js.map +0 -1
- package/dist/applyRowVisibilityHandler-LXCOGESZ.cjs.map +0 -1
- package/dist/callbackRemoteApi-BlXO5NJz.d.ts +0 -30
- package/dist/callbackRemoteApi-DgnXH-i0.d.cts +0 -30
- package/dist/chunk-633KP74Z.js.map +0 -1
- package/dist/chunk-ASPTRYRD.cjs +0 -21
- package/dist/chunk-ASPTRYRD.cjs.map +0 -1
- package/dist/chunk-BHDRUZH5.cjs +0 -33
- package/dist/chunk-BHDRUZH5.cjs.map +0 -1
- package/dist/chunk-BLYVOV3G.cjs.map +0 -1
- package/dist/chunk-DXRCYW42.cjs.map +0 -1
- package/dist/chunk-HTNJT2QU.js.map +0 -1
- package/dist/chunk-IIISFUW4.cjs.map +0 -1
- package/dist/chunk-KUBVDIF7.cjs.map +0 -1
- package/dist/chunk-KYAOSBQN.js +0 -31
- package/dist/chunk-KYAOSBQN.js.map +0 -1
- package/dist/chunk-PXCHPZTP.cjs.map +0 -1
- package/dist/chunk-QQMU44KJ.js.map +0 -1
- package/dist/chunk-RM6ZWNT3.js.map +0 -1
- package/dist/chunk-Y6W5V2CI.js +0 -19
- package/dist/chunk-Y6W5V2CI.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Cell, Row, Table, Collection, RowRemoved, MinimumRowConstraintViolated } from './chunk-5HKVMPBD.js';
|
|
2
2
|
import { isIndexColumn, clampColumnWidth, sizeColumnsToFitWidths, resolveColumnWidth, resolveColumnPinned, ViewportCalculator } from './chunk-IPPIXOVQ.js';
|
|
3
|
-
import { ChangeCellValueHandler, ApplyDynamicProjectionHandler, ChangeCellDisplayValueHandler, SaveDescriptionHandler } from './chunk-
|
|
3
|
+
import { ChangeCellValueHandler, ApplyDynamicProjectionHandler, ChangeCellDisplayValueHandler, SaveDescriptionHandler } from './chunk-7T6AWRPU.js';
|
|
4
4
|
import { DomainError } from './chunk-KHMG6EI2.js';
|
|
5
5
|
import { formatPrice } from './chunk-RKVSJU46.js';
|
|
6
6
|
import { normalizeDigits, isBlankSortValue, findSortedInsertIndex, applySort } from './chunk-AU3RDJYQ.js';
|
|
@@ -1333,6 +1333,7 @@ var SparseRowIndex = class {
|
|
|
1333
1333
|
this.orderedIds = [];
|
|
1334
1334
|
/** id → position in `orderedIds` (PR-99). */
|
|
1335
1335
|
this.posById = /* @__PURE__ */ new Map();
|
|
1336
|
+
this.revisionCount = 0;
|
|
1336
1337
|
for (const [id, value] of entries) {
|
|
1337
1338
|
this.byId.set(id, value);
|
|
1338
1339
|
this.posById.set(id, this.orderedIds.length);
|
|
@@ -1342,6 +1343,13 @@ var SparseRowIndex = class {
|
|
|
1342
1343
|
get size() {
|
|
1343
1344
|
return this.orderedIds.length;
|
|
1344
1345
|
}
|
|
1346
|
+
/**
|
|
1347
|
+
* Bumped by every change of ids, order or values. O(1) change detection for
|
|
1348
|
+
* subscribers (a sort keeps `size` but changes the order).
|
|
1349
|
+
*/
|
|
1350
|
+
get revision() {
|
|
1351
|
+
return this.revisionCount;
|
|
1352
|
+
}
|
|
1345
1353
|
getOrderedIds() {
|
|
1346
1354
|
return this.orderedIds;
|
|
1347
1355
|
}
|
|
@@ -1363,6 +1371,7 @@ var SparseRowIndex = class {
|
|
|
1363
1371
|
}
|
|
1364
1372
|
set(id, value) {
|
|
1365
1373
|
const existed = this.byId.has(id);
|
|
1374
|
+
this.revisionCount += 1;
|
|
1366
1375
|
this.byId.set(id, value);
|
|
1367
1376
|
if (!existed) {
|
|
1368
1377
|
this.posById.set(id, this.orderedIds.length);
|
|
@@ -1371,6 +1380,7 @@ var SparseRowIndex = class {
|
|
|
1371
1380
|
}
|
|
1372
1381
|
/** Insert `id` at `pos` (0…size). Shifts later positions — O(n-pos). */
|
|
1373
1382
|
insertAt(pos, id, value) {
|
|
1383
|
+
this.revisionCount += 1;
|
|
1374
1384
|
if (this.byId.has(id)) {
|
|
1375
1385
|
this.byId.set(id, value);
|
|
1376
1386
|
return;
|
|
@@ -1384,6 +1394,7 @@ var SparseRowIndex = class {
|
|
|
1384
1394
|
}
|
|
1385
1395
|
remove(id) {
|
|
1386
1396
|
if (!this.byId.has(id)) return false;
|
|
1397
|
+
this.revisionCount += 1;
|
|
1387
1398
|
this.byId.delete(id);
|
|
1388
1399
|
const pos = this.posById.get(id);
|
|
1389
1400
|
this.posById.delete(id);
|
|
@@ -1396,6 +1407,7 @@ var SparseRowIndex = class {
|
|
|
1396
1407
|
}
|
|
1397
1408
|
/** Replace order without rebuilding payloads (e.g. after sort). */
|
|
1398
1409
|
setOrder(orderedIds) {
|
|
1410
|
+
this.revisionCount += 1;
|
|
1399
1411
|
this.orderedIds = orderedIds.slice();
|
|
1400
1412
|
this.posById.clear();
|
|
1401
1413
|
for (let i = 0; i < this.orderedIds.length; i += 1) {
|
|
@@ -1404,6 +1416,7 @@ var SparseRowIndex = class {
|
|
|
1404
1416
|
}
|
|
1405
1417
|
/** Full replace of ids + values in one pass (PR-99 rebuild). */
|
|
1406
1418
|
replaceAll(orderedIds, valueFor) {
|
|
1419
|
+
this.revisionCount += 1;
|
|
1407
1420
|
this.byId.clear();
|
|
1408
1421
|
this.orderedIds = orderedIds.slice();
|
|
1409
1422
|
this.posById.clear();
|
|
@@ -1414,6 +1427,7 @@ var SparseRowIndex = class {
|
|
|
1414
1427
|
}
|
|
1415
1428
|
}
|
|
1416
1429
|
clear() {
|
|
1430
|
+
this.revisionCount += 1;
|
|
1417
1431
|
this.byId.clear();
|
|
1418
1432
|
this.orderedIds = [];
|
|
1419
1433
|
this.posById.clear();
|
|
@@ -3142,21 +3156,35 @@ var TableStore = class {
|
|
|
3142
3156
|
var DEFAULT_CELL_EDIT_OPTIONS = {
|
|
3143
3157
|
singleClickEdit: true,
|
|
3144
3158
|
stopEditingWhenCellsLoseFocus: true,
|
|
3145
|
-
editType: "cell"
|
|
3159
|
+
editType: "cell",
|
|
3160
|
+
commit: "deferred",
|
|
3161
|
+
enterNavigation: "nextCell"
|
|
3146
3162
|
};
|
|
3163
|
+
var sessionSeq = 0;
|
|
3147
3164
|
function createCellEditSession(input) {
|
|
3148
3165
|
const drafts = {};
|
|
3149
3166
|
for (const [colId, cell] of Object.entries(input.baseline)) {
|
|
3150
3167
|
drafts[colId] = { value: cell.value, display: cell.display };
|
|
3151
3168
|
}
|
|
3169
|
+
sessionSeq += 1;
|
|
3152
3170
|
return {
|
|
3153
3171
|
rowId: input.rowId,
|
|
3154
3172
|
columnId: input.columnId,
|
|
3155
3173
|
editType: input.editType,
|
|
3156
3174
|
baseline: input.baseline,
|
|
3157
|
-
drafts
|
|
3175
|
+
drafts,
|
|
3176
|
+
correlationId: `cell-edit-${Date.now()}-${sessionSeq}`
|
|
3158
3177
|
};
|
|
3159
3178
|
}
|
|
3179
|
+
function rebaseDraft(session, columnIds) {
|
|
3180
|
+
if (columnIds.length === 0) return session;
|
|
3181
|
+
const baseline = { ...session.baseline };
|
|
3182
|
+
for (const colId of columnIds) {
|
|
3183
|
+
const draft = session.drafts[colId];
|
|
3184
|
+
if (draft) baseline[colId] = { value: draft.value, display: draft.display };
|
|
3185
|
+
}
|
|
3186
|
+
return { ...session, baseline };
|
|
3187
|
+
}
|
|
3160
3188
|
function readDraft(session, rowId, columnId) {
|
|
3161
3189
|
if (!session || session.rowId !== rowId) return null;
|
|
3162
3190
|
return session.drafts[columnId] ?? null;
|
|
@@ -3181,8 +3209,8 @@ function patchDraft(session, columnId, patch) {
|
|
|
3181
3209
|
drafts: {
|
|
3182
3210
|
...session.drafts,
|
|
3183
3211
|
[columnId]: {
|
|
3184
|
-
value:
|
|
3185
|
-
display:
|
|
3212
|
+
value: "value" in patch ? patch.value : prev.value,
|
|
3213
|
+
display: "display" in patch ? patch.display : prev.display
|
|
3186
3214
|
}
|
|
3187
3215
|
}
|
|
3188
3216
|
};
|
|
@@ -4167,6 +4195,7 @@ var ViewStateBuilder = class {
|
|
|
4167
4195
|
};
|
|
4168
4196
|
|
|
4169
4197
|
// engine/tableEngine.ts
|
|
4198
|
+
var cellWriteKey = (kind, rowId, columnId) => `${kind}\0${rowId}\0${columnId}`;
|
|
4170
4199
|
var TableEngine = class {
|
|
4171
4200
|
constructor(app, repo, actor, audit, columnMeta) {
|
|
4172
4201
|
this.app = app;
|
|
@@ -4174,6 +4203,15 @@ var TableEngine = class {
|
|
|
4174
4203
|
this.actor = actor;
|
|
4175
4204
|
this.columnMeta = columnMeta;
|
|
4176
4205
|
this.cellEditOptions = { ...DEFAULT_CELL_EDIT_OPTIONS };
|
|
4206
|
+
/**
|
|
4207
|
+
* Cell writes coming from editors / host input, executed one at a time in
|
|
4208
|
+
* arrival order. Consecutive values for the same cell coalesce (latest
|
|
4209
|
+
* wins). Until a write landed, the queued value is what the cell shows.
|
|
4210
|
+
*/
|
|
4211
|
+
this.cellWrites = /* @__PURE__ */ new Map();
|
|
4212
|
+
this.cellWriteChain = Promise.resolve();
|
|
4213
|
+
/** > 0 while a queued write executes (re-entrant settle must not wait on itself). */
|
|
4214
|
+
this.cellWriteDepth = 0;
|
|
4177
4215
|
this.errors = /* @__PURE__ */ new Map();
|
|
4178
4216
|
this.searchResult = /* @__PURE__ */ new Map();
|
|
4179
4217
|
this.asyncCellCache = /* @__PURE__ */ new Map();
|
|
@@ -4748,54 +4786,54 @@ var TableEngine = class {
|
|
|
4748
4786
|
const next = command.sortModel.filter(
|
|
4749
4787
|
(item) => item && typeof item.colId === "string" && item.colId.length > 0 && (item.sort === "asc" || item.sort === "desc")
|
|
4750
4788
|
).map((item) => ({ colId: item.colId, sort: item.sort }));
|
|
4789
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4751
4790
|
store.setState((prev) => ({
|
|
4752
4791
|
...prev,
|
|
4753
4792
|
sortModel: next
|
|
4754
4793
|
}));
|
|
4755
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4756
4794
|
this.notifyViewQueryChanged();
|
|
4757
4795
|
}
|
|
4758
4796
|
setQuickFilterText(command) {
|
|
4759
4797
|
const store = this.getStore(command.tableKey);
|
|
4760
4798
|
if (!store) return;
|
|
4761
4799
|
const next = typeof command.quickFilterText === "string" ? command.quickFilterText : "";
|
|
4800
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4762
4801
|
store.setState((prev) => ({
|
|
4763
4802
|
...prev,
|
|
4764
4803
|
quickFilterText: next
|
|
4765
4804
|
}));
|
|
4766
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4767
4805
|
}
|
|
4768
4806
|
setFilterModel(command) {
|
|
4769
4807
|
const store = this.getStore(command.tableKey);
|
|
4770
4808
|
if (!store) return;
|
|
4771
4809
|
const next = command.filterModel && typeof command.filterModel === "object" ? { ...command.filterModel } : {};
|
|
4810
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4772
4811
|
store.setState((prev) => ({
|
|
4773
4812
|
...prev,
|
|
4774
4813
|
filterModel: next
|
|
4775
4814
|
}));
|
|
4776
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4777
4815
|
this.notifyViewQueryChanged();
|
|
4778
4816
|
}
|
|
4779
4817
|
setRowGroupColumns(command) {
|
|
4780
4818
|
const store = this.getStore(command.tableKey);
|
|
4781
4819
|
if (!store) return;
|
|
4782
4820
|
const next = command.columns.filter((c) => typeof c === "string" && c.trim() !== "").map((c) => c.trim());
|
|
4821
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4783
4822
|
store.setState((prev) => ({
|
|
4784
4823
|
...prev,
|
|
4785
4824
|
rowGroupColumns: next,
|
|
4786
4825
|
rowGroupExpanded: {}
|
|
4787
4826
|
}));
|
|
4788
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4789
4827
|
}
|
|
4790
4828
|
setGroupDefaultExpanded(command) {
|
|
4791
4829
|
const store = this.getStore(command.tableKey);
|
|
4792
4830
|
if (!store) return;
|
|
4831
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4793
4832
|
store.setState((prev) => ({
|
|
4794
4833
|
...prev,
|
|
4795
4834
|
groupDefaultExpanded: Boolean(command.expanded),
|
|
4796
4835
|
rowGroupExpanded: {}
|
|
4797
4836
|
}));
|
|
4798
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4799
4837
|
}
|
|
4800
4838
|
toggleRowGroup(command) {
|
|
4801
4839
|
const store = this.getStore(command.tableKey);
|
|
@@ -4806,6 +4844,7 @@ var TableEngine = class {
|
|
|
4806
4844
|
state.rowGroupExpanded,
|
|
4807
4845
|
key
|
|
4808
4846
|
) ? state.rowGroupExpanded[key] : state.groupDefaultExpanded;
|
|
4847
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4809
4848
|
store.setState((prev) => ({
|
|
4810
4849
|
...prev,
|
|
4811
4850
|
rowGroupExpanded: {
|
|
@@ -4813,7 +4852,6 @@ var TableEngine = class {
|
|
|
4813
4852
|
[key]: !current
|
|
4814
4853
|
}
|
|
4815
4854
|
}));
|
|
4816
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4817
4855
|
}
|
|
4818
4856
|
/**
|
|
4819
4857
|
* Server/infinite row model hooks (PR-96).
|
|
@@ -5082,6 +5120,7 @@ var TableEngine = class {
|
|
|
5082
5120
|
async getFullSnapShot(store, collectionScope = "active") {
|
|
5083
5121
|
if (!this.tableKey) return null;
|
|
5084
5122
|
try {
|
|
5123
|
+
await this.flushCellEdit();
|
|
5085
5124
|
const rows = await this.loadAllRows(store, collectionScope);
|
|
5086
5125
|
const { rowsToSnapshot } = await import('./memoryRecords-OJTGXLRH.js');
|
|
5087
5126
|
return rowsToSnapshot(rows);
|
|
@@ -5098,6 +5137,7 @@ var TableEngine = class {
|
|
|
5098
5137
|
async iterateRowsFromDb(store, collectionScope, onBatch, batchSize) {
|
|
5099
5138
|
if (!this.tableKey) return;
|
|
5100
5139
|
try {
|
|
5140
|
+
await this.flushCellEdit();
|
|
5101
5141
|
if (isWindowedRepository(this.repo)) {
|
|
5102
5142
|
await this.repo.iterateRowRecords(
|
|
5103
5143
|
store,
|
|
@@ -5154,8 +5194,196 @@ var TableEngine = class {
|
|
|
5154
5194
|
getCellEdit() {
|
|
5155
5195
|
return this.tableStore?.getState().cellEdit ?? null;
|
|
5156
5196
|
}
|
|
5197
|
+
/**
|
|
5198
|
+
* What the cell editor shows: the session draft, else a value that was
|
|
5199
|
+
* typed but whose write has not reached the table yet (no flicker back to
|
|
5200
|
+
* the old value while it is in flight). `null` = show the table value.
|
|
5201
|
+
*/
|
|
5157
5202
|
getEditDraft(rowId, columnId) {
|
|
5158
|
-
|
|
5203
|
+
const draft = readDraft(this.getCellEdit(), rowId, columnId);
|
|
5204
|
+
if (draft) return draft;
|
|
5205
|
+
const value = this.cellWrites.get(cellWriteKey("value", rowId, columnId));
|
|
5206
|
+
const display = this.cellWrites.get(cellWriteKey("display", rowId, columnId));
|
|
5207
|
+
if (!value && !display) return null;
|
|
5208
|
+
const cell = this.viewBuilder.getCell(rowId, columnId);
|
|
5209
|
+
return {
|
|
5210
|
+
value: value ? value.write.value : cell?.getValue(),
|
|
5211
|
+
display: display ? display.write.value : cell?.getDisplay()
|
|
5212
|
+
};
|
|
5213
|
+
}
|
|
5214
|
+
/** Editor / host value for a cell (`UI_CELL_CHANGE`). Resolves once it is durable. */
|
|
5215
|
+
inputCellValue(rowId, columnId, value) {
|
|
5216
|
+
return this.inputCell(rowId, columnId, "value", value);
|
|
5217
|
+
}
|
|
5218
|
+
/** Editor / host display label for a cell (`UI_CELL_CHANGE_DISPLAY`). */
|
|
5219
|
+
inputCellDisplay(rowId, columnId, display) {
|
|
5220
|
+
return this.inputCell(rowId, columnId, "display", display);
|
|
5221
|
+
}
|
|
5222
|
+
async inputCell(rowId, columnId, kind, input) {
|
|
5223
|
+
const store = this.tableStore;
|
|
5224
|
+
if (!store) return;
|
|
5225
|
+
const session = store.getState().cellEdit;
|
|
5226
|
+
if (session && isEditingCell(session, rowId, columnId)) {
|
|
5227
|
+
const immediate = this.cellEditOptions.commit === "immediate";
|
|
5228
|
+
const patch = kind === "value" ? { value: input } : { display: input };
|
|
5229
|
+
store.setState((prev) => {
|
|
5230
|
+
if (!prev.cellEdit || prev.cellEdit.rowId !== rowId) return prev;
|
|
5231
|
+
const patched = patchDraft(prev.cellEdit, columnId, patch);
|
|
5232
|
+
return {
|
|
5233
|
+
...prev,
|
|
5234
|
+
cellEdit: immediate ? rebaseDraft(patched, [columnId]) : patched
|
|
5235
|
+
};
|
|
5236
|
+
});
|
|
5237
|
+
if (!immediate) return;
|
|
5238
|
+
this.enqueueCellWrite({
|
|
5239
|
+
rowId,
|
|
5240
|
+
columnId,
|
|
5241
|
+
kind,
|
|
5242
|
+
value: input,
|
|
5243
|
+
correlationId: session.correlationId
|
|
5244
|
+
});
|
|
5245
|
+
} else {
|
|
5246
|
+
this.enqueueCellWrite({ rowId, columnId, kind, value: input });
|
|
5247
|
+
}
|
|
5248
|
+
await this.settleCellWrites();
|
|
5249
|
+
}
|
|
5250
|
+
enqueueCellWrite(write) {
|
|
5251
|
+
const key = cellWriteKey(write.kind, write.rowId, write.columnId);
|
|
5252
|
+
const pending = this.cellWrites.get(key);
|
|
5253
|
+
if (pending?.queued) {
|
|
5254
|
+
pending.write = write;
|
|
5255
|
+
return;
|
|
5256
|
+
}
|
|
5257
|
+
const slot = { write, queued: true };
|
|
5258
|
+
this.cellWrites.set(key, slot);
|
|
5259
|
+
this.cellWriteChain = this.cellWriteChain.then(() => this.runCellWrite(key, slot));
|
|
5260
|
+
}
|
|
5261
|
+
async runCellWrite(key, slot) {
|
|
5262
|
+
slot.queued = false;
|
|
5263
|
+
const { write } = slot;
|
|
5264
|
+
const commandStore = this.commandStore;
|
|
5265
|
+
const tableKey = this.tableKey;
|
|
5266
|
+
this.cellWriteDepth += 1;
|
|
5267
|
+
try {
|
|
5268
|
+
if (commandStore && tableKey && this.tableStore) {
|
|
5269
|
+
await this.dispatch(
|
|
5270
|
+
write.kind === "value" ? {
|
|
5271
|
+
type: "CHANGE_CELL_VALUE",
|
|
5272
|
+
store: commandStore,
|
|
5273
|
+
tableKey,
|
|
5274
|
+
rowId: write.rowId,
|
|
5275
|
+
columnId: write.columnId,
|
|
5276
|
+
newValue: write.value,
|
|
5277
|
+
correlationId: write.correlationId
|
|
5278
|
+
} : {
|
|
5279
|
+
type: "CHANGE_CELL_DISPLAY_VALUE",
|
|
5280
|
+
store: commandStore,
|
|
5281
|
+
tableKey,
|
|
5282
|
+
rowId: write.rowId,
|
|
5283
|
+
columnId: write.columnId,
|
|
5284
|
+
newValue: write.value == null ? "" : String(write.value),
|
|
5285
|
+
correlationId: write.correlationId
|
|
5286
|
+
}
|
|
5287
|
+
);
|
|
5288
|
+
}
|
|
5289
|
+
} catch (e) {
|
|
5290
|
+
this.errHandler.handle(e, "TableEngine.cellWrite");
|
|
5291
|
+
} finally {
|
|
5292
|
+
this.cellWriteDepth -= 1;
|
|
5293
|
+
if (this.cellWrites.get(key) === slot && !slot.queued) {
|
|
5294
|
+
this.cellWrites.delete(key);
|
|
5295
|
+
const cell = this.viewBuilder.getCell(write.rowId, write.columnId);
|
|
5296
|
+
const landed = write.kind === "value" ? cell?.getValue() : cell?.getDisplay();
|
|
5297
|
+
if (landed !== write.value) this.tableStore?.setState((prev) => ({ ...prev }));
|
|
5298
|
+
}
|
|
5299
|
+
}
|
|
5300
|
+
}
|
|
5301
|
+
/**
|
|
5302
|
+
* Resolves when every queued cell write reached the table. Called from inside
|
|
5303
|
+
* a write (re-entrant) it returns at once instead of waiting on itself.
|
|
5304
|
+
*/
|
|
5305
|
+
async settleCellWrites() {
|
|
5306
|
+
if (this.cellWriteDepth > 0) return;
|
|
5307
|
+
let chain;
|
|
5308
|
+
do {
|
|
5309
|
+
chain = this.cellWriteChain;
|
|
5310
|
+
await chain;
|
|
5311
|
+
} while (chain !== this.cellWriteChain);
|
|
5312
|
+
}
|
|
5313
|
+
/** Queues CHANGE_CELL_* for `columnIds` of `session`; returns the value writes. */
|
|
5314
|
+
queueDraftWrites(session, columnIds) {
|
|
5315
|
+
let writes = 0;
|
|
5316
|
+
for (const colId of columnIds) {
|
|
5317
|
+
const draft = session.drafts[colId];
|
|
5318
|
+
if (!draft) continue;
|
|
5319
|
+
const base = session.baseline[colId];
|
|
5320
|
+
if (!base || draft.value !== base.value) {
|
|
5321
|
+
this.enqueueCellWrite({
|
|
5322
|
+
rowId: session.rowId,
|
|
5323
|
+
columnId: colId,
|
|
5324
|
+
kind: "value",
|
|
5325
|
+
value: draft.value,
|
|
5326
|
+
correlationId: session.correlationId
|
|
5327
|
+
});
|
|
5328
|
+
writes += 1;
|
|
5329
|
+
}
|
|
5330
|
+
if (!base || draft.display !== base.display) {
|
|
5331
|
+
this.enqueueCellWrite({
|
|
5332
|
+
rowId: session.rowId,
|
|
5333
|
+
columnId: colId,
|
|
5334
|
+
kind: "display",
|
|
5335
|
+
value: draft.display,
|
|
5336
|
+
correlationId: session.correlationId
|
|
5337
|
+
});
|
|
5338
|
+
}
|
|
5339
|
+
}
|
|
5340
|
+
return writes;
|
|
5341
|
+
}
|
|
5342
|
+
/**
|
|
5343
|
+
* Make what the user typed durable WITHOUT ending the edit: dirty drafts are
|
|
5344
|
+
* written and become the session baseline, then all queued writes settle.
|
|
5345
|
+
* Every durable read (snapshot, row stream, export) calls this first, so a
|
|
5346
|
+
* save never misses the value still in the editor.
|
|
5347
|
+
*/
|
|
5348
|
+
async flushCellEdit() {
|
|
5349
|
+
const store = this.tableStore;
|
|
5350
|
+
const session = store?.getState().cellEdit;
|
|
5351
|
+
if (store && session) {
|
|
5352
|
+
const dirty = dirtyDraftColumns(session);
|
|
5353
|
+
if (dirty.length > 0) {
|
|
5354
|
+
store.setState(
|
|
5355
|
+
(prev) => prev.cellEdit && prev.cellEdit.rowId === session.rowId ? { ...prev, cellEdit: rebaseDraft(prev.cellEdit, dirty) } : prev
|
|
5356
|
+
);
|
|
5357
|
+
this.queueDraftWrites(session, dirty);
|
|
5358
|
+
}
|
|
5359
|
+
}
|
|
5360
|
+
await this.settleCellWrites();
|
|
5361
|
+
}
|
|
5362
|
+
/**
|
|
5363
|
+
* Focus / pointer moved outside the grid. Deferred commit ends the edit per
|
|
5364
|
+
* `stopEditingWhenCellsLoseFocus`; immediate commit has nothing pending and
|
|
5365
|
+
* keeps the editor (legacy table behaviour).
|
|
5366
|
+
*/
|
|
5367
|
+
async leaveGridFocus() {
|
|
5368
|
+
if (!this.getCellEdit()) return;
|
|
5369
|
+
if (this.cellEditOptions.commit !== "deferred") return;
|
|
5370
|
+
if (!this.cellEditOptions.stopEditingWhenCellsLoseFocus) return;
|
|
5371
|
+
await this.commitCellEdit();
|
|
5372
|
+
}
|
|
5373
|
+
/**
|
|
5374
|
+
* Before dispose / unmount: commit (or drop, when
|
|
5375
|
+
* `stopEditingWhenCellsLoseFocus` is false) the open edit and wait until
|
|
5376
|
+
* every queued write is durable.
|
|
5377
|
+
*/
|
|
5378
|
+
async settleEditsForTeardown() {
|
|
5379
|
+
if (this.getCellEdit()) {
|
|
5380
|
+
if (this.cellEditOptions.stopEditingWhenCellsLoseFocus) {
|
|
5381
|
+
await this.commitCellEdit();
|
|
5382
|
+
} else {
|
|
5383
|
+
this.cancelCellEdit();
|
|
5384
|
+
}
|
|
5385
|
+
}
|
|
5386
|
+
await this.settleCellWrites();
|
|
5159
5387
|
}
|
|
5160
5388
|
isEditingCell(rowId, columnId) {
|
|
5161
5389
|
return isEditingCell(this.getCellEdit(), rowId, columnId);
|
|
@@ -5246,39 +5474,12 @@ var TableEngine = class {
|
|
|
5246
5474
|
*/
|
|
5247
5475
|
async commitCellEdit() {
|
|
5248
5476
|
const store = this.tableStore;
|
|
5249
|
-
|
|
5250
|
-
const tableKey = this.tableKey;
|
|
5251
|
-
if (!store || !commandStore || !tableKey) return 0;
|
|
5477
|
+
if (!store || !this.commandStore || !this.tableKey) return 0;
|
|
5252
5478
|
const session = store.getState().cellEdit;
|
|
5253
5479
|
if (!session) return 0;
|
|
5254
|
-
const dirty = dirtyDraftColumns(session);
|
|
5255
5480
|
store.setState((prev) => ({ ...prev, cellEdit: null }));
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
const draft = session.drafts[colId];
|
|
5259
|
-
const base = session.baseline[colId];
|
|
5260
|
-
if (!base || draft.value !== base.value) {
|
|
5261
|
-
await this.dispatch({
|
|
5262
|
-
type: "CHANGE_CELL_VALUE",
|
|
5263
|
-
store: commandStore,
|
|
5264
|
-
tableKey,
|
|
5265
|
-
rowId: session.rowId,
|
|
5266
|
-
columnId: colId,
|
|
5267
|
-
newValue: draft.value
|
|
5268
|
-
});
|
|
5269
|
-
writes += 1;
|
|
5270
|
-
}
|
|
5271
|
-
if (!base || draft.display !== base.display) {
|
|
5272
|
-
await this.dispatch({
|
|
5273
|
-
type: "CHANGE_CELL_DISPLAY_VALUE",
|
|
5274
|
-
store: commandStore,
|
|
5275
|
-
tableKey,
|
|
5276
|
-
rowId: session.rowId,
|
|
5277
|
-
columnId: colId,
|
|
5278
|
-
newValue: draft.display == null ? "" : String(draft.display)
|
|
5279
|
-
});
|
|
5280
|
-
}
|
|
5281
|
-
}
|
|
5481
|
+
const writes = this.queueDraftWrites(session, dirtyDraftColumns(session));
|
|
5482
|
+
await this.settleCellWrites();
|
|
5282
5483
|
return writes;
|
|
5283
5484
|
}
|
|
5284
5485
|
async transitionActiveCell(rowId, columnId) {
|
|
@@ -5467,16 +5668,15 @@ var TableEngine = class {
|
|
|
5467
5668
|
if (syncError) return syncError;
|
|
5468
5669
|
return this.applyAsyncValidators(value, schema, caption, rowId);
|
|
5469
5670
|
}
|
|
5470
|
-
finishValidation(cb, tableStore) {
|
|
5671
|
+
finishValidation(cb, tableStore, errorsChanged) {
|
|
5471
5672
|
cb({
|
|
5472
5673
|
valid: this.errors.size === 0,
|
|
5473
5674
|
errors: this.errors,
|
|
5474
5675
|
data: this.getAllRows()
|
|
5475
5676
|
});
|
|
5476
|
-
tableStore.setState(
|
|
5477
|
-
...prev,
|
|
5478
|
-
|
|
5479
|
-
}));
|
|
5677
|
+
tableStore.setState(
|
|
5678
|
+
(prev) => !errorsChanged && Object.keys(prev.expandedRows ?? {}).length === 0 ? prev : { ...prev, expandedRows: {} }
|
|
5679
|
+
);
|
|
5480
5680
|
}
|
|
5481
5681
|
collectValidationJobs(table) {
|
|
5482
5682
|
const jobs = [];
|
|
@@ -5495,11 +5695,23 @@ var TableEngine = class {
|
|
|
5495
5695
|
});
|
|
5496
5696
|
return jobs;
|
|
5497
5697
|
}
|
|
5698
|
+
/** Replaces the error map; true when the set of errors / messages changed. */
|
|
5498
5699
|
applyValidationErrors(nextErrors) {
|
|
5700
|
+
let changed = nextErrors.size !== this.errors.size;
|
|
5701
|
+
if (!changed) {
|
|
5702
|
+
for (const [cellId, error] of nextErrors) {
|
|
5703
|
+
const prev = this.errors.get(cellId);
|
|
5704
|
+
if (!prev || prev.message !== error.message || prev.rowId !== error.rowId) {
|
|
5705
|
+
changed = true;
|
|
5706
|
+
break;
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5499
5710
|
this.errors.clear();
|
|
5500
5711
|
nextErrors.forEach((error, cellId) => {
|
|
5501
5712
|
this.errors.set(cellId, error);
|
|
5502
5713
|
});
|
|
5714
|
+
return changed;
|
|
5503
5715
|
}
|
|
5504
5716
|
runValidationSync(table, cb, tableStore) {
|
|
5505
5717
|
const nextErrors = /* @__PURE__ */ new Map();
|
|
@@ -5512,8 +5724,8 @@ var TableEngine = class {
|
|
|
5512
5724
|
);
|
|
5513
5725
|
if (error) nextErrors.set(job.cellId, error);
|
|
5514
5726
|
}
|
|
5515
|
-
this.applyValidationErrors(nextErrors);
|
|
5516
|
-
this.finishValidation(cb, tableStore);
|
|
5727
|
+
const changed = this.applyValidationErrors(nextErrors);
|
|
5728
|
+
this.finishValidation(cb, tableStore, changed);
|
|
5517
5729
|
}
|
|
5518
5730
|
async runValidationAsync(table, cb, tableStore) {
|
|
5519
5731
|
const nextErrors = /* @__PURE__ */ new Map();
|
|
@@ -5526,8 +5738,8 @@ var TableEngine = class {
|
|
|
5526
5738
|
);
|
|
5527
5739
|
if (error) nextErrors.set(job.cellId, error);
|
|
5528
5740
|
}
|
|
5529
|
-
this.applyValidationErrors(nextErrors);
|
|
5530
|
-
this.finishValidation(cb, tableStore);
|
|
5741
|
+
const changed = this.applyValidationErrors(nextErrors);
|
|
5742
|
+
this.finishValidation(cb, tableStore, changed);
|
|
5531
5743
|
}
|
|
5532
5744
|
scheduleAsyncCellCheck(cellId, valueKey, value, schema, caption, rowId) {
|
|
5533
5745
|
const seq = (this.asyncCellSeq.get(cellId) ?? 0) + 1;
|
|
@@ -5872,6 +6084,9 @@ async function openIndexedDbDatabase(dbName, storeNames, version = 1) {
|
|
|
5872
6084
|
request.onsuccess = () => resolve(request.result);
|
|
5873
6085
|
});
|
|
5874
6086
|
return {
|
|
6087
|
+
close() {
|
|
6088
|
+
db.close();
|
|
6089
|
+
},
|
|
5875
6090
|
objectStore(name) {
|
|
5876
6091
|
return {
|
|
5877
6092
|
async get(key) {
|
|
@@ -5923,6 +6138,8 @@ var IndexedDbEventStore = class _IndexedDbEventStore {
|
|
|
5923
6138
|
this.db = db;
|
|
5924
6139
|
this.listeners = /* @__PURE__ */ new Map();
|
|
5925
6140
|
this.globalListeners = /* @__PURE__ */ new Set();
|
|
6141
|
+
this.closed = false;
|
|
6142
|
+
this.inflight = /* @__PURE__ */ new Set();
|
|
5926
6143
|
this.ready = Promise.resolve();
|
|
5927
6144
|
}
|
|
5928
6145
|
static async open(dbName = DEFAULT_EVENT_STORE_PREFIX) {
|
|
@@ -5933,7 +6150,36 @@ var IndexedDbEventStore = class _IndexedDbEventStore {
|
|
|
5933
6150
|
static inMemory() {
|
|
5934
6151
|
return new _IndexedDbEventStore(new MemoryKvDatabase());
|
|
5935
6152
|
}
|
|
5936
|
-
|
|
6153
|
+
/**
|
|
6154
|
+
* Release the IndexedDB connection (stored events are untouched). Waits for
|
|
6155
|
+
* appends already in flight; appends started afterwards are dropped (they
|
|
6156
|
+
* resolve `ok` without writing) because the owning grid is gone. Idempotent.
|
|
6157
|
+
*/
|
|
6158
|
+
close() {
|
|
6159
|
+
if (!this.closePromise) {
|
|
6160
|
+
this.closed = true;
|
|
6161
|
+
this.closePromise = (async () => {
|
|
6162
|
+
await Promise.allSettled([...this.inflight]);
|
|
6163
|
+
this.listeners.clear();
|
|
6164
|
+
this.globalListeners.clear();
|
|
6165
|
+
this.db.close?.();
|
|
6166
|
+
})();
|
|
6167
|
+
}
|
|
6168
|
+
return this.closePromise;
|
|
6169
|
+
}
|
|
6170
|
+
append(streamId, events, expectedVersion) {
|
|
6171
|
+
if (this.closed) {
|
|
6172
|
+
return Promise.resolve({ ok: true, version: 0 });
|
|
6173
|
+
}
|
|
6174
|
+
const job = this.appendInternal(streamId, events, expectedVersion);
|
|
6175
|
+
this.inflight.add(job);
|
|
6176
|
+
const forget = () => {
|
|
6177
|
+
this.inflight.delete(job);
|
|
6178
|
+
};
|
|
6179
|
+
job.then(forget, forget);
|
|
6180
|
+
return job;
|
|
6181
|
+
}
|
|
6182
|
+
async appendInternal(streamId, events, expectedVersion) {
|
|
5937
6183
|
await this.ready;
|
|
5938
6184
|
const streamStore = this.db.objectStore(STREAMS);
|
|
5939
6185
|
const globalStore = this.db.objectStore(GLOBAL);
|
|
@@ -5973,11 +6219,13 @@ var IndexedDbEventStore = class _IndexedDbEventStore {
|
|
|
5973
6219
|
return { ok: true, version: record.events.length };
|
|
5974
6220
|
}
|
|
5975
6221
|
async read(streamId, fromVersion = 0) {
|
|
6222
|
+
if (this.closed) return [];
|
|
5976
6223
|
await this.ready;
|
|
5977
6224
|
const record = await this.db.objectStore(STREAMS).get(streamId);
|
|
5978
6225
|
return (record?.events ?? []).slice(fromVersion);
|
|
5979
6226
|
}
|
|
5980
6227
|
async readAll(fromPosition = 0) {
|
|
6228
|
+
if (this.closed) return [];
|
|
5981
6229
|
await this.ready;
|
|
5982
6230
|
const globalStore = this.db.objectStore(GLOBAL);
|
|
5983
6231
|
const keys = (await globalStore.getAllKeys()).map(Number).filter((n) => Number.isFinite(n)).sort((a, b) => a - b).filter((n) => n > fromPosition);
|
|
@@ -5989,6 +6237,7 @@ var IndexedDbEventStore = class _IndexedDbEventStore {
|
|
|
5989
6237
|
return events;
|
|
5990
6238
|
}
|
|
5991
6239
|
subscribe(streamId, onEvent) {
|
|
6240
|
+
if (this.closed) return () => void 0;
|
|
5992
6241
|
if (!this.listeners.has(streamId)) {
|
|
5993
6242
|
this.listeners.set(streamId, /* @__PURE__ */ new Set());
|
|
5994
6243
|
}
|
|
@@ -5999,6 +6248,7 @@ var IndexedDbEventStore = class _IndexedDbEventStore {
|
|
|
5999
6248
|
};
|
|
6000
6249
|
}
|
|
6001
6250
|
subscribeAll(onEvent) {
|
|
6251
|
+
if (this.closed) return () => void 0;
|
|
6002
6252
|
this.globalListeners.add(onEvent);
|
|
6003
6253
|
return () => {
|
|
6004
6254
|
this.globalListeners.delete(onEvent);
|
|
@@ -6047,6 +6297,8 @@ var OfflineStatus = class {
|
|
|
6047
6297
|
this.syncedIds = /* @__PURE__ */ new Set();
|
|
6048
6298
|
this.connectivityUnsub = null;
|
|
6049
6299
|
this.storeUnsub = null;
|
|
6300
|
+
/** Incremented by every stop(); invalidates an in-flight start(). */
|
|
6301
|
+
this.lifecycle = 0;
|
|
6050
6302
|
this.connectivityListeners = /* @__PURE__ */ new Set();
|
|
6051
6303
|
this.pendingListeners = /* @__PURE__ */ new Set();
|
|
6052
6304
|
this.online = options.connectivity.getOnline();
|
|
@@ -6054,11 +6306,14 @@ var OfflineStatus = class {
|
|
|
6054
6306
|
}
|
|
6055
6307
|
async start(eventStore) {
|
|
6056
6308
|
this.stop();
|
|
6309
|
+
const run2 = this.lifecycle;
|
|
6057
6310
|
this.connectivityUnsub = this.options.connectivity.subscribe((online) => {
|
|
6311
|
+
if (run2 !== this.lifecycle) return;
|
|
6058
6312
|
this.online = online;
|
|
6059
6313
|
this.emitConnectivity();
|
|
6060
6314
|
});
|
|
6061
6315
|
const past = await eventStore.readAll(0);
|
|
6316
|
+
if (run2 !== this.lifecycle) return;
|
|
6062
6317
|
for (const event of past) {
|
|
6063
6318
|
this.consider(event);
|
|
6064
6319
|
}
|
|
@@ -6067,7 +6322,14 @@ var OfflineStatus = class {
|
|
|
6067
6322
|
});
|
|
6068
6323
|
this.emitPending();
|
|
6069
6324
|
}
|
|
6325
|
+
/** Stop listening and drop all listeners. The instance is inert afterwards. */
|
|
6326
|
+
dispose() {
|
|
6327
|
+
this.stop();
|
|
6328
|
+
this.connectivityListeners.clear();
|
|
6329
|
+
this.pendingListeners.clear();
|
|
6330
|
+
}
|
|
6070
6331
|
stop() {
|
|
6332
|
+
this.lifecycle += 1;
|
|
6071
6333
|
this.connectivityUnsub?.();
|
|
6072
6334
|
this.connectivityUnsub = null;
|
|
6073
6335
|
this.storeUnsub?.();
|
|
@@ -6574,18 +6836,40 @@ var UITableController = class {
|
|
|
6574
6836
|
return this.syncPort;
|
|
6575
6837
|
}
|
|
6576
6838
|
setSyncPort(port) {
|
|
6839
|
+
if (this.releasePromise) {
|
|
6840
|
+
port?.dispose?.();
|
|
6841
|
+
return;
|
|
6842
|
+
}
|
|
6577
6843
|
this.syncPort = port;
|
|
6578
6844
|
}
|
|
6579
6845
|
getPresencePort() {
|
|
6580
6846
|
return this.presencePort;
|
|
6581
6847
|
}
|
|
6582
6848
|
setPresencePort(port) {
|
|
6849
|
+
if (this.releasePromise) {
|
|
6850
|
+
port?.dispose();
|
|
6851
|
+
return;
|
|
6852
|
+
}
|
|
6583
6853
|
this.presencePort = port;
|
|
6584
6854
|
}
|
|
6855
|
+
/**
|
|
6856
|
+
* Composition root hook: the callback that releases every resource the grid
|
|
6857
|
+
* created (subscriptions, projections, plugins, owned event store).
|
|
6858
|
+
* Run once by {@link releaseResources}.
|
|
6859
|
+
*/
|
|
6860
|
+
setResourceTeardown(teardown) {
|
|
6861
|
+
this.resourceTeardown = teardown;
|
|
6862
|
+
}
|
|
6863
|
+
/** True once resources were released (via releaseResources or dispose). */
|
|
6864
|
+
isReleased() {
|
|
6865
|
+
return this.releasePromise !== void 0;
|
|
6866
|
+
}
|
|
6585
6867
|
getPresencePeers() {
|
|
6586
6868
|
return this.presencePort?.getPeers() ?? [];
|
|
6587
6869
|
}
|
|
6588
6870
|
subscribePresencePeers(cb) {
|
|
6871
|
+
if (this.isReleased()) return () => {
|
|
6872
|
+
};
|
|
6589
6873
|
if (!this.presencePort) {
|
|
6590
6874
|
cb([]);
|
|
6591
6875
|
return () => {
|
|
@@ -6610,6 +6894,8 @@ var UITableController = class {
|
|
|
6610
6894
|
this.offlineStatus?.markSynced(eventIds);
|
|
6611
6895
|
}
|
|
6612
6896
|
subscribeConnectivity(cb) {
|
|
6897
|
+
if (this.isReleased()) return () => {
|
|
6898
|
+
};
|
|
6613
6899
|
if (!this.offlineStatus) {
|
|
6614
6900
|
cb("online");
|
|
6615
6901
|
return () => {
|
|
@@ -6618,6 +6904,8 @@ var UITableController = class {
|
|
|
6618
6904
|
return this.offlineStatus.subscribeConnectivity(cb);
|
|
6619
6905
|
}
|
|
6620
6906
|
subscribePendingChanges(cb) {
|
|
6907
|
+
if (this.isReleased()) return () => {
|
|
6908
|
+
};
|
|
6621
6909
|
if (!this.offlineStatus) {
|
|
6622
6910
|
cb([]);
|
|
6623
6911
|
return () => {
|
|
@@ -6635,6 +6923,8 @@ var UITableController = class {
|
|
|
6635
6923
|
return this.syncPort?.getOpenConflicts() ?? [];
|
|
6636
6924
|
}
|
|
6637
6925
|
subscribeSyncConflicts(cb) {
|
|
6926
|
+
if (this.isReleased()) return () => {
|
|
6927
|
+
};
|
|
6638
6928
|
if (!this.syncPort) {
|
|
6639
6929
|
cb([]);
|
|
6640
6930
|
return () => {
|
|
@@ -6643,10 +6933,11 @@ var UITableController = class {
|
|
|
6643
6933
|
return this.syncPort.subscribeConflicts(cb);
|
|
6644
6934
|
}
|
|
6645
6935
|
async syncNow() {
|
|
6646
|
-
if (!this.syncPort) return null;
|
|
6936
|
+
if (this.isReleased() || !this.syncPort) return null;
|
|
6647
6937
|
return this.syncPort.sync();
|
|
6648
6938
|
}
|
|
6649
6939
|
async resolveSyncConflict(conflictId, choice) {
|
|
6940
|
+
if (this.isReleased()) return;
|
|
6650
6941
|
await this.syncPort?.resolveConflict(conflictId, choice);
|
|
6651
6942
|
}
|
|
6652
6943
|
/** Apply a remote cell value (used by SyncPort; dual-writes via engine). */
|
|
@@ -6695,24 +6986,17 @@ var UITableController = class {
|
|
|
6695
6986
|
changePage(page) {
|
|
6696
6987
|
this.engine.dispatch({ type: "CHANGE_PAGE", store: this.store, tableKey: this.tableKey, page });
|
|
6697
6988
|
}
|
|
6989
|
+
/** Editor of this cell → session draft (written per `cellEditCommit`); otherwise write-through. */
|
|
6698
6990
|
onCellChange(rowId, columnId, value) {
|
|
6699
|
-
|
|
6700
|
-
this.engine.patchCellEdit(rowId, columnId, { value });
|
|
6701
|
-
return;
|
|
6702
|
-
}
|
|
6703
|
-
this.engine.dispatch({ type: "CHANGE_CELL_VALUE", store: this.store, tableKey: this.tableKey, rowId, columnId, newValue: value });
|
|
6991
|
+
return this.engine.inputCellValue(rowId, columnId, value);
|
|
6704
6992
|
}
|
|
6705
6993
|
onDescriptionSave(rowId, flag) {
|
|
6706
6994
|
this.engine.dispatch({ type: "SAVE_DESCRIPTION", store: this.store, tableKey: this.tableKey, rowId, flag });
|
|
6707
6995
|
}
|
|
6708
6996
|
onCellDisplayChange(rowId, columnId, value) {
|
|
6709
|
-
|
|
6710
|
-
this.engine.patchCellEdit(rowId, columnId, { display: value });
|
|
6711
|
-
return;
|
|
6712
|
-
}
|
|
6713
|
-
this.engine.dispatch({ type: "CHANGE_CELL_DISPLAY_VALUE", store: this.store, tableKey: this.tableKey, rowId, columnId, newValue: value });
|
|
6997
|
+
return this.engine.inputCellDisplay(rowId, columnId, value);
|
|
6714
6998
|
}
|
|
6715
|
-
setActiveCell(rowId, columnId) {
|
|
6999
|
+
async setActiveCell(rowId, columnId) {
|
|
6716
7000
|
const prev = this.engine.getActiveCell();
|
|
6717
7001
|
if (prev?.rowId === rowId && prev?.columnId === columnId) {
|
|
6718
7002
|
if (this.engine.getCellEditOptions().singleClickEdit && !this.engine.getCellEdit()) {
|
|
@@ -6729,14 +7013,14 @@ var UITableController = class {
|
|
|
6729
7013
|
rowId
|
|
6730
7014
|
});
|
|
6731
7015
|
}
|
|
6732
|
-
this.engine.dispatch({ type: "ACTIVE_CELL", tableKey: this.tableKey, rowId, columnId });
|
|
6733
7016
|
this.publishPresenceCell(rowId, columnId);
|
|
7017
|
+
await this.engine.dispatch({ type: "ACTIVE_CELL", tableKey: this.tableKey, rowId, columnId });
|
|
6734
7018
|
}
|
|
6735
7019
|
setActiveRow(rowId) {
|
|
6736
7020
|
this.engine.dispatch({ type: "ACTIVE_ROW", store: this.store, tableKey: this.tableKey, rowId });
|
|
6737
7021
|
}
|
|
6738
7022
|
moveActiveCellVertical(rowId, columnId, direction) {
|
|
6739
|
-
this.engine.dispatch({ type: "MOVE_ACTIVE_CELL_VERTICAL", store: this.store, tableKey: this.tableKey, rowId, columnId, direction });
|
|
7023
|
+
return this.engine.dispatch({ type: "MOVE_ACTIVE_CELL_VERTICAL", store: this.store, tableKey: this.tableKey, rowId, columnId, direction });
|
|
6740
7024
|
}
|
|
6741
7025
|
reorderRow(draggedRowId, droppedRowId, position) {
|
|
6742
7026
|
this.engine.dispatch({ type: "ROW_REORDERED", store: this.store, tableKey: this.tableKey, draggedRowId, droppedRowId, position });
|
|
@@ -6812,7 +7096,7 @@ var UITableController = class {
|
|
|
6812
7096
|
this.engine.dispatch({ type: "ACTIVATE_FIRST_CELL", tableKey: this.tableKey, rowId });
|
|
6813
7097
|
}
|
|
6814
7098
|
moveToNextCell(rowId, columnId, direction = "next") {
|
|
6815
|
-
this.engine.dispatch({ type: "MOVE_ACTIVE_CELL", store: this.store, tableKey: this.tableKey, rowId, columnId, direction });
|
|
7099
|
+
return this.engine.dispatch({ type: "MOVE_ACTIVE_CELL", store: this.store, tableKey: this.tableKey, rowId, columnId, direction });
|
|
6816
7100
|
}
|
|
6817
7101
|
async setTableAction(action) {
|
|
6818
7102
|
await this.engine.dispatch({ type: "SET_TABLE_ACTION", store: this.store, tableKey: this.tableKey, action });
|
|
@@ -7080,7 +7364,7 @@ var UITableController = class {
|
|
|
7080
7364
|
) ?? 0;
|
|
7081
7365
|
}
|
|
7082
7366
|
subscribeChangelog(cb, filter = {}) {
|
|
7083
|
-
if (!this.changelogProjection) return () => {
|
|
7367
|
+
if (!this.changelogProjection || this.isReleased()) return () => {
|
|
7084
7368
|
};
|
|
7085
7369
|
return this.safe(
|
|
7086
7370
|
() => this.changelogProjection.subscribe(cb, { tableId: this.tableKey, ...filter }),
|
|
@@ -7103,7 +7387,7 @@ var UITableController = class {
|
|
|
7103
7387
|
) ?? 0;
|
|
7104
7388
|
}
|
|
7105
7389
|
subscribeHistoryItems(cb, filter = {}) {
|
|
7106
|
-
if (!this.historyPanelViewModel) return () => {
|
|
7390
|
+
if (!this.historyPanelViewModel || this.isReleased()) return () => {
|
|
7107
7391
|
};
|
|
7108
7392
|
return this.safe(
|
|
7109
7393
|
() => this.historyPanelViewModel.subscribe(cb, { tableId: this.tableKey, ...filter }),
|
|
@@ -7176,6 +7460,40 @@ var UITableController = class {
|
|
|
7176
7460
|
commitCellEdit() {
|
|
7177
7461
|
return this.safe(() => this.engine.commitCellEdit(), "commitCellEdit") ?? Promise.resolve(0);
|
|
7178
7462
|
}
|
|
7463
|
+
/**
|
|
7464
|
+
* Write what is still in the cell editor (the edit stays open) and wait
|
|
7465
|
+
* until every pending cell write is durable. `getFullSnapShot` /
|
|
7466
|
+
* `iterateRowsFromDb` / exports already do this; call it before reading
|
|
7467
|
+
* synchronous APIs (`getRowView`, `getSnapShot`) for a save.
|
|
7468
|
+
*/
|
|
7469
|
+
flushCellEdit() {
|
|
7470
|
+
return this.engine.flushCellEdit().catch((error) => {
|
|
7471
|
+
this.audit.log({
|
|
7472
|
+
type: "ERROR",
|
|
7473
|
+
message: "UITableController.flushCellEdit failed",
|
|
7474
|
+
payload: { error, tableKey: this.tableKey }
|
|
7475
|
+
});
|
|
7476
|
+
});
|
|
7477
|
+
}
|
|
7478
|
+
/** DataGrid: focus / pointer left the grid (see `stopEditingWhenCellsLoseFocus`). */
|
|
7479
|
+
leaveGridFocus() {
|
|
7480
|
+
return this.engine.leaveGridFocus().catch((error) => {
|
|
7481
|
+
this.audit.log({
|
|
7482
|
+
type: "ERROR",
|
|
7483
|
+
message: "UITableController.leaveGridFocus failed",
|
|
7484
|
+
payload: { error, tableKey: this.tableKey }
|
|
7485
|
+
});
|
|
7486
|
+
});
|
|
7487
|
+
}
|
|
7488
|
+
settleEditsForTeardown() {
|
|
7489
|
+
return this.engine.settleEditsForTeardown().catch((error) => {
|
|
7490
|
+
this.audit.log({
|
|
7491
|
+
type: "ERROR",
|
|
7492
|
+
message: "UITableController: committing the open edit before teardown failed",
|
|
7493
|
+
payload: { error, tableKey: this.tableKey }
|
|
7494
|
+
});
|
|
7495
|
+
});
|
|
7496
|
+
}
|
|
7179
7497
|
getEditDraft(rowId, columnId) {
|
|
7180
7498
|
return this.safe(
|
|
7181
7499
|
() => this.engine.getEditDraft(rowId, columnId),
|
|
@@ -7296,12 +7614,68 @@ var UITableController = class {
|
|
|
7296
7614
|
this.engine.addCellRange(range);
|
|
7297
7615
|
}
|
|
7298
7616
|
// ─── lifecycle ───────────────────────────────────────────────────────
|
|
7617
|
+
/**
|
|
7618
|
+
* Full dispose: `TABLE_DISPOSED` (windowed repo: drop the RAM page window,
|
|
7619
|
+
* other repos: `repo.delete` — unchanged data semantics) followed by
|
|
7620
|
+
* {@link releaseResources}. Idempotent; the promise settles once teardown
|
|
7621
|
+
* finished and never rejects.
|
|
7622
|
+
*/
|
|
7299
7623
|
dispose() {
|
|
7300
|
-
if (this.disposed) return;
|
|
7624
|
+
if (this.disposed) return this.releasePromise ?? this.releaseResources();
|
|
7301
7625
|
this.disposed = true;
|
|
7302
7626
|
this.presencePort?.dispose();
|
|
7303
7627
|
this.presencePort = void 0;
|
|
7304
|
-
|
|
7628
|
+
const dispatched = this.settleEditsForTeardown().then(
|
|
7629
|
+
() => this.engine.dispatch({ type: "TABLE_DISPOSED", store: this.store, tableKey: this.tableKey })
|
|
7630
|
+
).catch((error) => {
|
|
7631
|
+
this.audit.log({
|
|
7632
|
+
type: "ERROR",
|
|
7633
|
+
message: "UITableController.dispose: TABLE_DISPOSED failed",
|
|
7634
|
+
payload: { error, tableKey: this.tableKey }
|
|
7635
|
+
});
|
|
7636
|
+
});
|
|
7637
|
+
return dispatched.then(() => this.releaseResources());
|
|
7638
|
+
}
|
|
7639
|
+
/**
|
|
7640
|
+
* Resource-only teardown: stops subscriptions, projections, sync, presence,
|
|
7641
|
+
* plugins, server row model and closes an event store the grid opened.
|
|
7642
|
+
* Does NOT dispatch `TABLE_DISPOSED` — persisted table data is untouched.
|
|
7643
|
+
* Idempotent (same promise on every call); never rejects.
|
|
7644
|
+
*/
|
|
7645
|
+
releaseResources() {
|
|
7646
|
+
if (!this.releasePromise) {
|
|
7647
|
+
this.releasePromise = this.runResourceTeardown();
|
|
7648
|
+
}
|
|
7649
|
+
return this.releasePromise;
|
|
7650
|
+
}
|
|
7651
|
+
async runResourceTeardown() {
|
|
7652
|
+
const fail = (what, error) => {
|
|
7653
|
+
this.audit.log({
|
|
7654
|
+
type: "ERROR",
|
|
7655
|
+
message: `UITableController.releaseResources: ${what} failed`,
|
|
7656
|
+
payload: { error, tableKey: this.tableKey }
|
|
7657
|
+
});
|
|
7658
|
+
};
|
|
7659
|
+
await this.settleEditsForTeardown();
|
|
7660
|
+
const presence = this.presencePort;
|
|
7661
|
+
const sync = this.syncPort;
|
|
7662
|
+
this.presencePort = void 0;
|
|
7663
|
+
this.syncPort = void 0;
|
|
7664
|
+
try {
|
|
7665
|
+
presence?.dispose();
|
|
7666
|
+
} catch (error) {
|
|
7667
|
+
fail("presence dispose", error);
|
|
7668
|
+
}
|
|
7669
|
+
try {
|
|
7670
|
+
sync?.dispose?.();
|
|
7671
|
+
} catch (error) {
|
|
7672
|
+
fail("sync dispose", error);
|
|
7673
|
+
}
|
|
7674
|
+
try {
|
|
7675
|
+
await this.resourceTeardown?.();
|
|
7676
|
+
} catch (error) {
|
|
7677
|
+
fail("teardown", error);
|
|
7678
|
+
}
|
|
7305
7679
|
}
|
|
7306
7680
|
// ─── main dispatch ───────────────────────────────────────────────────
|
|
7307
7681
|
async dispatch(command) {
|
|
@@ -7325,13 +7699,13 @@ var UITableController = class {
|
|
|
7325
7699
|
this.changePage(command.page);
|
|
7326
7700
|
return;
|
|
7327
7701
|
case "UI_CELL_CHANGE":
|
|
7328
|
-
this.onCellChange(command.rowId, command.columnId, command.value);
|
|
7702
|
+
await this.onCellChange(command.rowId, command.columnId, command.value);
|
|
7329
7703
|
return;
|
|
7330
7704
|
case "UI_DESCRIPTION_SAVE":
|
|
7331
7705
|
this.onDescriptionSave(command.rowId, command.flag);
|
|
7332
7706
|
return;
|
|
7333
7707
|
case "UI_CELL_CHANGE_DISPLAY":
|
|
7334
|
-
this.onCellDisplayChange(command.rowId, command.columnId, command.value);
|
|
7708
|
+
await this.onCellDisplayChange(command.rowId, command.columnId, command.value);
|
|
7335
7709
|
return;
|
|
7336
7710
|
case "ADD_EMPTY_ROW":
|
|
7337
7711
|
await this.addEmptyRow();
|
|
@@ -7371,13 +7745,13 @@ var UITableController = class {
|
|
|
7371
7745
|
shiftKey: Boolean(command.shiftKey),
|
|
7372
7746
|
ctrlKey: Boolean(command.ctrlKey)
|
|
7373
7747
|
});
|
|
7374
|
-
this.setActiveCell(command.rowId, command.columnId);
|
|
7748
|
+
await this.setActiveCell(command.rowId, command.columnId);
|
|
7375
7749
|
return;
|
|
7376
7750
|
case "UI_MOVE_ACTIVE_CELL":
|
|
7377
|
-
this.moveToNextCell(command.rowId, command.columnId, command.direction);
|
|
7751
|
+
await this.moveToNextCell(command.rowId, command.columnId, command.direction);
|
|
7378
7752
|
return;
|
|
7379
7753
|
case "UI_MOVE_ACTIVE_CELL_VERTICAL":
|
|
7380
|
-
this.moveActiveCellVertical(command.rowId, command.columnId, command.direction);
|
|
7754
|
+
await this.moveActiveCellVertical(command.rowId, command.columnId, command.direction);
|
|
7381
7755
|
return;
|
|
7382
7756
|
case "UI_ACTIVE_ROW":
|
|
7383
7757
|
this.setActiveRow(command.rowId);
|
|
@@ -7592,6 +7966,7 @@ var PluginHost = class {
|
|
|
7592
7966
|
return this.plugins.some((p) => p.name === pluginName);
|
|
7593
7967
|
}
|
|
7594
7968
|
async requestExport(options) {
|
|
7969
|
+
await this.deps.beforeRead?.();
|
|
7595
7970
|
const bus = this.createBus();
|
|
7596
7971
|
const correlationId = options.correlationId ?? createEventId();
|
|
7597
7972
|
const pluginName = options.format === "pdf" ? "pdf-export" : options.format === "csv" ? "csv-export" : "excel-export";
|
|
@@ -8077,6 +8452,40 @@ var ConsoleAuditLogger = class {
|
|
|
8077
8452
|
}
|
|
8078
8453
|
};
|
|
8079
8454
|
|
|
8455
|
+
// infrastructure/eventStore/trackedEventStore.ts
|
|
8456
|
+
function trackEventStoreSubscriptions(inner) {
|
|
8457
|
+
const open = /* @__PURE__ */ new Set();
|
|
8458
|
+
let released = false;
|
|
8459
|
+
const track = (subscribe) => {
|
|
8460
|
+
if (released) return () => void 0;
|
|
8461
|
+
const raw = subscribe();
|
|
8462
|
+
let done = false;
|
|
8463
|
+
const unsub = () => {
|
|
8464
|
+
if (done) return;
|
|
8465
|
+
done = true;
|
|
8466
|
+
open.delete(unsub);
|
|
8467
|
+
raw();
|
|
8468
|
+
};
|
|
8469
|
+
open.add(unsub);
|
|
8470
|
+
return unsub;
|
|
8471
|
+
};
|
|
8472
|
+
const store = {
|
|
8473
|
+
append: (streamId, events, expectedVersion) => inner.append(streamId, events, expectedVersion),
|
|
8474
|
+
read: (streamId, fromVersion) => inner.read(streamId, fromVersion),
|
|
8475
|
+
readAll: (fromPosition) => inner.readAll(fromPosition),
|
|
8476
|
+
subscribe: (streamId, onEvent) => track(() => inner.subscribe(streamId, onEvent)),
|
|
8477
|
+
subscribeAll: (onEvent) => track(() => inner.subscribeAll(onEvent))
|
|
8478
|
+
};
|
|
8479
|
+
return {
|
|
8480
|
+
store,
|
|
8481
|
+
release() {
|
|
8482
|
+
released = true;
|
|
8483
|
+
for (const unsub of [...open]) unsub();
|
|
8484
|
+
open.clear();
|
|
8485
|
+
}
|
|
8486
|
+
};
|
|
8487
|
+
}
|
|
8488
|
+
|
|
8080
8489
|
// infrastructure/history/HistoryPanelViewModel.ts
|
|
8081
8490
|
var HISTORY_CLASSIFICATIONS = {
|
|
8082
8491
|
CELL_CHANGED: { category: "data", severity: "info" },
|
|
@@ -8288,6 +8697,8 @@ var ChangelogProjection = class {
|
|
|
8288
8697
|
this.subscribers = /* @__PURE__ */ new Set();
|
|
8289
8698
|
this.seenEventIds = /* @__PURE__ */ new Set();
|
|
8290
8699
|
this.started = false;
|
|
8700
|
+
/** Incremented by start() and stop(); invalidates an in-flight catch-up. */
|
|
8701
|
+
this.run = 0;
|
|
8291
8702
|
}
|
|
8292
8703
|
/**
|
|
8293
8704
|
* Catch up via readAll, then subscribe for live events.
|
|
@@ -8301,17 +8712,25 @@ var ChangelogProjection = class {
|
|
|
8301
8712
|
this.seenEventIds.add(event.eventId);
|
|
8302
8713
|
this.project(event);
|
|
8303
8714
|
};
|
|
8715
|
+
const run2 = ++this.run;
|
|
8304
8716
|
this.unsubscribe = this.eventStore.subscribeAll(projectOnce);
|
|
8305
8717
|
const past = await this.eventStore.readAll(0);
|
|
8718
|
+
if (run2 !== this.run) return;
|
|
8306
8719
|
for (const event of past) {
|
|
8307
8720
|
projectOnce(event);
|
|
8308
8721
|
}
|
|
8309
8722
|
}
|
|
8310
8723
|
stop() {
|
|
8724
|
+
this.run += 1;
|
|
8311
8725
|
this.unsubscribe?.();
|
|
8312
8726
|
this.unsubscribe = null;
|
|
8313
8727
|
this.started = false;
|
|
8314
8728
|
}
|
|
8729
|
+
/** Stop and drop all subscribers (grid teardown). Entries stay readable. */
|
|
8730
|
+
dispose() {
|
|
8731
|
+
this.stop();
|
|
8732
|
+
this.subscribers.clear();
|
|
8733
|
+
}
|
|
8315
8734
|
query(filter = {}) {
|
|
8316
8735
|
let result = this.entries;
|
|
8317
8736
|
if (filter.tableId) {
|
|
@@ -8893,6 +9312,33 @@ function isCellEditorTarget(target) {
|
|
|
8893
9312
|
if (!editor) return false;
|
|
8894
9313
|
return Boolean(editor.closest('[role="gridcell"], [data-erp-cell-textarea]'));
|
|
8895
9314
|
}
|
|
9315
|
+
var CELL_SELECTOR = '[role="gridcell"], [data-erp-cell-textarea]';
|
|
9316
|
+
function isGridCellTarget(target) {
|
|
9317
|
+
if (!target || !(target instanceof Element)) return false;
|
|
9318
|
+
if (target.closest('[role="menu"], [role="dialog"], .erp-table-modal')) {
|
|
9319
|
+
return false;
|
|
9320
|
+
}
|
|
9321
|
+
return Boolean(target.closest(CELL_SELECTOR));
|
|
9322
|
+
}
|
|
9323
|
+
var TEXT_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
9324
|
+
"",
|
|
9325
|
+
"text",
|
|
9326
|
+
"search",
|
|
9327
|
+
"number",
|
|
9328
|
+
"tel",
|
|
9329
|
+
"url",
|
|
9330
|
+
"email",
|
|
9331
|
+
"password"
|
|
9332
|
+
]);
|
|
9333
|
+
function isTextEditorTarget(target) {
|
|
9334
|
+
if (!isCellEditorTarget(target)) return false;
|
|
9335
|
+
const el = target;
|
|
9336
|
+
if (el.isContentEditable || el.getAttribute("contenteditable") === "true") return true;
|
|
9337
|
+
const tag = el.tagName;
|
|
9338
|
+
if (tag === "TEXTAREA") return true;
|
|
9339
|
+
if (tag !== "INPUT") return false;
|
|
9340
|
+
return TEXT_INPUT_TYPES.has((el.getAttribute("type") ?? "").toLowerCase());
|
|
9341
|
+
}
|
|
8896
9342
|
function closestGridRoot(target) {
|
|
8897
9343
|
if (!target || !(target instanceof Element)) return null;
|
|
8898
9344
|
return target.closest('[role="grid"], [role="treegrid"]');
|
|
@@ -8947,6 +9393,13 @@ var UITableKeyboardHandler = class {
|
|
|
8947
9393
|
setPasteCells(handler) {
|
|
8948
9394
|
this.pasteCells = handler;
|
|
8949
9395
|
}
|
|
9396
|
+
/** More than one cell selected (Shift+Arrow / drag): clipboard keys act on the grid. */
|
|
9397
|
+
hasMultiCellRange() {
|
|
9398
|
+
const ranges = this.engine.getCellRanges();
|
|
9399
|
+
if (ranges.length > 1) return true;
|
|
9400
|
+
const range = ranges[0];
|
|
9401
|
+
return Boolean(range && (range.startRow !== range.endRow || range.colIds.length > 1));
|
|
9402
|
+
}
|
|
8950
9403
|
async handle(e, ctx2) {
|
|
8951
9404
|
try {
|
|
8952
9405
|
await this.handleInternal(e, ctx2);
|
|
@@ -8966,6 +9419,8 @@ var UITableKeyboardHandler = class {
|
|
|
8966
9419
|
const { activeColumnId } = ctx2;
|
|
8967
9420
|
const selectedRows = this.engine.getSelectedRows();
|
|
8968
9421
|
const activeRowId = ctx2.activeRowId ?? this.engine.getActiveRow() ?? (selectedRows ? Number(Object.keys(selectedRows).find((id) => selectedRows[Number(id)])) || null : null);
|
|
9422
|
+
const inTextEditor = isTextEditorTarget(e.target);
|
|
9423
|
+
const clipboardToEditor = inTextEditor && !this.hasMultiCellRange();
|
|
8969
9424
|
switch (code) {
|
|
8970
9425
|
case "KeyN": {
|
|
8971
9426
|
if (altKey) {
|
|
@@ -8997,7 +9452,7 @@ var UITableKeyboardHandler = class {
|
|
|
8997
9452
|
});
|
|
8998
9453
|
return;
|
|
8999
9454
|
}
|
|
9000
|
-
if (!ctrlKey && !shiftKey && !altKey && activeRowId && activeColumnId) {
|
|
9455
|
+
if (!ctrlKey && !shiftKey && !altKey && !inTextEditor && activeRowId && activeColumnId) {
|
|
9001
9456
|
e.preventDefault();
|
|
9002
9457
|
await this.dispatchIntent({
|
|
9003
9458
|
type: "JUMP_ACTIVE_CELL_ROW_EDGE",
|
|
@@ -9031,7 +9486,7 @@ var UITableKeyboardHandler = class {
|
|
|
9031
9486
|
});
|
|
9032
9487
|
return;
|
|
9033
9488
|
}
|
|
9034
|
-
if (!ctrlKey && !shiftKey && !altKey && activeRowId && activeColumnId) {
|
|
9489
|
+
if (!ctrlKey && !shiftKey && !altKey && !inTextEditor && activeRowId && activeColumnId) {
|
|
9035
9490
|
e.preventDefault();
|
|
9036
9491
|
await this.dispatchIntent({
|
|
9037
9492
|
type: "JUMP_ACTIVE_CELL_ROW_EDGE",
|
|
@@ -9059,28 +9514,28 @@ var UITableKeyboardHandler = class {
|
|
|
9059
9514
|
type: "ACTIVATE_FIRST_CELL",
|
|
9060
9515
|
rowId: activeRowId
|
|
9061
9516
|
});
|
|
9062
|
-
} else if (this.engine.getCellEdit()) {
|
|
9517
|
+
} else if (!this.engine.getCellEdit() && !this.engine.getCellEditOptions().singleClickEdit) {
|
|
9518
|
+
this.engine.startCellEdit(activeRowId, activeColumnId);
|
|
9519
|
+
} else if (this.engine.getCellEditOptions().enterNavigation === "down") {
|
|
9063
9520
|
await this.dispatchIntent({
|
|
9064
9521
|
type: "MOVE_ACTIVE_CELL_VERTICAL",
|
|
9065
9522
|
rowId: activeRowId,
|
|
9066
9523
|
columnId: activeColumnId,
|
|
9067
9524
|
direction: shiftKey ? "up" : "down"
|
|
9068
9525
|
});
|
|
9069
|
-
} else if (!this.engine.getCellEditOptions().singleClickEdit) {
|
|
9070
|
-
this.engine.startCellEdit(activeRowId, activeColumnId);
|
|
9071
9526
|
} else {
|
|
9072
9527
|
await this.dispatchIntent({
|
|
9073
|
-
type: "
|
|
9528
|
+
type: "MOVE_ACTIVE_CELL",
|
|
9074
9529
|
rowId: activeRowId,
|
|
9075
9530
|
columnId: activeColumnId,
|
|
9076
|
-
direction: shiftKey ? "
|
|
9531
|
+
direction: shiftKey ? "prev" : "next"
|
|
9077
9532
|
});
|
|
9078
9533
|
}
|
|
9079
9534
|
}
|
|
9080
9535
|
return;
|
|
9081
9536
|
}
|
|
9082
9537
|
case "Tab": {
|
|
9083
|
-
if (!
|
|
9538
|
+
if (!isGridCellTarget(e.target)) {
|
|
9084
9539
|
return;
|
|
9085
9540
|
}
|
|
9086
9541
|
if (activeRowId && activeColumnId) {
|
|
@@ -9270,7 +9725,7 @@ var UITableKeyboardHandler = class {
|
|
|
9270
9725
|
return;
|
|
9271
9726
|
}
|
|
9272
9727
|
case "KeyA": {
|
|
9273
|
-
if (ctrlKey) {
|
|
9728
|
+
if (ctrlKey && !inTextEditor) {
|
|
9274
9729
|
e.preventDefault();
|
|
9275
9730
|
await this.dispatchIntent({ type: "SELECT_ALL_CELLS" });
|
|
9276
9731
|
}
|
|
@@ -9278,6 +9733,7 @@ var UITableKeyboardHandler = class {
|
|
|
9278
9733
|
}
|
|
9279
9734
|
case "KeyC": {
|
|
9280
9735
|
if (ctrlKey && !altKey) {
|
|
9736
|
+
if (clipboardToEditor) return;
|
|
9281
9737
|
e.preventDefault();
|
|
9282
9738
|
if (this.copyCells) {
|
|
9283
9739
|
await this.copyCells();
|
|
@@ -9292,6 +9748,7 @@ var UITableKeyboardHandler = class {
|
|
|
9292
9748
|
}
|
|
9293
9749
|
case "KeyX": {
|
|
9294
9750
|
if (ctrlKey && !altKey) {
|
|
9751
|
+
if (clipboardToEditor) return;
|
|
9295
9752
|
e.preventDefault();
|
|
9296
9753
|
if (this.cutCells) {
|
|
9297
9754
|
await this.cutCells();
|
|
@@ -9306,6 +9763,7 @@ var UITableKeyboardHandler = class {
|
|
|
9306
9763
|
}
|
|
9307
9764
|
case "KeyV": {
|
|
9308
9765
|
if (ctrlKey && !altKey) {
|
|
9766
|
+
if (clipboardToEditor) return;
|
|
9309
9767
|
e.preventDefault();
|
|
9310
9768
|
if (this.pasteCells) {
|
|
9311
9769
|
await this.pasteCells();
|
|
@@ -9356,6 +9814,7 @@ var UITableKeyboardHandler = class {
|
|
|
9356
9814
|
return;
|
|
9357
9815
|
}
|
|
9358
9816
|
case "KeyZ": {
|
|
9817
|
+
if (inTextEditor) return;
|
|
9359
9818
|
if (ctrlKey && !shiftKey) {
|
|
9360
9819
|
e.preventDefault();
|
|
9361
9820
|
await this.dispatchIntent({ type: "UNDO" });
|
|
@@ -9368,7 +9827,7 @@ var UITableKeyboardHandler = class {
|
|
|
9368
9827
|
return;
|
|
9369
9828
|
}
|
|
9370
9829
|
case "KeyY": {
|
|
9371
|
-
if (ctrlKey) {
|
|
9830
|
+
if (ctrlKey && !inTextEditor) {
|
|
9372
9831
|
e.preventDefault();
|
|
9373
9832
|
await this.dispatchIntent({ type: "REDO" });
|
|
9374
9833
|
}
|
|
@@ -11049,7 +11508,7 @@ function createTableAppService(repo, audit, permissionPolicy, { columnMeta, remo
|
|
|
11049
11508
|
const changeCellHandler = new ChangeCellValueHandler(repo, audit, permissionPolicy, { columnMeta, remoteApi });
|
|
11050
11509
|
const applyDynamicProjection = new ApplyDynamicProjectionHandler(repo, audit, permissionPolicy, { columnMeta, remoteApi });
|
|
11051
11510
|
let rowVisibilityHandler;
|
|
11052
|
-
const applyRowVisibility = () => rowVisibilityHandler ?? (rowVisibilityHandler = import('./applyRowVisibilityHandler-
|
|
11511
|
+
const applyRowVisibility = () => rowVisibilityHandler ?? (rowVisibilityHandler = import('./applyRowVisibilityHandler-ZLZXQEGY.js').then(
|
|
11053
11512
|
(m) => new m.ApplyRowVisibilityHandler(repo, audit, permissionPolicy, { columnMeta, remoteApi })
|
|
11054
11513
|
));
|
|
11055
11514
|
const changeCellDisplayHandler = new ChangeCellDisplayValueHandler(repo, audit, permissionPolicy);
|
|
@@ -11106,14 +11565,39 @@ function createTableAppService(repo, audit, permissionPolicy, { columnMeta, remo
|
|
|
11106
11565
|
|
|
11107
11566
|
// bootstrap/index.ts
|
|
11108
11567
|
async function resolveEventStore(config, persist) {
|
|
11109
|
-
if (config.eventStore) return config.eventStore;
|
|
11110
|
-
if (config.persistence === "paged-idb")
|
|
11568
|
+
if (config.eventStore) return { eventStore: config.eventStore };
|
|
11569
|
+
if (config.persistence === "paged-idb") {
|
|
11570
|
+
return { eventStore: new InMemoryEventStore() };
|
|
11571
|
+
}
|
|
11111
11572
|
if (persist && typeof indexedDB !== "undefined") {
|
|
11112
|
-
|
|
11573
|
+
const opened = await IndexedDbEventStore.open(
|
|
11113
11574
|
eventStoreDbName(config.store, config.eventStoreName)
|
|
11114
11575
|
);
|
|
11576
|
+
return { eventStore: opened, close: () => opened.close() };
|
|
11115
11577
|
}
|
|
11116
|
-
return new InMemoryEventStore();
|
|
11578
|
+
return { eventStore: new InMemoryEventStore() };
|
|
11579
|
+
}
|
|
11580
|
+
function createDisposerRegistry() {
|
|
11581
|
+
const disposers = [];
|
|
11582
|
+
let running;
|
|
11583
|
+
return {
|
|
11584
|
+
add(disposer) {
|
|
11585
|
+
disposers.push(disposer);
|
|
11586
|
+
},
|
|
11587
|
+
run() {
|
|
11588
|
+
if (!running) {
|
|
11589
|
+
running = (async () => {
|
|
11590
|
+
for (const disposer of disposers.splice(0).reverse()) {
|
|
11591
|
+
try {
|
|
11592
|
+
await disposer();
|
|
11593
|
+
} catch {
|
|
11594
|
+
}
|
|
11595
|
+
}
|
|
11596
|
+
})();
|
|
11597
|
+
}
|
|
11598
|
+
return running;
|
|
11599
|
+
}
|
|
11600
|
+
};
|
|
11117
11601
|
}
|
|
11118
11602
|
function createInitialRows(collectionColumns) {
|
|
11119
11603
|
const rows = [];
|
|
@@ -11145,6 +11629,15 @@ function resolveHostRows(config, columns) {
|
|
|
11145
11629
|
);
|
|
11146
11630
|
}
|
|
11147
11631
|
async function assembleGrid(config) {
|
|
11632
|
+
const registry = createDisposerRegistry();
|
|
11633
|
+
try {
|
|
11634
|
+
return await assembleGridInner(config, registry);
|
|
11635
|
+
} catch (error) {
|
|
11636
|
+
await registry.run();
|
|
11637
|
+
throw error;
|
|
11638
|
+
}
|
|
11639
|
+
}
|
|
11640
|
+
async function assembleGridInner(config, registry) {
|
|
11148
11641
|
const { store, tableKey, actor, persist } = resolveCreateGridDefaults(config);
|
|
11149
11642
|
const resolved = {
|
|
11150
11643
|
...config,
|
|
@@ -11160,8 +11653,14 @@ async function assembleGrid(config) {
|
|
|
11160
11653
|
const windowed = isWindowedRepository(repo);
|
|
11161
11654
|
const audit = config.audit ?? new ConsoleAuditLogger();
|
|
11162
11655
|
const remoteApi = config.remoteApi ?? new NoopRemoteApi();
|
|
11163
|
-
const
|
|
11164
|
-
const
|
|
11656
|
+
const resolvedStore = await resolveEventStore(resolved, persist);
|
|
11657
|
+
const { eventStore } = resolvedStore;
|
|
11658
|
+
if (resolvedStore.close) registry.add(resolvedStore.close);
|
|
11659
|
+
const tracked = trackEventStoreSubscriptions(eventStore);
|
|
11660
|
+
registry.add(() => tracked.release());
|
|
11661
|
+
const internalStore = tracked.store;
|
|
11662
|
+
const changelogProjection = new ChangelogProjection(internalStore);
|
|
11663
|
+
registry.add(() => changelogProjection.dispose());
|
|
11165
11664
|
const historyPanelViewModel = new HistoryPanelViewModel(changelogProjection);
|
|
11166
11665
|
const cellUndoStack = new CellUndoStack();
|
|
11167
11666
|
await changelogProjection.start();
|
|
@@ -11170,11 +11669,12 @@ async function assembleGrid(config) {
|
|
|
11170
11669
|
connectivity: config.connectivity ?? createBrowserConnectivity(),
|
|
11171
11670
|
watermark: createLocalStorageWatermark(`pdg-sync-watermark:${store}:${tableKey}`)
|
|
11172
11671
|
});
|
|
11173
|
-
|
|
11672
|
+
registry.add(() => offlineStatus.dispose());
|
|
11673
|
+
await offlineStatus.start(internalStore);
|
|
11174
11674
|
const engineRef = {};
|
|
11175
11675
|
const snapshotStrategy = config.snapshotStore ? new SnapshotStrategy(
|
|
11176
11676
|
config.snapshotStore,
|
|
11177
|
-
|
|
11677
|
+
internalStore,
|
|
11178
11678
|
() => engineRef.current?.getSnapShot("active") ?? {
|
|
11179
11679
|
rows: []
|
|
11180
11680
|
},
|
|
@@ -11289,17 +11789,20 @@ async function assembleGrid(config) {
|
|
|
11289
11789
|
remoteApi,
|
|
11290
11790
|
offlineStatus
|
|
11291
11791
|
);
|
|
11792
|
+
controller.setResourceTeardown(() => registry.run());
|
|
11292
11793
|
let syncPort;
|
|
11293
11794
|
if (config.syncTransport) {
|
|
11294
|
-
const { GridSyncService } = await import('./GridSyncService-
|
|
11795
|
+
const { GridSyncService } = await import('./GridSyncService-GECXGEKL.js');
|
|
11295
11796
|
syncPort = new GridSyncService({
|
|
11296
11797
|
tableId: tableKey,
|
|
11297
|
-
eventStore,
|
|
11798
|
+
eventStore: internalStore,
|
|
11298
11799
|
offlineStatus,
|
|
11299
11800
|
transport: config.syncTransport,
|
|
11300
11801
|
policy: config.syncConflictPolicy,
|
|
11301
11802
|
applyCellValue: (rowId, columnId, value) => controller.applySyncedCellValue(rowId, columnId, value)
|
|
11302
11803
|
});
|
|
11804
|
+
const syncService = syncPort;
|
|
11805
|
+
registry.add(() => syncService.dispose?.());
|
|
11303
11806
|
controller.setSyncPort(syncPort);
|
|
11304
11807
|
}
|
|
11305
11808
|
let presencePort;
|
|
@@ -11314,6 +11817,8 @@ async function assembleGrid(config) {
|
|
|
11314
11817
|
label: config.presenceLabel ?? actor.userId,
|
|
11315
11818
|
transport: presenceTransport
|
|
11316
11819
|
});
|
|
11820
|
+
const presenceService = presencePort;
|
|
11821
|
+
registry.add(() => presenceService.dispose());
|
|
11317
11822
|
controller.setPresencePort(presencePort);
|
|
11318
11823
|
}
|
|
11319
11824
|
const { definitions: columnDefinitions, bindings: columnBindings } = mapColumnSchemas(hostColumns);
|
|
@@ -11331,7 +11836,11 @@ async function assembleGrid(config) {
|
|
|
11331
11836
|
engine.setCellEditOptions({
|
|
11332
11837
|
...typeof config.singleClickEdit === "boolean" ? { singleClickEdit: config.singleClickEdit } : {},
|
|
11333
11838
|
...typeof config.stopEditingWhenCellsLoseFocus === "boolean" ? { stopEditingWhenCellsLoseFocus: config.stopEditingWhenCellsLoseFocus } : {},
|
|
11334
|
-
...config.editType === "cell" || config.editType === "fullRow" ? { editType: config.editType } : {}
|
|
11839
|
+
...config.editType === "cell" || config.editType === "fullRow" ? { editType: config.editType } : {},
|
|
11840
|
+
// Page-window (document) grids keep the arianERP write-per-change
|
|
11841
|
+
// contract; the event-sourced grid avoids one EventStore write per key.
|
|
11842
|
+
commit: config.cellEditCommit === "immediate" || config.cellEditCommit === "deferred" ? config.cellEditCommit : pagedIdb ? "immediate" : "deferred",
|
|
11843
|
+
...config.enterNavigation === "nextCell" || config.enterNavigation === "down" ? { enterNavigation: config.enterNavigation } : {}
|
|
11335
11844
|
});
|
|
11336
11845
|
controller.configureClipboard({
|
|
11337
11846
|
copyFormattedValue: config.copyFormattedValue,
|
|
@@ -11373,6 +11882,7 @@ async function assembleGrid(config) {
|
|
|
11373
11882
|
maxBlocksInCache: config.maxBlocksInCache
|
|
11374
11883
|
});
|
|
11375
11884
|
refreshServerSide = () => handle.refreshServerSide();
|
|
11885
|
+
registry.add(() => handle.dispose());
|
|
11376
11886
|
}
|
|
11377
11887
|
if (snapshotStrategy) {
|
|
11378
11888
|
await snapshotStrategy.loadWithCatchUp(`table:${tableKey}`);
|
|
@@ -11380,10 +11890,12 @@ async function assembleGrid(config) {
|
|
|
11380
11890
|
const pluginHost = new PluginHost({
|
|
11381
11891
|
tableId: tableKey,
|
|
11382
11892
|
actorId: actor.userId,
|
|
11383
|
-
eventStore,
|
|
11893
|
+
eventStore: internalStore,
|
|
11384
11894
|
session,
|
|
11385
|
-
query: createEngineGridQuery(engine)
|
|
11895
|
+
query: createEngineGridQuery(engine),
|
|
11896
|
+
beforeRead: () => engine.flushCellEdit()
|
|
11386
11897
|
});
|
|
11898
|
+
registry.add(() => pluginHost.dispose());
|
|
11387
11899
|
if (config.plugins?.length) {
|
|
11388
11900
|
pluginHost.register(config.plugins);
|
|
11389
11901
|
}
|
|
@@ -11394,14 +11906,15 @@ async function assembleGrid(config) {
|
|
|
11394
11906
|
getRowId: config.getRowId,
|
|
11395
11907
|
refreshServerSide
|
|
11396
11908
|
});
|
|
11397
|
-
await attachColumnStatePersistence({
|
|
11909
|
+
const detachColumnState = await attachColumnStatePersistence({
|
|
11398
11910
|
api,
|
|
11399
11911
|
controller,
|
|
11400
11912
|
tableId: tableKey,
|
|
11401
11913
|
actorId: actor.userId,
|
|
11402
11914
|
stateKey: config.stateKey,
|
|
11403
|
-
eventStore
|
|
11915
|
+
eventStore: internalStore
|
|
11404
11916
|
});
|
|
11917
|
+
registry.add(detachColumnState);
|
|
11405
11918
|
return {
|
|
11406
11919
|
engine,
|
|
11407
11920
|
controller,
|
|
@@ -11670,5 +12183,5 @@ function listUndoableEventTypes() {
|
|
|
11670
12183
|
}
|
|
11671
12184
|
|
|
11672
12185
|
export { ColumnAggIndex, DEFAULT_EVENT_STORE_PREFIX, DEFAULT_GRID_ACTOR, DEFAULT_MEMORY_STORE, EVENT_CATALOG, InMemoryEventStore, InMemorySnapshotStore, IndexedDbEventStore, LEGACY_EVENT_STORE_PREFIX, MemoryKvDatabase, NoopRemoteApi, OfflineStatus, PluginHost, QuickFilterIndex, SnapshotStrategy, SparseRowIndex, TableEngine, UITableController, accumulateAdd, accumulateRemove, addJalaliMonths, alwaysOnlineConnectivity, applyAgg, applyFillHandleDrag, applyFilter, applyHostRowDataToTable, applyQuickFilter, buildClipboardPayload, buildColumnGroupHeaderModel, buildFillUpdates, buildPastePlan, buildQuickFilterBlob, canSetColumnVisible, cellRangeClassName, cellRangeEdgeAttr, clampColIndex, clampRowIndex, clickCell, coercePastedCellValue, colIndex, collectUniqueFilterValues, columnDefFieldName, copyGridSelectionToClipboard, createAccumulator, createBrowserConnectivity, createERPTable, createEmptyCellRangeSelection, createEngineGridQuery, createGrid, createGridApi, createGridTableKey, createLocalStorageWatermark, ctrlClickCell, cutGridSelectionToClipboard, defaultGetRowId, detectFillSeries, ensureIndexColumnDef, eventStoreDbName, extendSeriesValue, flattenColDefOrGroup, getEventCatalogEntry, isAggFuncName, isCellInRange, isColumnFilterActive, isColumnGroupDef, isCustomAggFunc, isPersistentStore, isServerRowModel, isWindowedRepository, listUndoableEventTypes, mapColDefOrGroups, mapColumnDefs, mapColumnSchemas, mapColumnSchemasToDefs, mapRowDataToRowInputs, maxColumnGroupDepth, mergeCellRanges, moveCellAddress, normalizeCellRange, normalizeFilterText, normalizePersianNumberText, normalizeQuickFilterText, openIndexedDbDatabase, pageWindow, parseClipboardDate, parseClipboardNumber, parseDelimitedClipboardText, pasteGridFromClipboard, rangeFromAnchorFocus, rangesOverlap, readAccumulator, readSystemClipboardText, resolveBuiltinFilterKind, resolveCellAddressFromPoint, resolveCellRangePresentation, resolveColumnAggSpecs, resolveCopyRanges, resolveCreateGridDefaults, resolveFillCorner, resolveFilterUi, resolveGroupBlockReorder, selectAllCellRanges, shiftArrowCell, shiftClickCell, toColumnDef, toColumnDefinition, toColumnSchema, toColumnViewBinding, toMinorUnits, trapTabKey, writeSystemClipboard };
|
|
11673
|
-
//# sourceMappingURL=chunk-
|
|
11674
|
-
//# sourceMappingURL=chunk-
|
|
12186
|
+
//# sourceMappingURL=chunk-27ALJSZP.js.map
|
|
12187
|
+
//# sourceMappingURL=chunk-27ALJSZP.js.map
|