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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var chunkMT3KLB2Q_cjs = require('./chunk-MT3KLB2Q.cjs');
|
|
4
4
|
var chunkUC7PHDM6_cjs = require('./chunk-UC7PHDM6.cjs');
|
|
5
|
-
var
|
|
5
|
+
var chunk52LFOPXD_cjs = require('./chunk-52LFOPXD.cjs');
|
|
6
6
|
var chunkKMRURD5J_cjs = require('./chunk-KMRURD5J.cjs');
|
|
7
7
|
var chunkJOICD47Q_cjs = require('./chunk-JOICD47Q.cjs');
|
|
8
8
|
var chunkDFFP7SJ6_cjs = require('./chunk-DFFP7SJ6.cjs');
|
|
@@ -1335,6 +1335,7 @@ var SparseRowIndex = class {
|
|
|
1335
1335
|
this.orderedIds = [];
|
|
1336
1336
|
/** id → position in `orderedIds` (PR-99). */
|
|
1337
1337
|
this.posById = /* @__PURE__ */ new Map();
|
|
1338
|
+
this.revisionCount = 0;
|
|
1338
1339
|
for (const [id, value] of entries) {
|
|
1339
1340
|
this.byId.set(id, value);
|
|
1340
1341
|
this.posById.set(id, this.orderedIds.length);
|
|
@@ -1344,6 +1345,13 @@ var SparseRowIndex = class {
|
|
|
1344
1345
|
get size() {
|
|
1345
1346
|
return this.orderedIds.length;
|
|
1346
1347
|
}
|
|
1348
|
+
/**
|
|
1349
|
+
* Bumped by every change of ids, order or values. O(1) change detection for
|
|
1350
|
+
* subscribers (a sort keeps `size` but changes the order).
|
|
1351
|
+
*/
|
|
1352
|
+
get revision() {
|
|
1353
|
+
return this.revisionCount;
|
|
1354
|
+
}
|
|
1347
1355
|
getOrderedIds() {
|
|
1348
1356
|
return this.orderedIds;
|
|
1349
1357
|
}
|
|
@@ -1365,6 +1373,7 @@ var SparseRowIndex = class {
|
|
|
1365
1373
|
}
|
|
1366
1374
|
set(id, value) {
|
|
1367
1375
|
const existed = this.byId.has(id);
|
|
1376
|
+
this.revisionCount += 1;
|
|
1368
1377
|
this.byId.set(id, value);
|
|
1369
1378
|
if (!existed) {
|
|
1370
1379
|
this.posById.set(id, this.orderedIds.length);
|
|
@@ -1373,6 +1382,7 @@ var SparseRowIndex = class {
|
|
|
1373
1382
|
}
|
|
1374
1383
|
/** Insert `id` at `pos` (0…size). Shifts later positions — O(n-pos). */
|
|
1375
1384
|
insertAt(pos, id, value) {
|
|
1385
|
+
this.revisionCount += 1;
|
|
1376
1386
|
if (this.byId.has(id)) {
|
|
1377
1387
|
this.byId.set(id, value);
|
|
1378
1388
|
return;
|
|
@@ -1386,6 +1396,7 @@ var SparseRowIndex = class {
|
|
|
1386
1396
|
}
|
|
1387
1397
|
remove(id) {
|
|
1388
1398
|
if (!this.byId.has(id)) return false;
|
|
1399
|
+
this.revisionCount += 1;
|
|
1389
1400
|
this.byId.delete(id);
|
|
1390
1401
|
const pos = this.posById.get(id);
|
|
1391
1402
|
this.posById.delete(id);
|
|
@@ -1398,6 +1409,7 @@ var SparseRowIndex = class {
|
|
|
1398
1409
|
}
|
|
1399
1410
|
/** Replace order without rebuilding payloads (e.g. after sort). */
|
|
1400
1411
|
setOrder(orderedIds) {
|
|
1412
|
+
this.revisionCount += 1;
|
|
1401
1413
|
this.orderedIds = orderedIds.slice();
|
|
1402
1414
|
this.posById.clear();
|
|
1403
1415
|
for (let i = 0; i < this.orderedIds.length; i += 1) {
|
|
@@ -1406,6 +1418,7 @@ var SparseRowIndex = class {
|
|
|
1406
1418
|
}
|
|
1407
1419
|
/** Full replace of ids + values in one pass (PR-99 rebuild). */
|
|
1408
1420
|
replaceAll(orderedIds, valueFor) {
|
|
1421
|
+
this.revisionCount += 1;
|
|
1409
1422
|
this.byId.clear();
|
|
1410
1423
|
this.orderedIds = orderedIds.slice();
|
|
1411
1424
|
this.posById.clear();
|
|
@@ -1416,6 +1429,7 @@ var SparseRowIndex = class {
|
|
|
1416
1429
|
}
|
|
1417
1430
|
}
|
|
1418
1431
|
clear() {
|
|
1432
|
+
this.revisionCount += 1;
|
|
1419
1433
|
this.byId.clear();
|
|
1420
1434
|
this.orderedIds = [];
|
|
1421
1435
|
this.posById.clear();
|
|
@@ -3144,21 +3158,35 @@ var TableStore = class {
|
|
|
3144
3158
|
var DEFAULT_CELL_EDIT_OPTIONS = {
|
|
3145
3159
|
singleClickEdit: true,
|
|
3146
3160
|
stopEditingWhenCellsLoseFocus: true,
|
|
3147
|
-
editType: "cell"
|
|
3161
|
+
editType: "cell",
|
|
3162
|
+
commit: "deferred",
|
|
3163
|
+
enterNavigation: "nextCell"
|
|
3148
3164
|
};
|
|
3165
|
+
var sessionSeq = 0;
|
|
3149
3166
|
function createCellEditSession(input) {
|
|
3150
3167
|
const drafts = {};
|
|
3151
3168
|
for (const [colId, cell] of Object.entries(input.baseline)) {
|
|
3152
3169
|
drafts[colId] = { value: cell.value, display: cell.display };
|
|
3153
3170
|
}
|
|
3171
|
+
sessionSeq += 1;
|
|
3154
3172
|
return {
|
|
3155
3173
|
rowId: input.rowId,
|
|
3156
3174
|
columnId: input.columnId,
|
|
3157
3175
|
editType: input.editType,
|
|
3158
3176
|
baseline: input.baseline,
|
|
3159
|
-
drafts
|
|
3177
|
+
drafts,
|
|
3178
|
+
correlationId: `cell-edit-${Date.now()}-${sessionSeq}`
|
|
3160
3179
|
};
|
|
3161
3180
|
}
|
|
3181
|
+
function rebaseDraft(session, columnIds) {
|
|
3182
|
+
if (columnIds.length === 0) return session;
|
|
3183
|
+
const baseline = { ...session.baseline };
|
|
3184
|
+
for (const colId of columnIds) {
|
|
3185
|
+
const draft = session.drafts[colId];
|
|
3186
|
+
if (draft) baseline[colId] = { value: draft.value, display: draft.display };
|
|
3187
|
+
}
|
|
3188
|
+
return { ...session, baseline };
|
|
3189
|
+
}
|
|
3162
3190
|
function readDraft(session, rowId, columnId) {
|
|
3163
3191
|
if (!session || session.rowId !== rowId) return null;
|
|
3164
3192
|
return session.drafts[columnId] ?? null;
|
|
@@ -3183,8 +3211,8 @@ function patchDraft(session, columnId, patch) {
|
|
|
3183
3211
|
drafts: {
|
|
3184
3212
|
...session.drafts,
|
|
3185
3213
|
[columnId]: {
|
|
3186
|
-
value:
|
|
3187
|
-
display:
|
|
3214
|
+
value: "value" in patch ? patch.value : prev.value,
|
|
3215
|
+
display: "display" in patch ? patch.display : prev.display
|
|
3188
3216
|
}
|
|
3189
3217
|
}
|
|
3190
3218
|
};
|
|
@@ -4169,6 +4197,7 @@ var ViewStateBuilder = class {
|
|
|
4169
4197
|
};
|
|
4170
4198
|
|
|
4171
4199
|
// engine/tableEngine.ts
|
|
4200
|
+
var cellWriteKey = (kind, rowId, columnId) => `${kind}\0${rowId}\0${columnId}`;
|
|
4172
4201
|
var TableEngine = class {
|
|
4173
4202
|
constructor(app, repo, actor, audit, columnMeta) {
|
|
4174
4203
|
this.app = app;
|
|
@@ -4176,6 +4205,15 @@ var TableEngine = class {
|
|
|
4176
4205
|
this.actor = actor;
|
|
4177
4206
|
this.columnMeta = columnMeta;
|
|
4178
4207
|
this.cellEditOptions = { ...DEFAULT_CELL_EDIT_OPTIONS };
|
|
4208
|
+
/**
|
|
4209
|
+
* Cell writes coming from editors / host input, executed one at a time in
|
|
4210
|
+
* arrival order. Consecutive values for the same cell coalesce (latest
|
|
4211
|
+
* wins). Until a write landed, the queued value is what the cell shows.
|
|
4212
|
+
*/
|
|
4213
|
+
this.cellWrites = /* @__PURE__ */ new Map();
|
|
4214
|
+
this.cellWriteChain = Promise.resolve();
|
|
4215
|
+
/** > 0 while a queued write executes (re-entrant settle must not wait on itself). */
|
|
4216
|
+
this.cellWriteDepth = 0;
|
|
4179
4217
|
this.errors = /* @__PURE__ */ new Map();
|
|
4180
4218
|
this.searchResult = /* @__PURE__ */ new Map();
|
|
4181
4219
|
this.asyncCellCache = /* @__PURE__ */ new Map();
|
|
@@ -4750,54 +4788,54 @@ var TableEngine = class {
|
|
|
4750
4788
|
const next = command.sortModel.filter(
|
|
4751
4789
|
(item) => item && typeof item.colId === "string" && item.colId.length > 0 && (item.sort === "asc" || item.sort === "desc")
|
|
4752
4790
|
).map((item) => ({ colId: item.colId, sort: item.sort }));
|
|
4791
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4753
4792
|
store.setState((prev) => ({
|
|
4754
4793
|
...prev,
|
|
4755
4794
|
sortModel: next
|
|
4756
4795
|
}));
|
|
4757
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4758
4796
|
this.notifyViewQueryChanged();
|
|
4759
4797
|
}
|
|
4760
4798
|
setQuickFilterText(command) {
|
|
4761
4799
|
const store = this.getStore(command.tableKey);
|
|
4762
4800
|
if (!store) return;
|
|
4763
4801
|
const next = typeof command.quickFilterText === "string" ? command.quickFilterText : "";
|
|
4802
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4764
4803
|
store.setState((prev) => ({
|
|
4765
4804
|
...prev,
|
|
4766
4805
|
quickFilterText: next
|
|
4767
4806
|
}));
|
|
4768
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4769
4807
|
}
|
|
4770
4808
|
setFilterModel(command) {
|
|
4771
4809
|
const store = this.getStore(command.tableKey);
|
|
4772
4810
|
if (!store) return;
|
|
4773
4811
|
const next = command.filterModel && typeof command.filterModel === "object" ? { ...command.filterModel } : {};
|
|
4812
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4774
4813
|
store.setState((prev) => ({
|
|
4775
4814
|
...prev,
|
|
4776
4815
|
filterModel: next
|
|
4777
4816
|
}));
|
|
4778
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4779
4817
|
this.notifyViewQueryChanged();
|
|
4780
4818
|
}
|
|
4781
4819
|
setRowGroupColumns(command) {
|
|
4782
4820
|
const store = this.getStore(command.tableKey);
|
|
4783
4821
|
if (!store) return;
|
|
4784
4822
|
const next = command.columns.filter((c) => typeof c === "string" && c.trim() !== "").map((c) => c.trim());
|
|
4823
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4785
4824
|
store.setState((prev) => ({
|
|
4786
4825
|
...prev,
|
|
4787
4826
|
rowGroupColumns: next,
|
|
4788
4827
|
rowGroupExpanded: {}
|
|
4789
4828
|
}));
|
|
4790
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4791
4829
|
}
|
|
4792
4830
|
setGroupDefaultExpanded(command) {
|
|
4793
4831
|
const store = this.getStore(command.tableKey);
|
|
4794
4832
|
if (!store) return;
|
|
4833
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4795
4834
|
store.setState((prev) => ({
|
|
4796
4835
|
...prev,
|
|
4797
4836
|
groupDefaultExpanded: Boolean(command.expanded),
|
|
4798
4837
|
rowGroupExpanded: {}
|
|
4799
4838
|
}));
|
|
4800
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4801
4839
|
}
|
|
4802
4840
|
toggleRowGroup(command) {
|
|
4803
4841
|
const store = this.getStore(command.tableKey);
|
|
@@ -4808,6 +4846,7 @@ var TableEngine = class {
|
|
|
4808
4846
|
state.rowGroupExpanded,
|
|
4809
4847
|
key
|
|
4810
4848
|
) ? state.rowGroupExpanded[key] : state.groupDefaultExpanded;
|
|
4849
|
+
this.viewBuilder.invalidateUiRowIndex();
|
|
4811
4850
|
store.setState((prev) => ({
|
|
4812
4851
|
...prev,
|
|
4813
4852
|
rowGroupExpanded: {
|
|
@@ -4815,7 +4854,6 @@ var TableEngine = class {
|
|
|
4815
4854
|
[key]: !current
|
|
4816
4855
|
}
|
|
4817
4856
|
}));
|
|
4818
|
-
this.viewBuilder.invalidateUiRowIndex();
|
|
4819
4857
|
}
|
|
4820
4858
|
/**
|
|
4821
4859
|
* Server/infinite row model hooks (PR-96).
|
|
@@ -5084,6 +5122,7 @@ var TableEngine = class {
|
|
|
5084
5122
|
async getFullSnapShot(store, collectionScope = "active") {
|
|
5085
5123
|
if (!this.tableKey) return null;
|
|
5086
5124
|
try {
|
|
5125
|
+
await this.flushCellEdit();
|
|
5087
5126
|
const rows = await this.loadAllRows(store, collectionScope);
|
|
5088
5127
|
const { rowsToSnapshot } = await import('./memoryRecords-AWDKUJ2F.cjs');
|
|
5089
5128
|
return rowsToSnapshot(rows);
|
|
@@ -5100,6 +5139,7 @@ var TableEngine = class {
|
|
|
5100
5139
|
async iterateRowsFromDb(store, collectionScope, onBatch, batchSize) {
|
|
5101
5140
|
if (!this.tableKey) return;
|
|
5102
5141
|
try {
|
|
5142
|
+
await this.flushCellEdit();
|
|
5103
5143
|
if (isWindowedRepository(this.repo)) {
|
|
5104
5144
|
await this.repo.iterateRowRecords(
|
|
5105
5145
|
store,
|
|
@@ -5156,8 +5196,196 @@ var TableEngine = class {
|
|
|
5156
5196
|
getCellEdit() {
|
|
5157
5197
|
return this.tableStore?.getState().cellEdit ?? null;
|
|
5158
5198
|
}
|
|
5199
|
+
/**
|
|
5200
|
+
* What the cell editor shows: the session draft, else a value that was
|
|
5201
|
+
* typed but whose write has not reached the table yet (no flicker back to
|
|
5202
|
+
* the old value while it is in flight). `null` = show the table value.
|
|
5203
|
+
*/
|
|
5159
5204
|
getEditDraft(rowId, columnId) {
|
|
5160
|
-
|
|
5205
|
+
const draft = readDraft(this.getCellEdit(), rowId, columnId);
|
|
5206
|
+
if (draft) return draft;
|
|
5207
|
+
const value = this.cellWrites.get(cellWriteKey("value", rowId, columnId));
|
|
5208
|
+
const display = this.cellWrites.get(cellWriteKey("display", rowId, columnId));
|
|
5209
|
+
if (!value && !display) return null;
|
|
5210
|
+
const cell = this.viewBuilder.getCell(rowId, columnId);
|
|
5211
|
+
return {
|
|
5212
|
+
value: value ? value.write.value : cell?.getValue(),
|
|
5213
|
+
display: display ? display.write.value : cell?.getDisplay()
|
|
5214
|
+
};
|
|
5215
|
+
}
|
|
5216
|
+
/** Editor / host value for a cell (`UI_CELL_CHANGE`). Resolves once it is durable. */
|
|
5217
|
+
inputCellValue(rowId, columnId, value) {
|
|
5218
|
+
return this.inputCell(rowId, columnId, "value", value);
|
|
5219
|
+
}
|
|
5220
|
+
/** Editor / host display label for a cell (`UI_CELL_CHANGE_DISPLAY`). */
|
|
5221
|
+
inputCellDisplay(rowId, columnId, display) {
|
|
5222
|
+
return this.inputCell(rowId, columnId, "display", display);
|
|
5223
|
+
}
|
|
5224
|
+
async inputCell(rowId, columnId, kind, input) {
|
|
5225
|
+
const store = this.tableStore;
|
|
5226
|
+
if (!store) return;
|
|
5227
|
+
const session = store.getState().cellEdit;
|
|
5228
|
+
if (session && isEditingCell(session, rowId, columnId)) {
|
|
5229
|
+
const immediate = this.cellEditOptions.commit === "immediate";
|
|
5230
|
+
const patch = kind === "value" ? { value: input } : { display: input };
|
|
5231
|
+
store.setState((prev) => {
|
|
5232
|
+
if (!prev.cellEdit || prev.cellEdit.rowId !== rowId) return prev;
|
|
5233
|
+
const patched = patchDraft(prev.cellEdit, columnId, patch);
|
|
5234
|
+
return {
|
|
5235
|
+
...prev,
|
|
5236
|
+
cellEdit: immediate ? rebaseDraft(patched, [columnId]) : patched
|
|
5237
|
+
};
|
|
5238
|
+
});
|
|
5239
|
+
if (!immediate) return;
|
|
5240
|
+
this.enqueueCellWrite({
|
|
5241
|
+
rowId,
|
|
5242
|
+
columnId,
|
|
5243
|
+
kind,
|
|
5244
|
+
value: input,
|
|
5245
|
+
correlationId: session.correlationId
|
|
5246
|
+
});
|
|
5247
|
+
} else {
|
|
5248
|
+
this.enqueueCellWrite({ rowId, columnId, kind, value: input });
|
|
5249
|
+
}
|
|
5250
|
+
await this.settleCellWrites();
|
|
5251
|
+
}
|
|
5252
|
+
enqueueCellWrite(write) {
|
|
5253
|
+
const key = cellWriteKey(write.kind, write.rowId, write.columnId);
|
|
5254
|
+
const pending = this.cellWrites.get(key);
|
|
5255
|
+
if (pending?.queued) {
|
|
5256
|
+
pending.write = write;
|
|
5257
|
+
return;
|
|
5258
|
+
}
|
|
5259
|
+
const slot = { write, queued: true };
|
|
5260
|
+
this.cellWrites.set(key, slot);
|
|
5261
|
+
this.cellWriteChain = this.cellWriteChain.then(() => this.runCellWrite(key, slot));
|
|
5262
|
+
}
|
|
5263
|
+
async runCellWrite(key, slot) {
|
|
5264
|
+
slot.queued = false;
|
|
5265
|
+
const { write } = slot;
|
|
5266
|
+
const commandStore = this.commandStore;
|
|
5267
|
+
const tableKey = this.tableKey;
|
|
5268
|
+
this.cellWriteDepth += 1;
|
|
5269
|
+
try {
|
|
5270
|
+
if (commandStore && tableKey && this.tableStore) {
|
|
5271
|
+
await this.dispatch(
|
|
5272
|
+
write.kind === "value" ? {
|
|
5273
|
+
type: "CHANGE_CELL_VALUE",
|
|
5274
|
+
store: commandStore,
|
|
5275
|
+
tableKey,
|
|
5276
|
+
rowId: write.rowId,
|
|
5277
|
+
columnId: write.columnId,
|
|
5278
|
+
newValue: write.value,
|
|
5279
|
+
correlationId: write.correlationId
|
|
5280
|
+
} : {
|
|
5281
|
+
type: "CHANGE_CELL_DISPLAY_VALUE",
|
|
5282
|
+
store: commandStore,
|
|
5283
|
+
tableKey,
|
|
5284
|
+
rowId: write.rowId,
|
|
5285
|
+
columnId: write.columnId,
|
|
5286
|
+
newValue: write.value == null ? "" : String(write.value),
|
|
5287
|
+
correlationId: write.correlationId
|
|
5288
|
+
}
|
|
5289
|
+
);
|
|
5290
|
+
}
|
|
5291
|
+
} catch (e) {
|
|
5292
|
+
this.errHandler.handle(e, "TableEngine.cellWrite");
|
|
5293
|
+
} finally {
|
|
5294
|
+
this.cellWriteDepth -= 1;
|
|
5295
|
+
if (this.cellWrites.get(key) === slot && !slot.queued) {
|
|
5296
|
+
this.cellWrites.delete(key);
|
|
5297
|
+
const cell = this.viewBuilder.getCell(write.rowId, write.columnId);
|
|
5298
|
+
const landed = write.kind === "value" ? cell?.getValue() : cell?.getDisplay();
|
|
5299
|
+
if (landed !== write.value) this.tableStore?.setState((prev) => ({ ...prev }));
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5302
|
+
}
|
|
5303
|
+
/**
|
|
5304
|
+
* Resolves when every queued cell write reached the table. Called from inside
|
|
5305
|
+
* a write (re-entrant) it returns at once instead of waiting on itself.
|
|
5306
|
+
*/
|
|
5307
|
+
async settleCellWrites() {
|
|
5308
|
+
if (this.cellWriteDepth > 0) return;
|
|
5309
|
+
let chain;
|
|
5310
|
+
do {
|
|
5311
|
+
chain = this.cellWriteChain;
|
|
5312
|
+
await chain;
|
|
5313
|
+
} while (chain !== this.cellWriteChain);
|
|
5314
|
+
}
|
|
5315
|
+
/** Queues CHANGE_CELL_* for `columnIds` of `session`; returns the value writes. */
|
|
5316
|
+
queueDraftWrites(session, columnIds) {
|
|
5317
|
+
let writes = 0;
|
|
5318
|
+
for (const colId of columnIds) {
|
|
5319
|
+
const draft = session.drafts[colId];
|
|
5320
|
+
if (!draft) continue;
|
|
5321
|
+
const base = session.baseline[colId];
|
|
5322
|
+
if (!base || draft.value !== base.value) {
|
|
5323
|
+
this.enqueueCellWrite({
|
|
5324
|
+
rowId: session.rowId,
|
|
5325
|
+
columnId: colId,
|
|
5326
|
+
kind: "value",
|
|
5327
|
+
value: draft.value,
|
|
5328
|
+
correlationId: session.correlationId
|
|
5329
|
+
});
|
|
5330
|
+
writes += 1;
|
|
5331
|
+
}
|
|
5332
|
+
if (!base || draft.display !== base.display) {
|
|
5333
|
+
this.enqueueCellWrite({
|
|
5334
|
+
rowId: session.rowId,
|
|
5335
|
+
columnId: colId,
|
|
5336
|
+
kind: "display",
|
|
5337
|
+
value: draft.display,
|
|
5338
|
+
correlationId: session.correlationId
|
|
5339
|
+
});
|
|
5340
|
+
}
|
|
5341
|
+
}
|
|
5342
|
+
return writes;
|
|
5343
|
+
}
|
|
5344
|
+
/**
|
|
5345
|
+
* Make what the user typed durable WITHOUT ending the edit: dirty drafts are
|
|
5346
|
+
* written and become the session baseline, then all queued writes settle.
|
|
5347
|
+
* Every durable read (snapshot, row stream, export) calls this first, so a
|
|
5348
|
+
* save never misses the value still in the editor.
|
|
5349
|
+
*/
|
|
5350
|
+
async flushCellEdit() {
|
|
5351
|
+
const store = this.tableStore;
|
|
5352
|
+
const session = store?.getState().cellEdit;
|
|
5353
|
+
if (store && session) {
|
|
5354
|
+
const dirty = dirtyDraftColumns(session);
|
|
5355
|
+
if (dirty.length > 0) {
|
|
5356
|
+
store.setState(
|
|
5357
|
+
(prev) => prev.cellEdit && prev.cellEdit.rowId === session.rowId ? { ...prev, cellEdit: rebaseDraft(prev.cellEdit, dirty) } : prev
|
|
5358
|
+
);
|
|
5359
|
+
this.queueDraftWrites(session, dirty);
|
|
5360
|
+
}
|
|
5361
|
+
}
|
|
5362
|
+
await this.settleCellWrites();
|
|
5363
|
+
}
|
|
5364
|
+
/**
|
|
5365
|
+
* Focus / pointer moved outside the grid. Deferred commit ends the edit per
|
|
5366
|
+
* `stopEditingWhenCellsLoseFocus`; immediate commit has nothing pending and
|
|
5367
|
+
* keeps the editor (legacy table behaviour).
|
|
5368
|
+
*/
|
|
5369
|
+
async leaveGridFocus() {
|
|
5370
|
+
if (!this.getCellEdit()) return;
|
|
5371
|
+
if (this.cellEditOptions.commit !== "deferred") return;
|
|
5372
|
+
if (!this.cellEditOptions.stopEditingWhenCellsLoseFocus) return;
|
|
5373
|
+
await this.commitCellEdit();
|
|
5374
|
+
}
|
|
5375
|
+
/**
|
|
5376
|
+
* Before dispose / unmount: commit (or drop, when
|
|
5377
|
+
* `stopEditingWhenCellsLoseFocus` is false) the open edit and wait until
|
|
5378
|
+
* every queued write is durable.
|
|
5379
|
+
*/
|
|
5380
|
+
async settleEditsForTeardown() {
|
|
5381
|
+
if (this.getCellEdit()) {
|
|
5382
|
+
if (this.cellEditOptions.stopEditingWhenCellsLoseFocus) {
|
|
5383
|
+
await this.commitCellEdit();
|
|
5384
|
+
} else {
|
|
5385
|
+
this.cancelCellEdit();
|
|
5386
|
+
}
|
|
5387
|
+
}
|
|
5388
|
+
await this.settleCellWrites();
|
|
5161
5389
|
}
|
|
5162
5390
|
isEditingCell(rowId, columnId) {
|
|
5163
5391
|
return isEditingCell(this.getCellEdit(), rowId, columnId);
|
|
@@ -5248,39 +5476,12 @@ var TableEngine = class {
|
|
|
5248
5476
|
*/
|
|
5249
5477
|
async commitCellEdit() {
|
|
5250
5478
|
const store = this.tableStore;
|
|
5251
|
-
|
|
5252
|
-
const tableKey = this.tableKey;
|
|
5253
|
-
if (!store || !commandStore || !tableKey) return 0;
|
|
5479
|
+
if (!store || !this.commandStore || !this.tableKey) return 0;
|
|
5254
5480
|
const session = store.getState().cellEdit;
|
|
5255
5481
|
if (!session) return 0;
|
|
5256
|
-
const dirty = dirtyDraftColumns(session);
|
|
5257
5482
|
store.setState((prev) => ({ ...prev, cellEdit: null }));
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
const draft = session.drafts[colId];
|
|
5261
|
-
const base = session.baseline[colId];
|
|
5262
|
-
if (!base || draft.value !== base.value) {
|
|
5263
|
-
await this.dispatch({
|
|
5264
|
-
type: "CHANGE_CELL_VALUE",
|
|
5265
|
-
store: commandStore,
|
|
5266
|
-
tableKey,
|
|
5267
|
-
rowId: session.rowId,
|
|
5268
|
-
columnId: colId,
|
|
5269
|
-
newValue: draft.value
|
|
5270
|
-
});
|
|
5271
|
-
writes += 1;
|
|
5272
|
-
}
|
|
5273
|
-
if (!base || draft.display !== base.display) {
|
|
5274
|
-
await this.dispatch({
|
|
5275
|
-
type: "CHANGE_CELL_DISPLAY_VALUE",
|
|
5276
|
-
store: commandStore,
|
|
5277
|
-
tableKey,
|
|
5278
|
-
rowId: session.rowId,
|
|
5279
|
-
columnId: colId,
|
|
5280
|
-
newValue: draft.display == null ? "" : String(draft.display)
|
|
5281
|
-
});
|
|
5282
|
-
}
|
|
5283
|
-
}
|
|
5483
|
+
const writes = this.queueDraftWrites(session, dirtyDraftColumns(session));
|
|
5484
|
+
await this.settleCellWrites();
|
|
5284
5485
|
return writes;
|
|
5285
5486
|
}
|
|
5286
5487
|
async transitionActiveCell(rowId, columnId) {
|
|
@@ -5469,16 +5670,15 @@ var TableEngine = class {
|
|
|
5469
5670
|
if (syncError) return syncError;
|
|
5470
5671
|
return this.applyAsyncValidators(value, schema, caption, rowId);
|
|
5471
5672
|
}
|
|
5472
|
-
finishValidation(cb, tableStore) {
|
|
5673
|
+
finishValidation(cb, tableStore, errorsChanged) {
|
|
5473
5674
|
cb({
|
|
5474
5675
|
valid: this.errors.size === 0,
|
|
5475
5676
|
errors: this.errors,
|
|
5476
5677
|
data: this.getAllRows()
|
|
5477
5678
|
});
|
|
5478
|
-
tableStore.setState(
|
|
5479
|
-
...prev,
|
|
5480
|
-
|
|
5481
|
-
}));
|
|
5679
|
+
tableStore.setState(
|
|
5680
|
+
(prev) => !errorsChanged && Object.keys(prev.expandedRows ?? {}).length === 0 ? prev : { ...prev, expandedRows: {} }
|
|
5681
|
+
);
|
|
5482
5682
|
}
|
|
5483
5683
|
collectValidationJobs(table) {
|
|
5484
5684
|
const jobs = [];
|
|
@@ -5497,11 +5697,23 @@ var TableEngine = class {
|
|
|
5497
5697
|
});
|
|
5498
5698
|
return jobs;
|
|
5499
5699
|
}
|
|
5700
|
+
/** Replaces the error map; true when the set of errors / messages changed. */
|
|
5500
5701
|
applyValidationErrors(nextErrors) {
|
|
5702
|
+
let changed = nextErrors.size !== this.errors.size;
|
|
5703
|
+
if (!changed) {
|
|
5704
|
+
for (const [cellId, error] of nextErrors) {
|
|
5705
|
+
const prev = this.errors.get(cellId);
|
|
5706
|
+
if (!prev || prev.message !== error.message || prev.rowId !== error.rowId) {
|
|
5707
|
+
changed = true;
|
|
5708
|
+
break;
|
|
5709
|
+
}
|
|
5710
|
+
}
|
|
5711
|
+
}
|
|
5501
5712
|
this.errors.clear();
|
|
5502
5713
|
nextErrors.forEach((error, cellId) => {
|
|
5503
5714
|
this.errors.set(cellId, error);
|
|
5504
5715
|
});
|
|
5716
|
+
return changed;
|
|
5505
5717
|
}
|
|
5506
5718
|
runValidationSync(table, cb, tableStore) {
|
|
5507
5719
|
const nextErrors = /* @__PURE__ */ new Map();
|
|
@@ -5514,8 +5726,8 @@ var TableEngine = class {
|
|
|
5514
5726
|
);
|
|
5515
5727
|
if (error) nextErrors.set(job.cellId, error);
|
|
5516
5728
|
}
|
|
5517
|
-
this.applyValidationErrors(nextErrors);
|
|
5518
|
-
this.finishValidation(cb, tableStore);
|
|
5729
|
+
const changed = this.applyValidationErrors(nextErrors);
|
|
5730
|
+
this.finishValidation(cb, tableStore, changed);
|
|
5519
5731
|
}
|
|
5520
5732
|
async runValidationAsync(table, cb, tableStore) {
|
|
5521
5733
|
const nextErrors = /* @__PURE__ */ new Map();
|
|
@@ -5528,8 +5740,8 @@ var TableEngine = class {
|
|
|
5528
5740
|
);
|
|
5529
5741
|
if (error) nextErrors.set(job.cellId, error);
|
|
5530
5742
|
}
|
|
5531
|
-
this.applyValidationErrors(nextErrors);
|
|
5532
|
-
this.finishValidation(cb, tableStore);
|
|
5743
|
+
const changed = this.applyValidationErrors(nextErrors);
|
|
5744
|
+
this.finishValidation(cb, tableStore, changed);
|
|
5533
5745
|
}
|
|
5534
5746
|
scheduleAsyncCellCheck(cellId, valueKey, value, schema, caption, rowId) {
|
|
5535
5747
|
const seq = (this.asyncCellSeq.get(cellId) ?? 0) + 1;
|
|
@@ -5874,6 +6086,9 @@ async function openIndexedDbDatabase(dbName, storeNames, version = 1) {
|
|
|
5874
6086
|
request.onsuccess = () => resolve(request.result);
|
|
5875
6087
|
});
|
|
5876
6088
|
return {
|
|
6089
|
+
close() {
|
|
6090
|
+
db.close();
|
|
6091
|
+
},
|
|
5877
6092
|
objectStore(name) {
|
|
5878
6093
|
return {
|
|
5879
6094
|
async get(key) {
|
|
@@ -5925,6 +6140,8 @@ var IndexedDbEventStore = class _IndexedDbEventStore {
|
|
|
5925
6140
|
this.db = db;
|
|
5926
6141
|
this.listeners = /* @__PURE__ */ new Map();
|
|
5927
6142
|
this.globalListeners = /* @__PURE__ */ new Set();
|
|
6143
|
+
this.closed = false;
|
|
6144
|
+
this.inflight = /* @__PURE__ */ new Set();
|
|
5928
6145
|
this.ready = Promise.resolve();
|
|
5929
6146
|
}
|
|
5930
6147
|
static async open(dbName = DEFAULT_EVENT_STORE_PREFIX) {
|
|
@@ -5935,7 +6152,36 @@ var IndexedDbEventStore = class _IndexedDbEventStore {
|
|
|
5935
6152
|
static inMemory() {
|
|
5936
6153
|
return new _IndexedDbEventStore(new MemoryKvDatabase());
|
|
5937
6154
|
}
|
|
5938
|
-
|
|
6155
|
+
/**
|
|
6156
|
+
* Release the IndexedDB connection (stored events are untouched). Waits for
|
|
6157
|
+
* appends already in flight; appends started afterwards are dropped (they
|
|
6158
|
+
* resolve `ok` without writing) because the owning grid is gone. Idempotent.
|
|
6159
|
+
*/
|
|
6160
|
+
close() {
|
|
6161
|
+
if (!this.closePromise) {
|
|
6162
|
+
this.closed = true;
|
|
6163
|
+
this.closePromise = (async () => {
|
|
6164
|
+
await Promise.allSettled([...this.inflight]);
|
|
6165
|
+
this.listeners.clear();
|
|
6166
|
+
this.globalListeners.clear();
|
|
6167
|
+
this.db.close?.();
|
|
6168
|
+
})();
|
|
6169
|
+
}
|
|
6170
|
+
return this.closePromise;
|
|
6171
|
+
}
|
|
6172
|
+
append(streamId, events, expectedVersion) {
|
|
6173
|
+
if (this.closed) {
|
|
6174
|
+
return Promise.resolve({ ok: true, version: 0 });
|
|
6175
|
+
}
|
|
6176
|
+
const job = this.appendInternal(streamId, events, expectedVersion);
|
|
6177
|
+
this.inflight.add(job);
|
|
6178
|
+
const forget = () => {
|
|
6179
|
+
this.inflight.delete(job);
|
|
6180
|
+
};
|
|
6181
|
+
job.then(forget, forget);
|
|
6182
|
+
return job;
|
|
6183
|
+
}
|
|
6184
|
+
async appendInternal(streamId, events, expectedVersion) {
|
|
5939
6185
|
await this.ready;
|
|
5940
6186
|
const streamStore = this.db.objectStore(STREAMS);
|
|
5941
6187
|
const globalStore = this.db.objectStore(GLOBAL);
|
|
@@ -5975,11 +6221,13 @@ var IndexedDbEventStore = class _IndexedDbEventStore {
|
|
|
5975
6221
|
return { ok: true, version: record.events.length };
|
|
5976
6222
|
}
|
|
5977
6223
|
async read(streamId, fromVersion = 0) {
|
|
6224
|
+
if (this.closed) return [];
|
|
5978
6225
|
await this.ready;
|
|
5979
6226
|
const record = await this.db.objectStore(STREAMS).get(streamId);
|
|
5980
6227
|
return (record?.events ?? []).slice(fromVersion);
|
|
5981
6228
|
}
|
|
5982
6229
|
async readAll(fromPosition = 0) {
|
|
6230
|
+
if (this.closed) return [];
|
|
5983
6231
|
await this.ready;
|
|
5984
6232
|
const globalStore = this.db.objectStore(GLOBAL);
|
|
5985
6233
|
const keys = (await globalStore.getAllKeys()).map(Number).filter((n) => Number.isFinite(n)).sort((a, b) => a - b).filter((n) => n > fromPosition);
|
|
@@ -5991,6 +6239,7 @@ var IndexedDbEventStore = class _IndexedDbEventStore {
|
|
|
5991
6239
|
return events;
|
|
5992
6240
|
}
|
|
5993
6241
|
subscribe(streamId, onEvent) {
|
|
6242
|
+
if (this.closed) return () => void 0;
|
|
5994
6243
|
if (!this.listeners.has(streamId)) {
|
|
5995
6244
|
this.listeners.set(streamId, /* @__PURE__ */ new Set());
|
|
5996
6245
|
}
|
|
@@ -6001,6 +6250,7 @@ var IndexedDbEventStore = class _IndexedDbEventStore {
|
|
|
6001
6250
|
};
|
|
6002
6251
|
}
|
|
6003
6252
|
subscribeAll(onEvent) {
|
|
6253
|
+
if (this.closed) return () => void 0;
|
|
6004
6254
|
this.globalListeners.add(onEvent);
|
|
6005
6255
|
return () => {
|
|
6006
6256
|
this.globalListeners.delete(onEvent);
|
|
@@ -6049,6 +6299,8 @@ var OfflineStatus = class {
|
|
|
6049
6299
|
this.syncedIds = /* @__PURE__ */ new Set();
|
|
6050
6300
|
this.connectivityUnsub = null;
|
|
6051
6301
|
this.storeUnsub = null;
|
|
6302
|
+
/** Incremented by every stop(); invalidates an in-flight start(). */
|
|
6303
|
+
this.lifecycle = 0;
|
|
6052
6304
|
this.connectivityListeners = /* @__PURE__ */ new Set();
|
|
6053
6305
|
this.pendingListeners = /* @__PURE__ */ new Set();
|
|
6054
6306
|
this.online = options.connectivity.getOnline();
|
|
@@ -6056,11 +6308,14 @@ var OfflineStatus = class {
|
|
|
6056
6308
|
}
|
|
6057
6309
|
async start(eventStore) {
|
|
6058
6310
|
this.stop();
|
|
6311
|
+
const run2 = this.lifecycle;
|
|
6059
6312
|
this.connectivityUnsub = this.options.connectivity.subscribe((online) => {
|
|
6313
|
+
if (run2 !== this.lifecycle) return;
|
|
6060
6314
|
this.online = online;
|
|
6061
6315
|
this.emitConnectivity();
|
|
6062
6316
|
});
|
|
6063
6317
|
const past = await eventStore.readAll(0);
|
|
6318
|
+
if (run2 !== this.lifecycle) return;
|
|
6064
6319
|
for (const event of past) {
|
|
6065
6320
|
this.consider(event);
|
|
6066
6321
|
}
|
|
@@ -6069,7 +6324,14 @@ var OfflineStatus = class {
|
|
|
6069
6324
|
});
|
|
6070
6325
|
this.emitPending();
|
|
6071
6326
|
}
|
|
6327
|
+
/** Stop listening and drop all listeners. The instance is inert afterwards. */
|
|
6328
|
+
dispose() {
|
|
6329
|
+
this.stop();
|
|
6330
|
+
this.connectivityListeners.clear();
|
|
6331
|
+
this.pendingListeners.clear();
|
|
6332
|
+
}
|
|
6072
6333
|
stop() {
|
|
6334
|
+
this.lifecycle += 1;
|
|
6073
6335
|
this.connectivityUnsub?.();
|
|
6074
6336
|
this.connectivityUnsub = null;
|
|
6075
6337
|
this.storeUnsub?.();
|
|
@@ -6576,18 +6838,40 @@ var UITableController = class {
|
|
|
6576
6838
|
return this.syncPort;
|
|
6577
6839
|
}
|
|
6578
6840
|
setSyncPort(port) {
|
|
6841
|
+
if (this.releasePromise) {
|
|
6842
|
+
port?.dispose?.();
|
|
6843
|
+
return;
|
|
6844
|
+
}
|
|
6579
6845
|
this.syncPort = port;
|
|
6580
6846
|
}
|
|
6581
6847
|
getPresencePort() {
|
|
6582
6848
|
return this.presencePort;
|
|
6583
6849
|
}
|
|
6584
6850
|
setPresencePort(port) {
|
|
6851
|
+
if (this.releasePromise) {
|
|
6852
|
+
port?.dispose();
|
|
6853
|
+
return;
|
|
6854
|
+
}
|
|
6585
6855
|
this.presencePort = port;
|
|
6586
6856
|
}
|
|
6857
|
+
/**
|
|
6858
|
+
* Composition root hook: the callback that releases every resource the grid
|
|
6859
|
+
* created (subscriptions, projections, plugins, owned event store).
|
|
6860
|
+
* Run once by {@link releaseResources}.
|
|
6861
|
+
*/
|
|
6862
|
+
setResourceTeardown(teardown) {
|
|
6863
|
+
this.resourceTeardown = teardown;
|
|
6864
|
+
}
|
|
6865
|
+
/** True once resources were released (via releaseResources or dispose). */
|
|
6866
|
+
isReleased() {
|
|
6867
|
+
return this.releasePromise !== void 0;
|
|
6868
|
+
}
|
|
6587
6869
|
getPresencePeers() {
|
|
6588
6870
|
return this.presencePort?.getPeers() ?? [];
|
|
6589
6871
|
}
|
|
6590
6872
|
subscribePresencePeers(cb) {
|
|
6873
|
+
if (this.isReleased()) return () => {
|
|
6874
|
+
};
|
|
6591
6875
|
if (!this.presencePort) {
|
|
6592
6876
|
cb([]);
|
|
6593
6877
|
return () => {
|
|
@@ -6612,6 +6896,8 @@ var UITableController = class {
|
|
|
6612
6896
|
this.offlineStatus?.markSynced(eventIds);
|
|
6613
6897
|
}
|
|
6614
6898
|
subscribeConnectivity(cb) {
|
|
6899
|
+
if (this.isReleased()) return () => {
|
|
6900
|
+
};
|
|
6615
6901
|
if (!this.offlineStatus) {
|
|
6616
6902
|
cb("online");
|
|
6617
6903
|
return () => {
|
|
@@ -6620,6 +6906,8 @@ var UITableController = class {
|
|
|
6620
6906
|
return this.offlineStatus.subscribeConnectivity(cb);
|
|
6621
6907
|
}
|
|
6622
6908
|
subscribePendingChanges(cb) {
|
|
6909
|
+
if (this.isReleased()) return () => {
|
|
6910
|
+
};
|
|
6623
6911
|
if (!this.offlineStatus) {
|
|
6624
6912
|
cb([]);
|
|
6625
6913
|
return () => {
|
|
@@ -6637,6 +6925,8 @@ var UITableController = class {
|
|
|
6637
6925
|
return this.syncPort?.getOpenConflicts() ?? [];
|
|
6638
6926
|
}
|
|
6639
6927
|
subscribeSyncConflicts(cb) {
|
|
6928
|
+
if (this.isReleased()) return () => {
|
|
6929
|
+
};
|
|
6640
6930
|
if (!this.syncPort) {
|
|
6641
6931
|
cb([]);
|
|
6642
6932
|
return () => {
|
|
@@ -6645,10 +6935,11 @@ var UITableController = class {
|
|
|
6645
6935
|
return this.syncPort.subscribeConflicts(cb);
|
|
6646
6936
|
}
|
|
6647
6937
|
async syncNow() {
|
|
6648
|
-
if (!this.syncPort) return null;
|
|
6938
|
+
if (this.isReleased() || !this.syncPort) return null;
|
|
6649
6939
|
return this.syncPort.sync();
|
|
6650
6940
|
}
|
|
6651
6941
|
async resolveSyncConflict(conflictId, choice) {
|
|
6942
|
+
if (this.isReleased()) return;
|
|
6652
6943
|
await this.syncPort?.resolveConflict(conflictId, choice);
|
|
6653
6944
|
}
|
|
6654
6945
|
/** Apply a remote cell value (used by SyncPort; dual-writes via engine). */
|
|
@@ -6697,24 +6988,17 @@ var UITableController = class {
|
|
|
6697
6988
|
changePage(page) {
|
|
6698
6989
|
this.engine.dispatch({ type: "CHANGE_PAGE", store: this.store, tableKey: this.tableKey, page });
|
|
6699
6990
|
}
|
|
6991
|
+
/** Editor of this cell → session draft (written per `cellEditCommit`); otherwise write-through. */
|
|
6700
6992
|
onCellChange(rowId, columnId, value) {
|
|
6701
|
-
|
|
6702
|
-
this.engine.patchCellEdit(rowId, columnId, { value });
|
|
6703
|
-
return;
|
|
6704
|
-
}
|
|
6705
|
-
this.engine.dispatch({ type: "CHANGE_CELL_VALUE", store: this.store, tableKey: this.tableKey, rowId, columnId, newValue: value });
|
|
6993
|
+
return this.engine.inputCellValue(rowId, columnId, value);
|
|
6706
6994
|
}
|
|
6707
6995
|
onDescriptionSave(rowId, flag) {
|
|
6708
6996
|
this.engine.dispatch({ type: "SAVE_DESCRIPTION", store: this.store, tableKey: this.tableKey, rowId, flag });
|
|
6709
6997
|
}
|
|
6710
6998
|
onCellDisplayChange(rowId, columnId, value) {
|
|
6711
|
-
|
|
6712
|
-
this.engine.patchCellEdit(rowId, columnId, { display: value });
|
|
6713
|
-
return;
|
|
6714
|
-
}
|
|
6715
|
-
this.engine.dispatch({ type: "CHANGE_CELL_DISPLAY_VALUE", store: this.store, tableKey: this.tableKey, rowId, columnId, newValue: value });
|
|
6999
|
+
return this.engine.inputCellDisplay(rowId, columnId, value);
|
|
6716
7000
|
}
|
|
6717
|
-
setActiveCell(rowId, columnId) {
|
|
7001
|
+
async setActiveCell(rowId, columnId) {
|
|
6718
7002
|
const prev = this.engine.getActiveCell();
|
|
6719
7003
|
if (prev?.rowId === rowId && prev?.columnId === columnId) {
|
|
6720
7004
|
if (this.engine.getCellEditOptions().singleClickEdit && !this.engine.getCellEdit()) {
|
|
@@ -6731,14 +7015,14 @@ var UITableController = class {
|
|
|
6731
7015
|
rowId
|
|
6732
7016
|
});
|
|
6733
7017
|
}
|
|
6734
|
-
this.engine.dispatch({ type: "ACTIVE_CELL", tableKey: this.tableKey, rowId, columnId });
|
|
6735
7018
|
this.publishPresenceCell(rowId, columnId);
|
|
7019
|
+
await this.engine.dispatch({ type: "ACTIVE_CELL", tableKey: this.tableKey, rowId, columnId });
|
|
6736
7020
|
}
|
|
6737
7021
|
setActiveRow(rowId) {
|
|
6738
7022
|
this.engine.dispatch({ type: "ACTIVE_ROW", store: this.store, tableKey: this.tableKey, rowId });
|
|
6739
7023
|
}
|
|
6740
7024
|
moveActiveCellVertical(rowId, columnId, direction) {
|
|
6741
|
-
this.engine.dispatch({ type: "MOVE_ACTIVE_CELL_VERTICAL", store: this.store, tableKey: this.tableKey, rowId, columnId, direction });
|
|
7025
|
+
return this.engine.dispatch({ type: "MOVE_ACTIVE_CELL_VERTICAL", store: this.store, tableKey: this.tableKey, rowId, columnId, direction });
|
|
6742
7026
|
}
|
|
6743
7027
|
reorderRow(draggedRowId, droppedRowId, position) {
|
|
6744
7028
|
this.engine.dispatch({ type: "ROW_REORDERED", store: this.store, tableKey: this.tableKey, draggedRowId, droppedRowId, position });
|
|
@@ -6814,7 +7098,7 @@ var UITableController = class {
|
|
|
6814
7098
|
this.engine.dispatch({ type: "ACTIVATE_FIRST_CELL", tableKey: this.tableKey, rowId });
|
|
6815
7099
|
}
|
|
6816
7100
|
moveToNextCell(rowId, columnId, direction = "next") {
|
|
6817
|
-
this.engine.dispatch({ type: "MOVE_ACTIVE_CELL", store: this.store, tableKey: this.tableKey, rowId, columnId, direction });
|
|
7101
|
+
return this.engine.dispatch({ type: "MOVE_ACTIVE_CELL", store: this.store, tableKey: this.tableKey, rowId, columnId, direction });
|
|
6818
7102
|
}
|
|
6819
7103
|
async setTableAction(action) {
|
|
6820
7104
|
await this.engine.dispatch({ type: "SET_TABLE_ACTION", store: this.store, tableKey: this.tableKey, action });
|
|
@@ -7082,7 +7366,7 @@ var UITableController = class {
|
|
|
7082
7366
|
) ?? 0;
|
|
7083
7367
|
}
|
|
7084
7368
|
subscribeChangelog(cb, filter = {}) {
|
|
7085
|
-
if (!this.changelogProjection) return () => {
|
|
7369
|
+
if (!this.changelogProjection || this.isReleased()) return () => {
|
|
7086
7370
|
};
|
|
7087
7371
|
return this.safe(
|
|
7088
7372
|
() => this.changelogProjection.subscribe(cb, { tableId: this.tableKey, ...filter }),
|
|
@@ -7105,7 +7389,7 @@ var UITableController = class {
|
|
|
7105
7389
|
) ?? 0;
|
|
7106
7390
|
}
|
|
7107
7391
|
subscribeHistoryItems(cb, filter = {}) {
|
|
7108
|
-
if (!this.historyPanelViewModel) return () => {
|
|
7392
|
+
if (!this.historyPanelViewModel || this.isReleased()) return () => {
|
|
7109
7393
|
};
|
|
7110
7394
|
return this.safe(
|
|
7111
7395
|
() => this.historyPanelViewModel.subscribe(cb, { tableId: this.tableKey, ...filter }),
|
|
@@ -7178,6 +7462,40 @@ var UITableController = class {
|
|
|
7178
7462
|
commitCellEdit() {
|
|
7179
7463
|
return this.safe(() => this.engine.commitCellEdit(), "commitCellEdit") ?? Promise.resolve(0);
|
|
7180
7464
|
}
|
|
7465
|
+
/**
|
|
7466
|
+
* Write what is still in the cell editor (the edit stays open) and wait
|
|
7467
|
+
* until every pending cell write is durable. `getFullSnapShot` /
|
|
7468
|
+
* `iterateRowsFromDb` / exports already do this; call it before reading
|
|
7469
|
+
* synchronous APIs (`getRowView`, `getSnapShot`) for a save.
|
|
7470
|
+
*/
|
|
7471
|
+
flushCellEdit() {
|
|
7472
|
+
return this.engine.flushCellEdit().catch((error) => {
|
|
7473
|
+
this.audit.log({
|
|
7474
|
+
type: "ERROR",
|
|
7475
|
+
message: "UITableController.flushCellEdit failed",
|
|
7476
|
+
payload: { error, tableKey: this.tableKey }
|
|
7477
|
+
});
|
|
7478
|
+
});
|
|
7479
|
+
}
|
|
7480
|
+
/** DataGrid: focus / pointer left the grid (see `stopEditingWhenCellsLoseFocus`). */
|
|
7481
|
+
leaveGridFocus() {
|
|
7482
|
+
return this.engine.leaveGridFocus().catch((error) => {
|
|
7483
|
+
this.audit.log({
|
|
7484
|
+
type: "ERROR",
|
|
7485
|
+
message: "UITableController.leaveGridFocus failed",
|
|
7486
|
+
payload: { error, tableKey: this.tableKey }
|
|
7487
|
+
});
|
|
7488
|
+
});
|
|
7489
|
+
}
|
|
7490
|
+
settleEditsForTeardown() {
|
|
7491
|
+
return this.engine.settleEditsForTeardown().catch((error) => {
|
|
7492
|
+
this.audit.log({
|
|
7493
|
+
type: "ERROR",
|
|
7494
|
+
message: "UITableController: committing the open edit before teardown failed",
|
|
7495
|
+
payload: { error, tableKey: this.tableKey }
|
|
7496
|
+
});
|
|
7497
|
+
});
|
|
7498
|
+
}
|
|
7181
7499
|
getEditDraft(rowId, columnId) {
|
|
7182
7500
|
return this.safe(
|
|
7183
7501
|
() => this.engine.getEditDraft(rowId, columnId),
|
|
@@ -7298,12 +7616,68 @@ var UITableController = class {
|
|
|
7298
7616
|
this.engine.addCellRange(range);
|
|
7299
7617
|
}
|
|
7300
7618
|
// ─── lifecycle ───────────────────────────────────────────────────────
|
|
7619
|
+
/**
|
|
7620
|
+
* Full dispose: `TABLE_DISPOSED` (windowed repo: drop the RAM page window,
|
|
7621
|
+
* other repos: `repo.delete` — unchanged data semantics) followed by
|
|
7622
|
+
* {@link releaseResources}. Idempotent; the promise settles once teardown
|
|
7623
|
+
* finished and never rejects.
|
|
7624
|
+
*/
|
|
7301
7625
|
dispose() {
|
|
7302
|
-
if (this.disposed) return;
|
|
7626
|
+
if (this.disposed) return this.releasePromise ?? this.releaseResources();
|
|
7303
7627
|
this.disposed = true;
|
|
7304
7628
|
this.presencePort?.dispose();
|
|
7305
7629
|
this.presencePort = void 0;
|
|
7306
|
-
|
|
7630
|
+
const dispatched = this.settleEditsForTeardown().then(
|
|
7631
|
+
() => this.engine.dispatch({ type: "TABLE_DISPOSED", store: this.store, tableKey: this.tableKey })
|
|
7632
|
+
).catch((error) => {
|
|
7633
|
+
this.audit.log({
|
|
7634
|
+
type: "ERROR",
|
|
7635
|
+
message: "UITableController.dispose: TABLE_DISPOSED failed",
|
|
7636
|
+
payload: { error, tableKey: this.tableKey }
|
|
7637
|
+
});
|
|
7638
|
+
});
|
|
7639
|
+
return dispatched.then(() => this.releaseResources());
|
|
7640
|
+
}
|
|
7641
|
+
/**
|
|
7642
|
+
* Resource-only teardown: stops subscriptions, projections, sync, presence,
|
|
7643
|
+
* plugins, server row model and closes an event store the grid opened.
|
|
7644
|
+
* Does NOT dispatch `TABLE_DISPOSED` — persisted table data is untouched.
|
|
7645
|
+
* Idempotent (same promise on every call); never rejects.
|
|
7646
|
+
*/
|
|
7647
|
+
releaseResources() {
|
|
7648
|
+
if (!this.releasePromise) {
|
|
7649
|
+
this.releasePromise = this.runResourceTeardown();
|
|
7650
|
+
}
|
|
7651
|
+
return this.releasePromise;
|
|
7652
|
+
}
|
|
7653
|
+
async runResourceTeardown() {
|
|
7654
|
+
const fail = (what, error) => {
|
|
7655
|
+
this.audit.log({
|
|
7656
|
+
type: "ERROR",
|
|
7657
|
+
message: `UITableController.releaseResources: ${what} failed`,
|
|
7658
|
+
payload: { error, tableKey: this.tableKey }
|
|
7659
|
+
});
|
|
7660
|
+
};
|
|
7661
|
+
await this.settleEditsForTeardown();
|
|
7662
|
+
const presence = this.presencePort;
|
|
7663
|
+
const sync = this.syncPort;
|
|
7664
|
+
this.presencePort = void 0;
|
|
7665
|
+
this.syncPort = void 0;
|
|
7666
|
+
try {
|
|
7667
|
+
presence?.dispose();
|
|
7668
|
+
} catch (error) {
|
|
7669
|
+
fail("presence dispose", error);
|
|
7670
|
+
}
|
|
7671
|
+
try {
|
|
7672
|
+
sync?.dispose?.();
|
|
7673
|
+
} catch (error) {
|
|
7674
|
+
fail("sync dispose", error);
|
|
7675
|
+
}
|
|
7676
|
+
try {
|
|
7677
|
+
await this.resourceTeardown?.();
|
|
7678
|
+
} catch (error) {
|
|
7679
|
+
fail("teardown", error);
|
|
7680
|
+
}
|
|
7307
7681
|
}
|
|
7308
7682
|
// ─── main dispatch ───────────────────────────────────────────────────
|
|
7309
7683
|
async dispatch(command) {
|
|
@@ -7327,13 +7701,13 @@ var UITableController = class {
|
|
|
7327
7701
|
this.changePage(command.page);
|
|
7328
7702
|
return;
|
|
7329
7703
|
case "UI_CELL_CHANGE":
|
|
7330
|
-
this.onCellChange(command.rowId, command.columnId, command.value);
|
|
7704
|
+
await this.onCellChange(command.rowId, command.columnId, command.value);
|
|
7331
7705
|
return;
|
|
7332
7706
|
case "UI_DESCRIPTION_SAVE":
|
|
7333
7707
|
this.onDescriptionSave(command.rowId, command.flag);
|
|
7334
7708
|
return;
|
|
7335
7709
|
case "UI_CELL_CHANGE_DISPLAY":
|
|
7336
|
-
this.onCellDisplayChange(command.rowId, command.columnId, command.value);
|
|
7710
|
+
await this.onCellDisplayChange(command.rowId, command.columnId, command.value);
|
|
7337
7711
|
return;
|
|
7338
7712
|
case "ADD_EMPTY_ROW":
|
|
7339
7713
|
await this.addEmptyRow();
|
|
@@ -7373,13 +7747,13 @@ var UITableController = class {
|
|
|
7373
7747
|
shiftKey: Boolean(command.shiftKey),
|
|
7374
7748
|
ctrlKey: Boolean(command.ctrlKey)
|
|
7375
7749
|
});
|
|
7376
|
-
this.setActiveCell(command.rowId, command.columnId);
|
|
7750
|
+
await this.setActiveCell(command.rowId, command.columnId);
|
|
7377
7751
|
return;
|
|
7378
7752
|
case "UI_MOVE_ACTIVE_CELL":
|
|
7379
|
-
this.moveToNextCell(command.rowId, command.columnId, command.direction);
|
|
7753
|
+
await this.moveToNextCell(command.rowId, command.columnId, command.direction);
|
|
7380
7754
|
return;
|
|
7381
7755
|
case "UI_MOVE_ACTIVE_CELL_VERTICAL":
|
|
7382
|
-
this.moveActiveCellVertical(command.rowId, command.columnId, command.direction);
|
|
7756
|
+
await this.moveActiveCellVertical(command.rowId, command.columnId, command.direction);
|
|
7383
7757
|
return;
|
|
7384
7758
|
case "UI_ACTIVE_ROW":
|
|
7385
7759
|
this.setActiveRow(command.rowId);
|
|
@@ -7594,6 +7968,7 @@ var PluginHost = class {
|
|
|
7594
7968
|
return this.plugins.some((p) => p.name === pluginName);
|
|
7595
7969
|
}
|
|
7596
7970
|
async requestExport(options) {
|
|
7971
|
+
await this.deps.beforeRead?.();
|
|
7597
7972
|
const bus = this.createBus();
|
|
7598
7973
|
const correlationId = options.correlationId ?? createEventId();
|
|
7599
7974
|
const pluginName = options.format === "pdf" ? "pdf-export" : options.format === "csv" ? "csv-export" : "excel-export";
|
|
@@ -8079,6 +8454,40 @@ var ConsoleAuditLogger = class {
|
|
|
8079
8454
|
}
|
|
8080
8455
|
};
|
|
8081
8456
|
|
|
8457
|
+
// infrastructure/eventStore/trackedEventStore.ts
|
|
8458
|
+
function trackEventStoreSubscriptions(inner) {
|
|
8459
|
+
const open = /* @__PURE__ */ new Set();
|
|
8460
|
+
let released = false;
|
|
8461
|
+
const track = (subscribe) => {
|
|
8462
|
+
if (released) return () => void 0;
|
|
8463
|
+
const raw = subscribe();
|
|
8464
|
+
let done = false;
|
|
8465
|
+
const unsub = () => {
|
|
8466
|
+
if (done) return;
|
|
8467
|
+
done = true;
|
|
8468
|
+
open.delete(unsub);
|
|
8469
|
+
raw();
|
|
8470
|
+
};
|
|
8471
|
+
open.add(unsub);
|
|
8472
|
+
return unsub;
|
|
8473
|
+
};
|
|
8474
|
+
const store = {
|
|
8475
|
+
append: (streamId, events, expectedVersion) => inner.append(streamId, events, expectedVersion),
|
|
8476
|
+
read: (streamId, fromVersion) => inner.read(streamId, fromVersion),
|
|
8477
|
+
readAll: (fromPosition) => inner.readAll(fromPosition),
|
|
8478
|
+
subscribe: (streamId, onEvent) => track(() => inner.subscribe(streamId, onEvent)),
|
|
8479
|
+
subscribeAll: (onEvent) => track(() => inner.subscribeAll(onEvent))
|
|
8480
|
+
};
|
|
8481
|
+
return {
|
|
8482
|
+
store,
|
|
8483
|
+
release() {
|
|
8484
|
+
released = true;
|
|
8485
|
+
for (const unsub of [...open]) unsub();
|
|
8486
|
+
open.clear();
|
|
8487
|
+
}
|
|
8488
|
+
};
|
|
8489
|
+
}
|
|
8490
|
+
|
|
8082
8491
|
// infrastructure/history/HistoryPanelViewModel.ts
|
|
8083
8492
|
var HISTORY_CLASSIFICATIONS = {
|
|
8084
8493
|
CELL_CHANGED: { category: "data", severity: "info" },
|
|
@@ -8290,6 +8699,8 @@ var ChangelogProjection = class {
|
|
|
8290
8699
|
this.subscribers = /* @__PURE__ */ new Set();
|
|
8291
8700
|
this.seenEventIds = /* @__PURE__ */ new Set();
|
|
8292
8701
|
this.started = false;
|
|
8702
|
+
/** Incremented by start() and stop(); invalidates an in-flight catch-up. */
|
|
8703
|
+
this.run = 0;
|
|
8293
8704
|
}
|
|
8294
8705
|
/**
|
|
8295
8706
|
* Catch up via readAll, then subscribe for live events.
|
|
@@ -8303,17 +8714,25 @@ var ChangelogProjection = class {
|
|
|
8303
8714
|
this.seenEventIds.add(event.eventId);
|
|
8304
8715
|
this.project(event);
|
|
8305
8716
|
};
|
|
8717
|
+
const run2 = ++this.run;
|
|
8306
8718
|
this.unsubscribe = this.eventStore.subscribeAll(projectOnce);
|
|
8307
8719
|
const past = await this.eventStore.readAll(0);
|
|
8720
|
+
if (run2 !== this.run) return;
|
|
8308
8721
|
for (const event of past) {
|
|
8309
8722
|
projectOnce(event);
|
|
8310
8723
|
}
|
|
8311
8724
|
}
|
|
8312
8725
|
stop() {
|
|
8726
|
+
this.run += 1;
|
|
8313
8727
|
this.unsubscribe?.();
|
|
8314
8728
|
this.unsubscribe = null;
|
|
8315
8729
|
this.started = false;
|
|
8316
8730
|
}
|
|
8731
|
+
/** Stop and drop all subscribers (grid teardown). Entries stay readable. */
|
|
8732
|
+
dispose() {
|
|
8733
|
+
this.stop();
|
|
8734
|
+
this.subscribers.clear();
|
|
8735
|
+
}
|
|
8317
8736
|
query(filter = {}) {
|
|
8318
8737
|
let result = this.entries;
|
|
8319
8738
|
if (filter.tableId) {
|
|
@@ -8895,6 +9314,33 @@ function isCellEditorTarget(target) {
|
|
|
8895
9314
|
if (!editor) return false;
|
|
8896
9315
|
return Boolean(editor.closest('[role="gridcell"], [data-erp-cell-textarea]'));
|
|
8897
9316
|
}
|
|
9317
|
+
var CELL_SELECTOR = '[role="gridcell"], [data-erp-cell-textarea]';
|
|
9318
|
+
function isGridCellTarget(target) {
|
|
9319
|
+
if (!target || !(target instanceof Element)) return false;
|
|
9320
|
+
if (target.closest('[role="menu"], [role="dialog"], .erp-table-modal')) {
|
|
9321
|
+
return false;
|
|
9322
|
+
}
|
|
9323
|
+
return Boolean(target.closest(CELL_SELECTOR));
|
|
9324
|
+
}
|
|
9325
|
+
var TEXT_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
9326
|
+
"",
|
|
9327
|
+
"text",
|
|
9328
|
+
"search",
|
|
9329
|
+
"number",
|
|
9330
|
+
"tel",
|
|
9331
|
+
"url",
|
|
9332
|
+
"email",
|
|
9333
|
+
"password"
|
|
9334
|
+
]);
|
|
9335
|
+
function isTextEditorTarget(target) {
|
|
9336
|
+
if (!isCellEditorTarget(target)) return false;
|
|
9337
|
+
const el = target;
|
|
9338
|
+
if (el.isContentEditable || el.getAttribute("contenteditable") === "true") return true;
|
|
9339
|
+
const tag = el.tagName;
|
|
9340
|
+
if (tag === "TEXTAREA") return true;
|
|
9341
|
+
if (tag !== "INPUT") return false;
|
|
9342
|
+
return TEXT_INPUT_TYPES.has((el.getAttribute("type") ?? "").toLowerCase());
|
|
9343
|
+
}
|
|
8898
9344
|
function closestGridRoot(target) {
|
|
8899
9345
|
if (!target || !(target instanceof Element)) return null;
|
|
8900
9346
|
return target.closest('[role="grid"], [role="treegrid"]');
|
|
@@ -8949,6 +9395,13 @@ var UITableKeyboardHandler = class {
|
|
|
8949
9395
|
setPasteCells(handler) {
|
|
8950
9396
|
this.pasteCells = handler;
|
|
8951
9397
|
}
|
|
9398
|
+
/** More than one cell selected (Shift+Arrow / drag): clipboard keys act on the grid. */
|
|
9399
|
+
hasMultiCellRange() {
|
|
9400
|
+
const ranges = this.engine.getCellRanges();
|
|
9401
|
+
if (ranges.length > 1) return true;
|
|
9402
|
+
const range = ranges[0];
|
|
9403
|
+
return Boolean(range && (range.startRow !== range.endRow || range.colIds.length > 1));
|
|
9404
|
+
}
|
|
8952
9405
|
async handle(e, ctx2) {
|
|
8953
9406
|
try {
|
|
8954
9407
|
await this.handleInternal(e, ctx2);
|
|
@@ -8968,6 +9421,8 @@ var UITableKeyboardHandler = class {
|
|
|
8968
9421
|
const { activeColumnId } = ctx2;
|
|
8969
9422
|
const selectedRows = this.engine.getSelectedRows();
|
|
8970
9423
|
const activeRowId = ctx2.activeRowId ?? this.engine.getActiveRow() ?? (selectedRows ? Number(Object.keys(selectedRows).find((id) => selectedRows[Number(id)])) || null : null);
|
|
9424
|
+
const inTextEditor = isTextEditorTarget(e.target);
|
|
9425
|
+
const clipboardToEditor = inTextEditor && !this.hasMultiCellRange();
|
|
8971
9426
|
switch (code) {
|
|
8972
9427
|
case "KeyN": {
|
|
8973
9428
|
if (altKey) {
|
|
@@ -8999,7 +9454,7 @@ var UITableKeyboardHandler = class {
|
|
|
8999
9454
|
});
|
|
9000
9455
|
return;
|
|
9001
9456
|
}
|
|
9002
|
-
if (!ctrlKey && !shiftKey && !altKey && activeRowId && activeColumnId) {
|
|
9457
|
+
if (!ctrlKey && !shiftKey && !altKey && !inTextEditor && activeRowId && activeColumnId) {
|
|
9003
9458
|
e.preventDefault();
|
|
9004
9459
|
await this.dispatchIntent({
|
|
9005
9460
|
type: "JUMP_ACTIVE_CELL_ROW_EDGE",
|
|
@@ -9033,7 +9488,7 @@ var UITableKeyboardHandler = class {
|
|
|
9033
9488
|
});
|
|
9034
9489
|
return;
|
|
9035
9490
|
}
|
|
9036
|
-
if (!ctrlKey && !shiftKey && !altKey && activeRowId && activeColumnId) {
|
|
9491
|
+
if (!ctrlKey && !shiftKey && !altKey && !inTextEditor && activeRowId && activeColumnId) {
|
|
9037
9492
|
e.preventDefault();
|
|
9038
9493
|
await this.dispatchIntent({
|
|
9039
9494
|
type: "JUMP_ACTIVE_CELL_ROW_EDGE",
|
|
@@ -9061,28 +9516,28 @@ var UITableKeyboardHandler = class {
|
|
|
9061
9516
|
type: "ACTIVATE_FIRST_CELL",
|
|
9062
9517
|
rowId: activeRowId
|
|
9063
9518
|
});
|
|
9064
|
-
} else if (this.engine.getCellEdit()) {
|
|
9519
|
+
} else if (!this.engine.getCellEdit() && !this.engine.getCellEditOptions().singleClickEdit) {
|
|
9520
|
+
this.engine.startCellEdit(activeRowId, activeColumnId);
|
|
9521
|
+
} else if (this.engine.getCellEditOptions().enterNavigation === "down") {
|
|
9065
9522
|
await this.dispatchIntent({
|
|
9066
9523
|
type: "MOVE_ACTIVE_CELL_VERTICAL",
|
|
9067
9524
|
rowId: activeRowId,
|
|
9068
9525
|
columnId: activeColumnId,
|
|
9069
9526
|
direction: shiftKey ? "up" : "down"
|
|
9070
9527
|
});
|
|
9071
|
-
} else if (!this.engine.getCellEditOptions().singleClickEdit) {
|
|
9072
|
-
this.engine.startCellEdit(activeRowId, activeColumnId);
|
|
9073
9528
|
} else {
|
|
9074
9529
|
await this.dispatchIntent({
|
|
9075
|
-
type: "
|
|
9530
|
+
type: "MOVE_ACTIVE_CELL",
|
|
9076
9531
|
rowId: activeRowId,
|
|
9077
9532
|
columnId: activeColumnId,
|
|
9078
|
-
direction: shiftKey ? "
|
|
9533
|
+
direction: shiftKey ? "prev" : "next"
|
|
9079
9534
|
});
|
|
9080
9535
|
}
|
|
9081
9536
|
}
|
|
9082
9537
|
return;
|
|
9083
9538
|
}
|
|
9084
9539
|
case "Tab": {
|
|
9085
|
-
if (!
|
|
9540
|
+
if (!isGridCellTarget(e.target)) {
|
|
9086
9541
|
return;
|
|
9087
9542
|
}
|
|
9088
9543
|
if (activeRowId && activeColumnId) {
|
|
@@ -9272,7 +9727,7 @@ var UITableKeyboardHandler = class {
|
|
|
9272
9727
|
return;
|
|
9273
9728
|
}
|
|
9274
9729
|
case "KeyA": {
|
|
9275
|
-
if (ctrlKey) {
|
|
9730
|
+
if (ctrlKey && !inTextEditor) {
|
|
9276
9731
|
e.preventDefault();
|
|
9277
9732
|
await this.dispatchIntent({ type: "SELECT_ALL_CELLS" });
|
|
9278
9733
|
}
|
|
@@ -9280,6 +9735,7 @@ var UITableKeyboardHandler = class {
|
|
|
9280
9735
|
}
|
|
9281
9736
|
case "KeyC": {
|
|
9282
9737
|
if (ctrlKey && !altKey) {
|
|
9738
|
+
if (clipboardToEditor) return;
|
|
9283
9739
|
e.preventDefault();
|
|
9284
9740
|
if (this.copyCells) {
|
|
9285
9741
|
await this.copyCells();
|
|
@@ -9294,6 +9750,7 @@ var UITableKeyboardHandler = class {
|
|
|
9294
9750
|
}
|
|
9295
9751
|
case "KeyX": {
|
|
9296
9752
|
if (ctrlKey && !altKey) {
|
|
9753
|
+
if (clipboardToEditor) return;
|
|
9297
9754
|
e.preventDefault();
|
|
9298
9755
|
if (this.cutCells) {
|
|
9299
9756
|
await this.cutCells();
|
|
@@ -9308,6 +9765,7 @@ var UITableKeyboardHandler = class {
|
|
|
9308
9765
|
}
|
|
9309
9766
|
case "KeyV": {
|
|
9310
9767
|
if (ctrlKey && !altKey) {
|
|
9768
|
+
if (clipboardToEditor) return;
|
|
9311
9769
|
e.preventDefault();
|
|
9312
9770
|
if (this.pasteCells) {
|
|
9313
9771
|
await this.pasteCells();
|
|
@@ -9358,6 +9816,7 @@ var UITableKeyboardHandler = class {
|
|
|
9358
9816
|
return;
|
|
9359
9817
|
}
|
|
9360
9818
|
case "KeyZ": {
|
|
9819
|
+
if (inTextEditor) return;
|
|
9361
9820
|
if (ctrlKey && !shiftKey) {
|
|
9362
9821
|
e.preventDefault();
|
|
9363
9822
|
await this.dispatchIntent({ type: "UNDO" });
|
|
@@ -9370,7 +9829,7 @@ var UITableKeyboardHandler = class {
|
|
|
9370
9829
|
return;
|
|
9371
9830
|
}
|
|
9372
9831
|
case "KeyY": {
|
|
9373
|
-
if (ctrlKey) {
|
|
9832
|
+
if (ctrlKey && !inTextEditor) {
|
|
9374
9833
|
e.preventDefault();
|
|
9375
9834
|
await this.dispatchIntent({ type: "REDO" });
|
|
9376
9835
|
}
|
|
@@ -11048,14 +11507,14 @@ function createPermissionPolicy(config, columnMeta, table, repo, audit) {
|
|
|
11048
11507
|
};
|
|
11049
11508
|
}
|
|
11050
11509
|
function createTableAppService(repo, audit, permissionPolicy, { columnMeta, remoteApi }, eventStore) {
|
|
11051
|
-
const changeCellHandler = new
|
|
11052
|
-
const applyDynamicProjection = new
|
|
11510
|
+
const changeCellHandler = new chunk52LFOPXD_cjs.ChangeCellValueHandler(repo, audit, permissionPolicy, { columnMeta, remoteApi });
|
|
11511
|
+
const applyDynamicProjection = new chunk52LFOPXD_cjs.ApplyDynamicProjectionHandler(repo, audit, permissionPolicy, { columnMeta, remoteApi });
|
|
11053
11512
|
let rowVisibilityHandler;
|
|
11054
|
-
const applyRowVisibility = () => rowVisibilityHandler ?? (rowVisibilityHandler = import('./applyRowVisibilityHandler-
|
|
11513
|
+
const applyRowVisibility = () => rowVisibilityHandler ?? (rowVisibilityHandler = import('./applyRowVisibilityHandler-Q64ZFC7A.cjs').then(
|
|
11055
11514
|
(m) => new m.ApplyRowVisibilityHandler(repo, audit, permissionPolicy, { columnMeta, remoteApi })
|
|
11056
11515
|
));
|
|
11057
|
-
const changeCellDisplayHandler = new
|
|
11058
|
-
const saveDescriptionHandler = new
|
|
11516
|
+
const changeCellDisplayHandler = new chunk52LFOPXD_cjs.ChangeCellDisplayValueHandler(repo, audit, permissionPolicy);
|
|
11517
|
+
const saveDescriptionHandler = new chunk52LFOPXD_cjs.SaveDescriptionHandler(repo, audit, permissionPolicy);
|
|
11059
11518
|
const addNewRowHandler = new AddNewRowCommandHandler(repo, audit, permissionPolicy);
|
|
11060
11519
|
const addNewRowsHandler = new AddNewRowsCommandHandler(repo, audit, permissionPolicy);
|
|
11061
11520
|
const duplicateRowHandler = new DuplicateRowCommandHandler(repo, audit, permissionPolicy);
|
|
@@ -11108,14 +11567,39 @@ function createTableAppService(repo, audit, permissionPolicy, { columnMeta, remo
|
|
|
11108
11567
|
|
|
11109
11568
|
// bootstrap/index.ts
|
|
11110
11569
|
async function resolveEventStore(config, persist) {
|
|
11111
|
-
if (config.eventStore) return config.eventStore;
|
|
11112
|
-
if (config.persistence === "paged-idb")
|
|
11570
|
+
if (config.eventStore) return { eventStore: config.eventStore };
|
|
11571
|
+
if (config.persistence === "paged-idb") {
|
|
11572
|
+
return { eventStore: new InMemoryEventStore() };
|
|
11573
|
+
}
|
|
11113
11574
|
if (persist && typeof indexedDB !== "undefined") {
|
|
11114
|
-
|
|
11575
|
+
const opened = await IndexedDbEventStore.open(
|
|
11115
11576
|
eventStoreDbName(config.store, config.eventStoreName)
|
|
11116
11577
|
);
|
|
11578
|
+
return { eventStore: opened, close: () => opened.close() };
|
|
11117
11579
|
}
|
|
11118
|
-
return new InMemoryEventStore();
|
|
11580
|
+
return { eventStore: new InMemoryEventStore() };
|
|
11581
|
+
}
|
|
11582
|
+
function createDisposerRegistry() {
|
|
11583
|
+
const disposers = [];
|
|
11584
|
+
let running;
|
|
11585
|
+
return {
|
|
11586
|
+
add(disposer) {
|
|
11587
|
+
disposers.push(disposer);
|
|
11588
|
+
},
|
|
11589
|
+
run() {
|
|
11590
|
+
if (!running) {
|
|
11591
|
+
running = (async () => {
|
|
11592
|
+
for (const disposer of disposers.splice(0).reverse()) {
|
|
11593
|
+
try {
|
|
11594
|
+
await disposer();
|
|
11595
|
+
} catch {
|
|
11596
|
+
}
|
|
11597
|
+
}
|
|
11598
|
+
})();
|
|
11599
|
+
}
|
|
11600
|
+
return running;
|
|
11601
|
+
}
|
|
11602
|
+
};
|
|
11119
11603
|
}
|
|
11120
11604
|
function createInitialRows(collectionColumns) {
|
|
11121
11605
|
const rows = [];
|
|
@@ -11147,6 +11631,15 @@ function resolveHostRows(config, columns) {
|
|
|
11147
11631
|
);
|
|
11148
11632
|
}
|
|
11149
11633
|
async function assembleGrid(config) {
|
|
11634
|
+
const registry = createDisposerRegistry();
|
|
11635
|
+
try {
|
|
11636
|
+
return await assembleGridInner(config, registry);
|
|
11637
|
+
} catch (error) {
|
|
11638
|
+
await registry.run();
|
|
11639
|
+
throw error;
|
|
11640
|
+
}
|
|
11641
|
+
}
|
|
11642
|
+
async function assembleGridInner(config, registry) {
|
|
11150
11643
|
const { store, tableKey, actor, persist } = resolveCreateGridDefaults(config);
|
|
11151
11644
|
const resolved = {
|
|
11152
11645
|
...config,
|
|
@@ -11162,8 +11655,14 @@ async function assembleGrid(config) {
|
|
|
11162
11655
|
const windowed = isWindowedRepository(repo);
|
|
11163
11656
|
const audit = config.audit ?? new ConsoleAuditLogger();
|
|
11164
11657
|
const remoteApi = config.remoteApi ?? new NoopRemoteApi();
|
|
11165
|
-
const
|
|
11166
|
-
const
|
|
11658
|
+
const resolvedStore = await resolveEventStore(resolved, persist);
|
|
11659
|
+
const { eventStore } = resolvedStore;
|
|
11660
|
+
if (resolvedStore.close) registry.add(resolvedStore.close);
|
|
11661
|
+
const tracked = trackEventStoreSubscriptions(eventStore);
|
|
11662
|
+
registry.add(() => tracked.release());
|
|
11663
|
+
const internalStore = tracked.store;
|
|
11664
|
+
const changelogProjection = new ChangelogProjection(internalStore);
|
|
11665
|
+
registry.add(() => changelogProjection.dispose());
|
|
11167
11666
|
const historyPanelViewModel = new HistoryPanelViewModel(changelogProjection);
|
|
11168
11667
|
const cellUndoStack = new CellUndoStack();
|
|
11169
11668
|
await changelogProjection.start();
|
|
@@ -11172,11 +11671,12 @@ async function assembleGrid(config) {
|
|
|
11172
11671
|
connectivity: config.connectivity ?? createBrowserConnectivity(),
|
|
11173
11672
|
watermark: createLocalStorageWatermark(`pdg-sync-watermark:${store}:${tableKey}`)
|
|
11174
11673
|
});
|
|
11175
|
-
|
|
11674
|
+
registry.add(() => offlineStatus.dispose());
|
|
11675
|
+
await offlineStatus.start(internalStore);
|
|
11176
11676
|
const engineRef = {};
|
|
11177
11677
|
const snapshotStrategy = config.snapshotStore ? new SnapshotStrategy(
|
|
11178
11678
|
config.snapshotStore,
|
|
11179
|
-
|
|
11679
|
+
internalStore,
|
|
11180
11680
|
() => engineRef.current?.getSnapShot("active") ?? {
|
|
11181
11681
|
rows: []
|
|
11182
11682
|
},
|
|
@@ -11291,17 +11791,20 @@ async function assembleGrid(config) {
|
|
|
11291
11791
|
remoteApi,
|
|
11292
11792
|
offlineStatus
|
|
11293
11793
|
);
|
|
11794
|
+
controller.setResourceTeardown(() => registry.run());
|
|
11294
11795
|
let syncPort;
|
|
11295
11796
|
if (config.syncTransport) {
|
|
11296
|
-
const { GridSyncService } = await import('./GridSyncService-
|
|
11797
|
+
const { GridSyncService } = await import('./GridSyncService-3JQLEY65.cjs');
|
|
11297
11798
|
syncPort = new GridSyncService({
|
|
11298
11799
|
tableId: tableKey,
|
|
11299
|
-
eventStore,
|
|
11800
|
+
eventStore: internalStore,
|
|
11300
11801
|
offlineStatus,
|
|
11301
11802
|
transport: config.syncTransport,
|
|
11302
11803
|
policy: config.syncConflictPolicy,
|
|
11303
11804
|
applyCellValue: (rowId, columnId, value) => controller.applySyncedCellValue(rowId, columnId, value)
|
|
11304
11805
|
});
|
|
11806
|
+
const syncService = syncPort;
|
|
11807
|
+
registry.add(() => syncService.dispose?.());
|
|
11305
11808
|
controller.setSyncPort(syncPort);
|
|
11306
11809
|
}
|
|
11307
11810
|
let presencePort;
|
|
@@ -11316,6 +11819,8 @@ async function assembleGrid(config) {
|
|
|
11316
11819
|
label: config.presenceLabel ?? actor.userId,
|
|
11317
11820
|
transport: presenceTransport
|
|
11318
11821
|
});
|
|
11822
|
+
const presenceService = presencePort;
|
|
11823
|
+
registry.add(() => presenceService.dispose());
|
|
11319
11824
|
controller.setPresencePort(presencePort);
|
|
11320
11825
|
}
|
|
11321
11826
|
const { definitions: columnDefinitions, bindings: columnBindings } = mapColumnSchemas(hostColumns);
|
|
@@ -11333,7 +11838,11 @@ async function assembleGrid(config) {
|
|
|
11333
11838
|
engine.setCellEditOptions({
|
|
11334
11839
|
...typeof config.singleClickEdit === "boolean" ? { singleClickEdit: config.singleClickEdit } : {},
|
|
11335
11840
|
...typeof config.stopEditingWhenCellsLoseFocus === "boolean" ? { stopEditingWhenCellsLoseFocus: config.stopEditingWhenCellsLoseFocus } : {},
|
|
11336
|
-
...config.editType === "cell" || config.editType === "fullRow" ? { editType: config.editType } : {}
|
|
11841
|
+
...config.editType === "cell" || config.editType === "fullRow" ? { editType: config.editType } : {},
|
|
11842
|
+
// Page-window (document) grids keep the arianERP write-per-change
|
|
11843
|
+
// contract; the event-sourced grid avoids one EventStore write per key.
|
|
11844
|
+
commit: config.cellEditCommit === "immediate" || config.cellEditCommit === "deferred" ? config.cellEditCommit : pagedIdb ? "immediate" : "deferred",
|
|
11845
|
+
...config.enterNavigation === "nextCell" || config.enterNavigation === "down" ? { enterNavigation: config.enterNavigation } : {}
|
|
11337
11846
|
});
|
|
11338
11847
|
controller.configureClipboard({
|
|
11339
11848
|
copyFormattedValue: config.copyFormattedValue,
|
|
@@ -11375,6 +11884,7 @@ async function assembleGrid(config) {
|
|
|
11375
11884
|
maxBlocksInCache: config.maxBlocksInCache
|
|
11376
11885
|
});
|
|
11377
11886
|
refreshServerSide = () => handle.refreshServerSide();
|
|
11887
|
+
registry.add(() => handle.dispose());
|
|
11378
11888
|
}
|
|
11379
11889
|
if (snapshotStrategy) {
|
|
11380
11890
|
await snapshotStrategy.loadWithCatchUp(`table:${tableKey}`);
|
|
@@ -11382,10 +11892,12 @@ async function assembleGrid(config) {
|
|
|
11382
11892
|
const pluginHost = new PluginHost({
|
|
11383
11893
|
tableId: tableKey,
|
|
11384
11894
|
actorId: actor.userId,
|
|
11385
|
-
eventStore,
|
|
11895
|
+
eventStore: internalStore,
|
|
11386
11896
|
session,
|
|
11387
|
-
query: createEngineGridQuery(engine)
|
|
11897
|
+
query: createEngineGridQuery(engine),
|
|
11898
|
+
beforeRead: () => engine.flushCellEdit()
|
|
11388
11899
|
});
|
|
11900
|
+
registry.add(() => pluginHost.dispose());
|
|
11389
11901
|
if (config.plugins?.length) {
|
|
11390
11902
|
pluginHost.register(config.plugins);
|
|
11391
11903
|
}
|
|
@@ -11396,14 +11908,15 @@ async function assembleGrid(config) {
|
|
|
11396
11908
|
getRowId: config.getRowId,
|
|
11397
11909
|
refreshServerSide
|
|
11398
11910
|
});
|
|
11399
|
-
await attachColumnStatePersistence({
|
|
11911
|
+
const detachColumnState = await attachColumnStatePersistence({
|
|
11400
11912
|
api,
|
|
11401
11913
|
controller,
|
|
11402
11914
|
tableId: tableKey,
|
|
11403
11915
|
actorId: actor.userId,
|
|
11404
11916
|
stateKey: config.stateKey,
|
|
11405
|
-
eventStore
|
|
11917
|
+
eventStore: internalStore
|
|
11406
11918
|
});
|
|
11919
|
+
registry.add(detachColumnState);
|
|
11407
11920
|
return {
|
|
11408
11921
|
engine,
|
|
11409
11922
|
controller,
|
|
@@ -11782,5 +12295,5 @@ exports.toColumnViewBinding = toColumnViewBinding;
|
|
|
11782
12295
|
exports.toMinorUnits = toMinorUnits;
|
|
11783
12296
|
exports.trapTabKey = trapTabKey;
|
|
11784
12297
|
exports.writeSystemClipboard = writeSystemClipboard;
|
|
11785
|
-
//# sourceMappingURL=chunk-
|
|
11786
|
-
//# sourceMappingURL=chunk-
|
|
12298
|
+
//# sourceMappingURL=chunk-WTHTVKVI.cjs.map
|
|
12299
|
+
//# sourceMappingURL=chunk-WTHTVKVI.cjs.map
|