@aurum-grid/enterprise 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/range.js ADDED
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Excel-like cell range selection: drag with the mouse, Shift+click to extend,
3
+ * Shift+arrow keys to extend from the focused cell, Ctrl+C copies the range.
4
+ * Status bar shows Sum / Average / Count / Min / Max for numeric cells.
5
+ */
6
+ export const RangeSelectionModule = {
7
+ name: 'RangeSelectionModule',
8
+ install(grid) {
9
+ let anchor = null;
10
+ let end = null;
11
+ let dragging = false;
12
+ const colIndex = (colId) => grid.getAllDisplayedColumns().findIndex((c) => c.colId === colId);
13
+ const bounds = () => {
14
+ if (!anchor || !end)
15
+ return null;
16
+ return {
17
+ r0: Math.min(anchor.row, end.row), r1: Math.max(anchor.row, end.row),
18
+ c0: Math.min(anchor.col, end.col), c1: Math.max(anchor.col, end.col),
19
+ };
20
+ };
21
+ const isMulti = () => {
22
+ const b = bounds();
23
+ return !!b && (b.r0 !== b.r1 || b.c0 !== b.c1);
24
+ };
25
+ const changed = () => {
26
+ grid.renderRows(true);
27
+ grid.renderStatusBar();
28
+ grid.dispatch('rangeSelectionChanged', { ranges: api.getCellRanges() });
29
+ };
30
+ const api = {
31
+ getCellRanges() {
32
+ const b = bounds();
33
+ if (!b || !isMulti())
34
+ return [];
35
+ const cols = grid.getAllDisplayedColumns().slice(b.c0, b.c1 + 1).map((c) => c.colId);
36
+ return [{ startRow: b.r0, endRow: b.r1, columns: cols }];
37
+ },
38
+ clearRangeSelection() {
39
+ if (!anchor)
40
+ return;
41
+ anchor = end = null;
42
+ changed();
43
+ },
44
+ addCellRange(p) {
45
+ anchor = { row: p.rowStartIndex, col: colIndex(p.columnStart) };
46
+ end = { row: p.rowEndIndex, col: colIndex(p.columnEnd) };
47
+ changed();
48
+ },
49
+ getRangeData() {
50
+ const b = bounds();
51
+ if (!b || !isMulti())
52
+ return null;
53
+ const cols = grid.getAllDisplayedColumns().slice(b.c0, b.c1 + 1);
54
+ const rows = [];
55
+ const formatted = [];
56
+ for (let r = b.r0; r <= b.r1; r++) {
57
+ const node = grid.getDisplayedRowAtIndex(r);
58
+ if (!node)
59
+ continue;
60
+ rows.push(cols.map((c) => grid.getCellValue(node, c.colId)));
61
+ formatted.push(cols.map((c) => grid.getCellFormatted(node, c.colId)));
62
+ }
63
+ return { headers: cols.map((c) => c.headerName), rows, formatted };
64
+ },
65
+ getRangeAggregates() {
66
+ const data = api.getRangeData();
67
+ if (!data)
68
+ return null;
69
+ const nums = [];
70
+ let count = 0;
71
+ for (const row of data.rows)
72
+ for (const v of row) {
73
+ if (v == null || v === '')
74
+ continue;
75
+ count++;
76
+ if (typeof v === 'number' && Number.isFinite(v))
77
+ nums.push(v);
78
+ }
79
+ const sum = nums.reduce((a, b) => a + b, 0);
80
+ return {
81
+ count, numericCount: nums.length, sum,
82
+ avg: nums.length ? sum / nums.length : null,
83
+ min: nums.length ? Math.min(...nums) : null,
84
+ max: nums.length ? Math.max(...nums) : null,
85
+ };
86
+ },
87
+ };
88
+ Object.assign(grid, api);
89
+ const onDown = (e, pos) => {
90
+ const c = colIndex(pos.colId);
91
+ if (e.target.closest('input, button, .agr-row-drag-handle'))
92
+ return false;
93
+ if (e.shiftKey) {
94
+ const f = grid.getFocusedCell();
95
+ anchor = anchor ?? (f ? { row: f.rowIndex, col: colIndex(f.colId) } : { row: pos.rowIndex, col: c });
96
+ end = { row: pos.rowIndex, col: c };
97
+ changed();
98
+ return false;
99
+ }
100
+ anchor = { row: pos.rowIndex, col: c };
101
+ end = { row: pos.rowIndex, col: c };
102
+ dragging = true;
103
+ const up = () => {
104
+ dragging = false;
105
+ document.removeEventListener('pointerup', up);
106
+ };
107
+ document.addEventListener('pointerup', up);
108
+ if (isMulti())
109
+ changed();
110
+ else
111
+ grid.renderStatusBar();
112
+ return false;
113
+ };
114
+ const onOver = (_e, pos) => {
115
+ if (!dragging || !anchor)
116
+ return;
117
+ const next = { row: pos.rowIndex, col: colIndex(pos.colId) };
118
+ if (end && end.row === next.row && end.col === next.col)
119
+ return;
120
+ end = next;
121
+ changed();
122
+ };
123
+ const onKey = (e) => {
124
+ const arrows = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
125
+ if (e.key === 'Escape' && isMulti()) {
126
+ api.clearRangeSelection();
127
+ return true;
128
+ }
129
+ if (!e.shiftKey || e.altKey || !arrows.includes(e.key)) {
130
+ if (arrows.includes(e.key) && !e.altKey && anchor) {
131
+ anchor = end = null;
132
+ grid.renderRows(true);
133
+ grid.renderStatusBar();
134
+ }
135
+ return false;
136
+ }
137
+ // keep row-selection behaviour for Shift+Up/Down when there's no column extent
138
+ const f = grid.getFocusedCell();
139
+ if (!f || f.rowIndex < 0)
140
+ return false;
141
+ if (!anchor)
142
+ anchor = { row: f.rowIndex, col: colIndex(f.colId) };
143
+ if (!end)
144
+ end = { ...anchor };
145
+ const maxR = grid.getDisplayedRowCount() - 1;
146
+ const maxC = grid.getAllDisplayedColumns().length - 1;
147
+ if (e.key === 'ArrowUp')
148
+ end.row = Math.max(0, end.row - 1);
149
+ if (e.key === 'ArrowDown')
150
+ end.row = Math.min(maxR, end.row + 1);
151
+ if (e.key === 'ArrowLeft')
152
+ end.col = Math.max(0, end.col - 1);
153
+ if (e.key === 'ArrowRight')
154
+ end.col = Math.min(maxC, end.col + 1);
155
+ e.preventDefault();
156
+ grid.ensureIndexVisible(end.row);
157
+ changed();
158
+ return true;
159
+ };
160
+ const cellClass = (_node, col, rowIndex) => {
161
+ const b = bounds();
162
+ if (!b || !isMulti())
163
+ return null;
164
+ const c = colIndex(col.colId);
165
+ if (rowIndex < b.r0 || rowIndex > b.r1 || c < b.c0 || c > b.c1)
166
+ return null;
167
+ const edges = ['agr-cell-range'];
168
+ if (rowIndex === b.r0)
169
+ edges.push('agr-range-top');
170
+ if (rowIndex === b.r1)
171
+ edges.push('agr-range-bottom');
172
+ if (c === b.c0)
173
+ edges.push('agr-range-left');
174
+ if (c === b.c1)
175
+ edges.push('agr-range-right');
176
+ return edges.join(' ');
177
+ };
178
+ const fmt = (n) => (n == null ? '—' : n.toLocaleString(undefined, { maximumFractionDigits: 2 }));
179
+ const status = () => {
180
+ const a = api.getRangeAggregates();
181
+ if (!a)
182
+ return [];
183
+ const items = [{ label: 'Count', value: a.count.toLocaleString() }];
184
+ if (a.numericCount) {
185
+ items.push({ label: 'Sum', value: fmt(a.sum) }, { label: 'Avg', value: fmt(a.avg) }, { label: 'Min', value: fmt(a.min) }, { label: 'Max', value: fmt(a.max) });
186
+ }
187
+ return items;
188
+ };
189
+ const copy = () => {
190
+ const d = api.getRangeData();
191
+ if (!d)
192
+ return null;
193
+ return d.formatted.map((r) => r.join('\t')).join('\n');
194
+ };
195
+ grid.hooks.cellMouseDown.add(onDown);
196
+ grid.hooks.cellMouseOver.add(onOver);
197
+ grid.hooks.keyDown.add(onKey);
198
+ grid.hooks.cellClass.add(cellClass);
199
+ grid.hooks.statusBarItems.add(status);
200
+ grid.hooks.copyText.add(copy);
201
+ grid.eRoot.classList.add('agr-range-enabled');
202
+ return () => {
203
+ grid.hooks.cellMouseDown.delete(onDown);
204
+ grid.hooks.cellMouseOver.delete(onOver);
205
+ grid.hooks.keyDown.delete(onKey);
206
+ grid.hooks.cellClass.delete(cellClass);
207
+ grid.hooks.statusBarItems.delete(status);
208
+ grid.hooks.copyText.delete(copy);
209
+ for (const k of Object.keys(api))
210
+ delete grid[k];
211
+ };
212
+ },
213
+ };
214
+ //# sourceMappingURL=range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.js","sourceRoot":"","sources":["../src/range.ts"],"names":[],"mappings":"AAiCA;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAe;IAC9C,IAAI,EAAE,sBAAsB;IAC5B,OAAO,CAAC,IAAe;QACrB,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,IAAI,GAAG,GAAkB,IAAI,CAAC;QAC9B,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QACtG,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YACjC,OAAO;gBACL,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC;gBACpE,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC;aACrE,CAAC;QACJ,CAAC,CAAC;QACF,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;YACnB,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC,CAAC;QACF,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,CAAC,QAAQ,CAAC,uBAAuB,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,aAAa,EAAE,EAAW,CAAC,CAAC;QACnF,CAAC,CAAC;QAEF,MAAM,GAAG,GAAG;YACV,aAAa;gBACX,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;gBACnB,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE;oBAAE,OAAO,EAAE,CAAC;gBAChC,MAAM,IAAI,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACrF,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,CAAC;YACD,mBAAmB;gBACjB,IAAI,CAAC,MAAM;oBAAE,OAAO;gBACpB,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC;gBACpB,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,YAAY,CAAC,CAAyF;gBACpG,MAAM,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,aAAa,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC;gBAChE,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzD,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,YAAY;gBACV,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;gBACnB,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE;oBAAE,OAAO,IAAI,CAAC;gBAClC,MAAM,IAAI,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;gBACjE,MAAM,IAAI,GAAgB,EAAE,CAAC;gBAC7B,MAAM,SAAS,GAAe,EAAE,CAAC;gBACjC,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;oBAClC,MAAM,IAAI,GAAG,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;oBAC5C,IAAI,CAAC,IAAI;wBAAE,SAAS;oBACpB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC7D,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACxE,CAAC;gBACD,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YACrE,CAAC;YACD,kBAAkB;gBAChB,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;gBAChC,IAAI,CAAC,IAAI;oBAAE,OAAO,IAAI,CAAC;gBACvB,MAAM,IAAI,GAAa,EAAE,CAAC;gBAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;gBACd,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI;oBAAE,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;wBACjD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;4BAAE,SAAS;wBACpC,KAAK,EAAE,CAAC;wBACR,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;4BAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAChE,CAAC;gBACD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC5C,OAAO;oBACL,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG;oBACrC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;oBAC3C,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;oBAC3C,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;iBAC5C,CAAC;YACJ,CAAC;SACF,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAEzB,MAAM,MAAM,GAAG,CAAC,CAAa,EAAE,GAAwC,EAAE,EAAE;YACzE,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAK,CAAC,CAAC,MAAsB,CAAC,OAAO,CAAC,qCAAqC,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC3F,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACf,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;gBAChC,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBACrG,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;gBACpC,OAAO,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;YACvC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;YACpC,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,EAAE,GAAG,GAAG,EAAE;gBACd,QAAQ,GAAG,KAAK,CAAC;gBACjB,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAChD,CAAC,CAAC;YACF,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAC3C,IAAI,OAAO,EAAE;gBAAE,OAAO,EAAE,CAAC;;gBACpB,IAAI,CAAC,eAAe,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,EAAc,EAAE,GAAwC,EAAE,EAAE;YAC1E,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM;gBAAE,OAAO;YACjC,MAAM,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7D,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG;gBAAE,OAAO;YAChE,GAAG,GAAG,IAAI,CAAC;YACX,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,CAAC,CAAgB,EAAE,EAAE;YACjC,MAAM,MAAM,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;YACnE,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,EAAE,EAAE,CAAC;gBACpC,GAAG,CAAC,mBAAmB,EAAE,CAAC;gBAC1B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvD,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;oBAClD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC;oBACpB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;oBACtB,IAAI,CAAC,eAAe,EAAE,CAAC;gBACzB,CAAC;gBACD,OAAO,KAAK,CAAC;YACf,CAAC;YACD,+EAA+E;YAC/E,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAChC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YACvC,IAAI,CAAC,MAAM;gBAAE,MAAM,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAClE,IAAI,CAAC,GAAG;gBAAE,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;YACtD,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS;gBAAE,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YAC5D,IAAI,CAAC,CAAC,GAAG,KAAK,WAAW;gBAAE,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YACjE,IAAI,CAAC,CAAC,GAAG,KAAK,WAAW;gBAAE,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YAC9D,IAAI,CAAC,CAAC,GAAG,KAAK,YAAY;gBAAE,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YAClE,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACjC,OAAO,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACF,MAAM,SAAS,GAAG,CAAC,KAAc,EAAE,GAAsB,EAAE,QAAgB,EAAE,EAAE;YAC7E,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE;gBAAE,OAAO,IAAI,CAAC;YAClC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,QAAQ,GAAG,CAAC,CAAC,EAAE,IAAI,QAAQ,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC;YAC5E,MAAM,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC;YACjC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACnD,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YACtD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC7C,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC,CAAC;QACF,MAAM,GAAG,GAAG,CAAC,CAAgB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAChH,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,MAAM,CAAC,GAAG,GAAG,CAAC,kBAAkB,EAAE,CAAC;YACnC,IAAI,CAAC,CAAC;gBAAE,OAAO,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;gBACnB,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjK,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QACF,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,MAAM,CAAC,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;YAC7B,IAAI,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpB,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzD,CAAC,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,SAAkB,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAC9C,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,SAAkB,CAAC,CAAC;YAChD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACjC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,OAAQ,IAAY,CAAC,CAAC,CAAC,CAAC;QAC5D,CAAC,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type GridModule } from '@aurum-grid/core';
2
+ export type ToolPanelId = 'columns' | 'filters';
3
+ export interface SideBarDef {
4
+ toolPanels?: ToolPanelId[];
5
+ defaultToolPanel?: ToolPanelId | null;
6
+ position?: 'right' | 'left';
7
+ }
8
+ declare module '@aurum-grid/core' {
9
+ interface GridOptions<T> {
10
+ sideBar?: boolean | SideBarDef;
11
+ }
12
+ interface Grid<T> {
13
+ openToolPanel(id: ToolPanelId): void;
14
+ closeToolPanel(): void;
15
+ getOpenedToolPanel(): ToolPanelId | null;
16
+ setSideBarVisible(visible: boolean): void;
17
+ }
18
+ }
19
+ /** Tool panels for columns (visibility, grouping, values, pivot) and filters. */
20
+ export declare const SideBarModule: GridModule;
@@ -0,0 +1,154 @@
1
+ import { h, icon, buildFilterPanel, filterKindFor } from '@aurum-grid/core';
2
+ const LABELS = { columns: 'Columns', filters: 'Filters' };
3
+ const AGGS = ['sum', 'avg', 'min', 'max', 'count'];
4
+ /** Tool panels for columns (visibility, grouping, values, pivot) and filters. */
5
+ export const SideBarModule = {
6
+ name: 'SideBarModule',
7
+ install(grid) {
8
+ const opt = grid.options.sideBar;
9
+ const def = opt === true ? {} : opt || {};
10
+ const panels = def.toolPanels ?? ['columns', 'filters'];
11
+ let open = def.defaultToolPanel ?? null;
12
+ let visible = !!opt;
13
+ const strip = h('div', { class: 'agr-side-tabs', role: 'tablist', 'aria-orientation': 'vertical', 'aria-label': 'Tool panels' });
14
+ const body = h('div', { class: 'agr-side-panel', role: 'tabpanel' });
15
+ const root = h('div', { class: `agr-side-bar ${def.position === 'left' ? 'agr-side-left' : ''}` }, [body, strip]);
16
+ let search = '';
17
+ const columnsPanel = () => {
18
+ const wrap = h('div', { class: 'agr-tool-columns' });
19
+ const pivotAvailable = typeof grid.setPivotMode === 'function';
20
+ if (pivotAvailable) {
21
+ const on = grid.isPivotMode();
22
+ const sw = h('input', { type: 'checkbox', role: 'switch', checked: on, 'aria-label': 'Pivot mode' });
23
+ sw.addEventListener('change', () => {
24
+ if (sw.checked) {
25
+ const text = grid.getColumns().filter((c) => filterKindFor(c) !== 'number' && c.visible);
26
+ const groups = grid.getRowGroupColumns().map((c) => c.colId);
27
+ const rows = groups.length ? groups : text.slice(0, 1).map((c) => c.colId);
28
+ const pivotCol = text.find((c) => !rows.includes(c.colId));
29
+ const values = grid.getColumns().filter((c) => filterKindFor(c) === 'number' && c.visible).slice(0, 2)
30
+ .map((c) => ({ colId: c.colId, aggFunc: (typeof c.aggFunc === 'string' ? c.aggFunc : 'sum') }));
31
+ grid.setPivotMode(true, { rows, columns: pivotCol ? [pivotCol.colId] : [], values });
32
+ }
33
+ else
34
+ grid.setPivotMode(false);
35
+ render();
36
+ });
37
+ wrap.append(h('label', { class: 'agr-switch-row' }, [sw, h('span', { text: 'Pivot mode' })]));
38
+ if (on) {
39
+ const cfg = grid.getPivotConfig();
40
+ wrap.append(h('p', { class: 'agr-muted agr-tool-note', text: `Rows: ${cfg.rows.join(', ') || '—'} · Columns: ${cfg.columns.join(', ') || '—'} · Values: ${cfg.values.map((v) => `${v.aggFunc}(${v.colId})`).join(', ')}` }));
41
+ return wrap;
42
+ }
43
+ }
44
+ const q = h('input', { class: 'agr-input', type: 'search', placeholder: 'Search columns…', 'aria-label': 'Search columns' });
45
+ q.value = search;
46
+ q.addEventListener('input', () => {
47
+ search = q.value;
48
+ renderList();
49
+ });
50
+ const list = h('div', { class: 'agr-tool-list', role: 'list' });
51
+ const renderList = () => {
52
+ list.replaceChildren();
53
+ const cols = grid.getColumns().filter((c) => c.headerName.toLowerCase().includes(search.toLowerCase()));
54
+ for (const c of cols) {
55
+ const cb = h('input', { type: 'checkbox', checked: c.visible, 'aria-label': `Show ${c.headerName}` });
56
+ cb.addEventListener('change', () => grid.setColumnsVisible([c.colId], cb.checked));
57
+ const grouped = c.rowGroupActive;
58
+ const groupBtn = h('button', {
59
+ type: 'button', class: `agr-icon-btn ${grouped ? 'agr-active' : ''}`, 'aria-pressed': String(grouped),
60
+ 'aria-label': `${grouped ? 'Ungroup' : 'Group'} by ${c.headerName}`, title: grouped ? 'Remove row group' : 'Group rows by this column',
61
+ disabled: c.colDef.enableRowGroup === false || !!grid.options.treeData,
62
+ }, [icon('group', 14)]);
63
+ groupBtn.addEventListener('click', () => (grouped ? grid.removeRowGroupColumn(c.colId) : grid.addRowGroupColumn(c.colId)));
64
+ const items = [cb, h('span', { class: 'agr-tool-name', text: c.headerName }), groupBtn];
65
+ if (filterKindFor(c) === 'number') {
66
+ const sel = h('select', { class: 'agr-input agr-tool-agg', 'aria-label': `Aggregation for ${c.headerName}` });
67
+ sel.append(h('option', { value: '', text: 'No agg' }));
68
+ for (const a of AGGS)
69
+ sel.append(h('option', { value: a, text: a, selected: c.aggFunc === a }));
70
+ sel.addEventListener('change', () => grid.applyColumnState({ state: [{ colId: c.colId, aggFunc: (sel.value || null) }] }));
71
+ items.push(sel);
72
+ }
73
+ list.append(h('div', { class: 'agr-tool-item', role: 'listitem' }, items));
74
+ }
75
+ if (!cols.length)
76
+ list.append(h('p', { class: 'agr-muted', text: 'No columns match' }));
77
+ };
78
+ renderList();
79
+ const groupCols = grid.getRowGroupColumns();
80
+ wrap.append(q, list, h('div', { class: 'agr-tool-section', text: 'Row groups' }), groupCols.length ? h('div', { class: 'agr-tool-chips' }, groupCols.map((c) => {
81
+ const x = h('button', { type: 'button', class: 'agr-chip-remove', 'aria-label': `Remove ${c.headerName} grouping` }, [icon('close', 11)]);
82
+ x.addEventListener('click', () => grid.removeRowGroupColumn(c.colId));
83
+ return h('span', { class: 'agr-chip' }, [h('span', { text: c.headerName }), x]);
84
+ })) : h('p', { class: 'agr-muted agr-tool-note', text: 'Use the group button next to a column.' }));
85
+ return wrap;
86
+ };
87
+ const filtersPanel = () => {
88
+ const wrap = h('div', { class: 'agr-tool-filters' });
89
+ for (const c of grid.getColumns().filter((c) => filterKindFor(c) && c.visible)) {
90
+ const active = !!grid.getFilterModel()[c.colId];
91
+ const det = h('details', { class: 'agr-tool-filter' });
92
+ const sum = h('summary', {}, [h('span', { text: c.headerName }), active ? h('span', { class: 'agr-filter-ind', 'aria-label': 'Filtered' }, [icon('filter', 12)]) : '']);
93
+ det.append(sum);
94
+ det.addEventListener('toggle', () => {
95
+ if (det.open && det.childElementCount === 1)
96
+ det.append(buildFilterPanel(grid, c));
97
+ });
98
+ wrap.append(det);
99
+ }
100
+ return wrap;
101
+ };
102
+ const render = () => {
103
+ root.hidden = !visible;
104
+ grid.eRoot.classList.toggle('agr-has-side-bar', visible);
105
+ strip.replaceChildren(...panels.map((id) => {
106
+ const b = h('button', {
107
+ type: 'button', role: 'tab', class: 'agr-side-tab', 'aria-selected': String(open === id), 'aria-controls': `${grid.gridId}-panel`,
108
+ title: LABELS[id],
109
+ }, [icon(id === 'columns' ? 'columns' : 'filter', 15), h('span', { class: 'agr-side-tab-label', text: LABELS[id] })]);
110
+ b.addEventListener('click', () => {
111
+ open = open === id ? null : id;
112
+ render();
113
+ });
114
+ return b;
115
+ }));
116
+ body.id = `${grid.gridId}-panel`;
117
+ body.hidden = !open;
118
+ if (open) {
119
+ body.replaceChildren(h('div', { class: 'agr-side-title', text: LABELS[open] }), open === 'columns' ? columnsPanel() : filtersPanel());
120
+ }
121
+ };
122
+ const api = {
123
+ openToolPanel(id) {
124
+ open = id;
125
+ visible = true;
126
+ render();
127
+ },
128
+ closeToolPanel() {
129
+ open = null;
130
+ render();
131
+ },
132
+ getOpenedToolPanel: () => open,
133
+ setSideBarVisible(v) {
134
+ visible = v;
135
+ render();
136
+ },
137
+ };
138
+ Object.assign(grid, api);
139
+ grid.eSideHost.append(root);
140
+ render();
141
+ const offs = ['displayedColumnsChanged', 'columnRowGroupChanged', 'columnVisible'].map((t) => grid.addEventListener(t, () => open === 'columns' && render()));
142
+ offs.push(grid.addEventListener('filterChanged', () => {
143
+ if (open === 'filters' && !body.contains(document.activeElement))
144
+ render();
145
+ }));
146
+ return () => {
147
+ offs.forEach((f) => f());
148
+ root.remove();
149
+ for (const k of Object.keys(api))
150
+ delete grid[k];
151
+ };
152
+ },
153
+ };
154
+ //# sourceMappingURL=sidebar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidebar.js","sourceRoot":"","sources":["../src/sidebar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /* Aurum Grid Enterprise styles — opt-in. Uses the same --agr-* theme tokens as core. */
2
+
3
+ /* range selection */
4
+ .agr-cell-range { background-image: linear-gradient(var(--agr-range-bg), var(--agr-range-bg)); }
5
+ .agr-range-top { box-shadow: inset 0 2px 0 var(--agr-accent); }
6
+ .agr-range-bottom { box-shadow: inset 0 -2px 0 var(--agr-accent); }
7
+ .agr-range-left { border-left: 2px solid var(--agr-accent); }
8
+ .agr-range-right { border-right: 2px solid var(--agr-accent); }
9
+ .agr-range-top.agr-range-bottom { box-shadow: inset 0 2px 0 var(--agr-accent), inset 0 -2px 0 var(--agr-accent); }
10
+ .agr-range-enabled .agr-body { user-select: none; }
11
+
12
+ /* side bar */
13
+ .agr-side-bar { display: flex; height: 100%; border-left: 1px solid var(--agr-border); background: var(--agr-bg); }
14
+ .agr-side-bar[hidden] { display: none; }
15
+ .agr-side-left { order: -1; flex-direction: row-reverse; border-left: 0; border-right: 1px solid var(--agr-border); }
16
+ .agr-side-host { display: flex; }
17
+ .agr-side-tabs { display: flex; flex-direction: column; gap: 2px; padding: 6px 3px; background: var(--agr-header-bg); }
18
+ .agr-side-tab {
19
+ display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 6px; border: 0; border-radius: 4px;
20
+ background: transparent; color: var(--agr-header-fg); cursor: pointer; font: inherit; font-size: 12px;
21
+ }
22
+ .agr-side-tab-label { writing-mode: vertical-rl; transform: rotate(180deg); letter-spacing: 0.04em; }
23
+ .agr-side-tab[aria-selected='true'] { background: var(--agr-accent); color: var(--agr-accent-fg); }
24
+ .agr-side-tab:hover:not([aria-selected='true']) { background: color-mix(in srgb, var(--agr-header-fg) 10%, transparent); }
25
+ .agr-side-tab:focus-visible { outline: 2px solid var(--agr-focus); outline-offset: 1px; }
26
+ .agr-side-panel { width: 260px; overflow: auto; padding: 10px; display: flex; flex-direction: column; gap: 8px; }
27
+ .agr-side-panel[hidden] { display: none; }
28
+ .agr-side-title { font-weight: 700; }
29
+ .agr-tool-columns, .agr-tool-filters { display: flex; flex-direction: column; gap: 8px; }
30
+ .agr-tool-list { display: flex; flex-direction: column; }
31
+ .agr-tool-item { display: flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 2px; border-radius: 4px; }
32
+ .agr-tool-item:hover { background: var(--agr-row-hover-bg); }
33
+ .agr-tool-item input[type='checkbox'] { accent-color: var(--agr-accent); }
34
+ .agr-tool-name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
35
+ .agr-tool-agg { height: 26px; width: 76px; font-size: 12px; }
36
+ .agr-tool-section { margin-top: 6px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--agr-muted); }
37
+ .agr-tool-chips { display: flex; flex-wrap: wrap; gap: 6px; }
38
+ .agr-tool-note { margin: 0; font-size: 12px; }
39
+ .agr-icon-btn.agr-active { background: var(--agr-accent); color: var(--agr-accent-fg); }
40
+ .agr-switch-row { display: flex; align-items: center; gap: 8px; font-weight: 600; }
41
+ .agr-switch-row input { accent-color: var(--agr-accent); width: 16px; height: 16px; }
42
+ .agr-tool-filter { border: 1px solid var(--agr-border); border-radius: 4px; }
43
+ .agr-tool-filter > summary { display: flex; align-items: center; gap: 6px; padding: 6px 8px; cursor: pointer; font-weight: 600; }
44
+ .agr-tool-filter[open] > summary { border-bottom: 1px solid var(--agr-border); }
45
+
46
+ /* advanced filter builder */
47
+ .agr-adv-builder { display: flex; flex-direction: column; gap: 8px; padding: 4px 6px 8px; min-width: 300px; }
48
+ .agr-adv-row { display: grid; grid-template-columns: 1fr 1fr 1fr auto; gap: 6px; align-items: center; }
49
+ .agr-adv-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--agr-muted); }
50
+ .agr-adv-preview { display: block; padding: 6px 8px; border-radius: 4px; background: var(--agr-input-bg); border: 1px solid var(--agr-border); white-space: pre-wrap; font-size: 12px; }
51
+ .agr-adv-actions { display: flex; justify-content: flex-end; gap: 6px; }
52
+ .agr-popup:has(.agr-adv-builder) { max-width: 560px; }
53
+
54
+ /* pivot */
55
+ .agr-pivot-total { font-weight: 700; }
package/dist/sync.d.ts ADDED
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Persist a grid configuration to a REST collection:
3
+ * POST {endpoint} → 201 + Location: /grids/42 (or JSON { id })
4
+ * PUT {resource} ← debounced edits, strictly one at a time, latest wins
5
+ * Without an endpoint the client stays in "local-only" mode and says so.
6
+ */
7
+ export type SyncStatus = 'local-only' | 'idle' | 'creating' | 'saving' | 'saved' | 'error';
8
+ export interface SyncState {
9
+ status: SyncStatus;
10
+ message: string;
11
+ resourceUrl: string | null;
12
+ /** Number of edits made locally. */
13
+ revision: number;
14
+ /** Highest revision the server has confirmed. */
15
+ savedRevision: number;
16
+ lastSavedAt: string | null;
17
+ requests: number;
18
+ }
19
+ type FetchLike = (input: string, init?: {
20
+ method?: string;
21
+ headers?: Record<string, string>;
22
+ body?: string;
23
+ signal?: AbortSignal;
24
+ }) => Promise<{
25
+ ok: boolean;
26
+ status: number;
27
+ headers: {
28
+ get(name: string): string | null;
29
+ };
30
+ json(): Promise<unknown>;
31
+ }>;
32
+ export interface GridSyncOptions {
33
+ endpoint?: string | null;
34
+ fetch?: FetchLike;
35
+ debounceMs?: number;
36
+ headers?: Record<string, string>;
37
+ timeoutMs?: number;
38
+ onState?: (s: SyncState) => void;
39
+ }
40
+ export declare function validateCollectionUrl(raw: string): {
41
+ ok: true;
42
+ url: string;
43
+ } | {
44
+ ok: false;
45
+ error: string;
46
+ };
47
+ export declare class GridSync<P extends object = object> {
48
+ private o;
49
+ private state;
50
+ private chain;
51
+ private pending;
52
+ private timer;
53
+ private disposed;
54
+ private endpoint;
55
+ private fetcher;
56
+ constructor(o?: GridSyncOptions);
57
+ getState(): SyncState;
58
+ private set;
59
+ private request;
60
+ /** POST the full configuration. Resolves once the server has created the resource (or failed). */
61
+ create(payload: P): Promise<void>;
62
+ /** Record an edit; the latest payload is PUT after the debounce interval. */
63
+ update(payload: P): void;
64
+ /** Send any pending edit now (still serialised behind in-flight requests). */
65
+ flush(): Promise<void>;
66
+ retry(): Promise<void>;
67
+ dispose(): void;
68
+ }
69
+ export declare function createGridSync<P extends object>(o?: GridSyncOptions): GridSync<P>;
70
+ export interface MockServerLogEntry {
71
+ at: string;
72
+ method: string;
73
+ url: string;
74
+ status: number;
75
+ bytes: number;
76
+ }
77
+ export declare function createMockCollectionServer(o?: {
78
+ baseUrl?: string;
79
+ latencyMs?: number | (() => number);
80
+ failNext?: number;
81
+ }): {
82
+ baseUrl: string;
83
+ fetch: FetchLike;
84
+ log: MockServerLogEntry[];
85
+ get: (id: string) => unknown;
86
+ failNextRequests: (n: number) => void;
87
+ };
88
+ export {};