@sisense/sdk-pivot-query-client 2.17.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.
Files changed (189) hide show
  1. package/LICENSE.md +35 -0
  2. package/README.md +2 -0
  3. package/dist/__test-helpers__/testUtils.d.ts +30 -0
  4. package/dist/__test-helpers__/testUtils.js +89 -0
  5. package/dist/builders/index.d.ts +2 -0
  6. package/dist/builders/index.js +2 -0
  7. package/dist/builders/pivot-data-builder.d.ts +34 -0
  8. package/dist/builders/pivot-data-builder.js +182 -0
  9. package/dist/builders/socket-builder.d.ts +18 -0
  10. package/dist/builders/socket-builder.js +72 -0
  11. package/dist/cjs/__test-helpers__/testUtils.d.ts +30 -0
  12. package/dist/cjs/__test-helpers__/testUtils.js +104 -0
  13. package/dist/cjs/builders/index.d.ts +2 -0
  14. package/dist/cjs/builders/index.js +7 -0
  15. package/dist/cjs/builders/pivot-data-builder.d.ts +34 -0
  16. package/dist/cjs/builders/pivot-data-builder.js +186 -0
  17. package/dist/cjs/builders/socket-builder.d.ts +18 -0
  18. package/dist/cjs/builders/socket-builder.js +79 -0
  19. package/dist/cjs/data-handling/DataService.d.ts +672 -0
  20. package/dist/cjs/data-handling/DataService.js +1364 -0
  21. package/dist/cjs/data-handling/DivergenceComparator.d.ts +7 -0
  22. package/dist/cjs/data-handling/DivergenceComparator.js +20 -0
  23. package/dist/cjs/data-handling/constants.d.ts +44 -0
  24. package/dist/cjs/data-handling/constants.js +43 -0
  25. package/dist/cjs/data-handling/index.d.ts +3 -0
  26. package/dist/cjs/data-handling/index.js +23 -0
  27. package/dist/cjs/data-handling/types.d.ts +104 -0
  28. package/dist/cjs/data-handling/types.js +2 -0
  29. package/dist/cjs/data-handling/utils/createPivotTreeNode.d.ts +13 -0
  30. package/dist/cjs/data-handling/utils/createPivotTreeNode.js +21 -0
  31. package/dist/cjs/data-handling/utils/index.d.ts +4 -0
  32. package/dist/cjs/data-handling/utils/index.js +14 -0
  33. package/dist/cjs/data-handling/utils/jaqlProcessor.d.ts +122 -0
  34. package/dist/cjs/data-handling/utils/jaqlProcessor.js +661 -0
  35. package/dist/cjs/data-handling/utils/pivotTransforms.d.ts +74 -0
  36. package/dist/cjs/data-handling/utils/pivotTransforms.js +373 -0
  37. package/dist/cjs/data-handling/utils/plugins/PluginService.d.ts +135 -0
  38. package/dist/cjs/data-handling/utils/plugins/PluginService.js +383 -0
  39. package/dist/cjs/data-handling/utils/plugins/getters.d.ts +23 -0
  40. package/dist/cjs/data-handling/utils/plugins/getters.js +70 -0
  41. package/dist/cjs/data-handling/utils/plugins/types.d.ts +75 -0
  42. package/dist/cjs/data-handling/utils/plugins/types.js +2 -0
  43. package/dist/cjs/data-handling/utils/plugins/validator.d.ts +13 -0
  44. package/dist/cjs/data-handling/utils/plugins/validator.js +169 -0
  45. package/dist/cjs/data-load/AbstractDataLoadService.d.ts +256 -0
  46. package/dist/cjs/data-load/AbstractDataLoadService.js +473 -0
  47. package/dist/cjs/data-load/DataLoadService.d.ts +63 -0
  48. package/dist/cjs/data-load/DataLoadService.js +152 -0
  49. package/dist/cjs/data-load/SisenseDataLoadService.d.ts +44 -0
  50. package/dist/cjs/data-load/SisenseDataLoadService.js +87 -0
  51. package/dist/cjs/data-load/TestDataLoadService.d.ts +27 -0
  52. package/dist/cjs/data-load/TestDataLoadService.js +76 -0
  53. package/dist/cjs/data-load/constants.d.ts +13 -0
  54. package/dist/cjs/data-load/constants.js +28 -0
  55. package/dist/cjs/data-load/index.d.ts +6 -0
  56. package/dist/cjs/data-load/index.js +14 -0
  57. package/dist/cjs/data-load/sockets/SisenseSocket.d.ts +81 -0
  58. package/dist/cjs/data-load/sockets/SisenseSocket.js +162 -0
  59. package/dist/cjs/data-load/sockets/TestSocket.d.ts +61 -0
  60. package/dist/cjs/data-load/sockets/TestSocket.js +90 -0
  61. package/dist/cjs/data-load/sockets/helpers.d.ts +4 -0
  62. package/dist/cjs/data-load/sockets/helpers.js +27 -0
  63. package/dist/cjs/data-load/sockets/index.d.ts +2 -0
  64. package/dist/cjs/data-load/sockets/index.js +8 -0
  65. package/dist/cjs/data-load/types.d.ts +90 -0
  66. package/dist/cjs/data-load/types.js +2 -0
  67. package/dist/cjs/errors/LoadingCanceledError.d.ts +7 -0
  68. package/dist/cjs/errors/LoadingCanceledError.js +24 -0
  69. package/dist/cjs/errors/index.d.ts +1 -0
  70. package/dist/cjs/errors/index.js +6 -0
  71. package/dist/cjs/index.d.ts +17 -0
  72. package/dist/cjs/index.js +32 -0
  73. package/dist/cjs/package.json +12 -0
  74. package/dist/cjs/pivot-query-client.d.ts +13 -0
  75. package/dist/cjs/pivot-query-client.js +26 -0
  76. package/dist/cjs/tree-structure/AbstractTreeService.d.ts +308 -0
  77. package/dist/cjs/tree-structure/AbstractTreeService.js +716 -0
  78. package/dist/cjs/tree-structure/HeaderTreeService.d.ts +180 -0
  79. package/dist/cjs/tree-structure/HeaderTreeService.js +280 -0
  80. package/dist/cjs/tree-structure/TreeCellMap.d.ts +104 -0
  81. package/dist/cjs/tree-structure/TreeCellMap.js +145 -0
  82. package/dist/cjs/tree-structure/TreeService.d.ts +8 -0
  83. package/dist/cjs/tree-structure/TreeService.js +12 -0
  84. package/dist/cjs/tree-structure/constants.d.ts +6 -0
  85. package/dist/cjs/tree-structure/constants.js +10 -0
  86. package/dist/cjs/tree-structure/index.d.ts +5 -0
  87. package/dist/cjs/tree-structure/index.js +10 -0
  88. package/dist/cjs/tree-structure/types.d.ts +93 -0
  89. package/dist/cjs/tree-structure/types.js +2 -0
  90. package/dist/cjs/tree-structure/utils/index.d.ts +1 -0
  91. package/dist/cjs/tree-structure/utils/index.js +9 -0
  92. package/dist/cjs/tree-structure/utils/treeNode.d.ts +147 -0
  93. package/dist/cjs/tree-structure/utils/treeNode.js +534 -0
  94. package/dist/cjs/utils/array.d.ts +13 -0
  95. package/dist/cjs/utils/array.js +25 -0
  96. package/dist/cjs/utils/cloneObject.d.ts +30 -0
  97. package/dist/cjs/utils/cloneObject.js +225 -0
  98. package/dist/cjs/utils/index.d.ts +3 -0
  99. package/dist/cjs/utils/index.js +9 -0
  100. package/dist/cjs/utils/throttle.d.ts +12 -0
  101. package/dist/cjs/utils/throttle.js +39 -0
  102. package/dist/cjs/utils/types.d.ts +12 -0
  103. package/dist/cjs/utils/types.js +2 -0
  104. package/dist/data-handling/DataService.d.ts +672 -0
  105. package/dist/data-handling/DataService.js +1357 -0
  106. package/dist/data-handling/DivergenceComparator.d.ts +7 -0
  107. package/dist/data-handling/DivergenceComparator.js +16 -0
  108. package/dist/data-handling/constants.d.ts +44 -0
  109. package/dist/data-handling/constants.js +40 -0
  110. package/dist/data-handling/index.d.ts +3 -0
  111. package/dist/data-handling/index.js +4 -0
  112. package/dist/data-handling/types.d.ts +104 -0
  113. package/dist/data-handling/types.js +1 -0
  114. package/dist/data-handling/utils/createPivotTreeNode.d.ts +13 -0
  115. package/dist/data-handling/utils/createPivotTreeNode.js +17 -0
  116. package/dist/data-handling/utils/index.d.ts +4 -0
  117. package/dist/data-handling/utils/index.js +4 -0
  118. package/dist/data-handling/utils/jaqlProcessor.d.ts +122 -0
  119. package/dist/data-handling/utils/jaqlProcessor.js +621 -0
  120. package/dist/data-handling/utils/pivotTransforms.d.ts +74 -0
  121. package/dist/data-handling/utils/pivotTransforms.js +335 -0
  122. package/dist/data-handling/utils/plugins/PluginService.d.ts +135 -0
  123. package/dist/data-handling/utils/plugins/PluginService.js +379 -0
  124. package/dist/data-handling/utils/plugins/getters.d.ts +23 -0
  125. package/dist/data-handling/utils/plugins/getters.js +65 -0
  126. package/dist/data-handling/utils/plugins/types.d.ts +75 -0
  127. package/dist/data-handling/utils/plugins/types.js +1 -0
  128. package/dist/data-handling/utils/plugins/validator.d.ts +13 -0
  129. package/dist/data-handling/utils/plugins/validator.js +165 -0
  130. package/dist/data-load/AbstractDataLoadService.d.ts +256 -0
  131. package/dist/data-load/AbstractDataLoadService.js +466 -0
  132. package/dist/data-load/DataLoadService.d.ts +63 -0
  133. package/dist/data-load/DataLoadService.js +148 -0
  134. package/dist/data-load/SisenseDataLoadService.d.ts +44 -0
  135. package/dist/data-load/SisenseDataLoadService.js +83 -0
  136. package/dist/data-load/TestDataLoadService.d.ts +27 -0
  137. package/dist/data-load/TestDataLoadService.js +69 -0
  138. package/dist/data-load/constants.d.ts +13 -0
  139. package/dist/data-load/constants.js +25 -0
  140. package/dist/data-load/index.d.ts +6 -0
  141. package/dist/data-load/index.js +6 -0
  142. package/dist/data-load/sockets/SisenseSocket.d.ts +81 -0
  143. package/dist/data-load/sockets/SisenseSocket.js +155 -0
  144. package/dist/data-load/sockets/TestSocket.d.ts +61 -0
  145. package/dist/data-load/sockets/TestSocket.js +83 -0
  146. package/dist/data-load/sockets/helpers.d.ts +4 -0
  147. package/dist/data-load/sockets/helpers.js +23 -0
  148. package/dist/data-load/sockets/index.d.ts +2 -0
  149. package/dist/data-load/sockets/index.js +3 -0
  150. package/dist/data-load/types.d.ts +90 -0
  151. package/dist/data-load/types.js +1 -0
  152. package/dist/errors/LoadingCanceledError.d.ts +7 -0
  153. package/dist/errors/LoadingCanceledError.js +20 -0
  154. package/dist/errors/index.d.ts +1 -0
  155. package/dist/errors/index.js +2 -0
  156. package/dist/index.d.ts +17 -0
  157. package/dist/index.js +9 -0
  158. package/dist/pivot-query-client.d.ts +13 -0
  159. package/dist/pivot-query-client.js +22 -0
  160. package/dist/tree-structure/AbstractTreeService.d.ts +308 -0
  161. package/dist/tree-structure/AbstractTreeService.js +712 -0
  162. package/dist/tree-structure/HeaderTreeService.d.ts +180 -0
  163. package/dist/tree-structure/HeaderTreeService.js +276 -0
  164. package/dist/tree-structure/TreeCellMap.d.ts +104 -0
  165. package/dist/tree-structure/TreeCellMap.js +141 -0
  166. package/dist/tree-structure/TreeService.d.ts +8 -0
  167. package/dist/tree-structure/TreeService.js +8 -0
  168. package/dist/tree-structure/constants.d.ts +6 -0
  169. package/dist/tree-structure/constants.js +7 -0
  170. package/dist/tree-structure/index.d.ts +5 -0
  171. package/dist/tree-structure/index.js +4 -0
  172. package/dist/tree-structure/types.d.ts +93 -0
  173. package/dist/tree-structure/types.js +1 -0
  174. package/dist/tree-structure/utils/index.d.ts +1 -0
  175. package/dist/tree-structure/utils/index.js +1 -0
  176. package/dist/tree-structure/utils/treeNode.d.ts +147 -0
  177. package/dist/tree-structure/utils/treeNode.js +515 -0
  178. package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -0
  179. package/dist/utils/array.d.ts +13 -0
  180. package/dist/utils/array.js +21 -0
  181. package/dist/utils/cloneObject.d.ts +30 -0
  182. package/dist/utils/cloneObject.js +221 -0
  183. package/dist/utils/index.d.ts +3 -0
  184. package/dist/utils/index.js +3 -0
  185. package/dist/utils/throttle.d.ts +12 -0
  186. package/dist/utils/throttle.js +35 -0
  187. package/dist/utils/types.d.ts +12 -0
  188. package/dist/utils/types.js +1 -0
  189. package/package.json +61 -0
@@ -0,0 +1,716 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractTreeService = void 0;
4
+ const constants_js_1 = require("./constants.js");
5
+ const TreeCellMap_js_1 = require("./TreeCellMap.js");
6
+ const index_js_1 = require("./utils/index.js");
7
+ const keyCreator = (rowIndex, columnIndex) => `${rowIndex}-${columnIndex}`;
8
+ /**
9
+ * AbstractTreeService required as parent class to solve circular dependencies
10
+ * TreeService converts tree structure into grid structure, also it keeps inner grid structure
11
+ * to update cache system (via setCellCache) and receive merged cells (via updateMainCellMargins)
12
+ */
13
+ class AbstractTreeService {
14
+ constructor(tree, isVertical = false, deep) {
15
+ this.hasGrandTotals = false;
16
+ /**
17
+ * Defines if tree will be converted to vertical or horizontal grid
18
+ *
19
+ *
20
+ * @private
21
+ */
22
+ this.isVertical = false;
23
+ /**
24
+ * Cache tree nodes by deep levels
25
+ *
26
+ *
27
+ * @private
28
+ */
29
+ this.columns = [];
30
+ /**
31
+ * Cache last levels tree nodes
32
+ *
33
+ *
34
+ * @private
35
+ */
36
+ this.lastLevel = [];
37
+ /**
38
+ * Mapping object between tree<>grid
39
+ *
40
+ *
41
+ * @private
42
+ */
43
+ this.map = {};
44
+ /**
45
+ * Metadata cache object
46
+ *
47
+ *
48
+ * @private
49
+ */
50
+ this.metadataCache = {};
51
+ this.isVertical = isVertical;
52
+ this.deep = deep;
53
+ if (tree) {
54
+ this.tree = tree;
55
+ this.columns = this.cacheLevels(index_js_1.treeNode.getChildren(this.tree));
56
+ }
57
+ }
58
+ destroy() {
59
+ this.tree = undefined;
60
+ this.columns = [];
61
+ this.lastLevel = [];
62
+ this.map = {};
63
+ this.metadataCache = {};
64
+ this.valueNode = undefined;
65
+ this.grid = undefined;
66
+ }
67
+ getMainCellWidth(rowIndex, columnIndex, columnWidth, borderWidth, options = { offsetTop: -1, columnsOffset: 0 }) {
68
+ const { columnsOffset = 0 } = options;
69
+ const item = this.getItem(rowIndex, columnIndex);
70
+ const isMergedColumn = item && item.hasChildren() && item.hasColCell();
71
+ let width = Number.NaN;
72
+ let hasAllWidth = true;
73
+ if (item && isMergedColumn) {
74
+ const childColCells = item.getColCell();
75
+ const parentItemWidth = columnWidth({ index: columnIndex + columnsOffset });
76
+ width = childColCells.reduce((prev, curr) => {
77
+ const currentWidth = columnWidth({ index: curr.colIndex + columnsOffset });
78
+ if (!currentWidth) {
79
+ hasAllWidth = false;
80
+ }
81
+ return prev + currentWidth;
82
+ }, parentItemWidth);
83
+ width -= borderWidth;
84
+ width = Math.ceil(width);
85
+ }
86
+ return hasAllWidth ? width : Number.NaN;
87
+ }
88
+ /**
89
+ * Adds additional tree node to current state
90
+ *
91
+ * @param {TreeNode} tree - new treeNode
92
+ * @returns {void}
93
+ */
94
+ extend(tree) {
95
+ if (tree) {
96
+ this.grid = undefined;
97
+ this.tree = index_js_1.treeNode.merge(this.tree, tree);
98
+ this.columns = this.cacheLevels(index_js_1.treeNode.getChildren(tree), this.columns);
99
+ }
100
+ }
101
+ /**
102
+ * Returns grid (2d list) of tree structure
103
+ *
104
+ * @returns {Array<Array<TreeNode | string>>} - 2d list
105
+ */
106
+ getGrid() {
107
+ if (this.grid) {
108
+ return this.grid;
109
+ }
110
+ let rows = this.getTreeDeepsLength();
111
+ let cols = this.getTreeChildLength();
112
+ if (this.isVertical) {
113
+ [rows, cols] = [cols, rows];
114
+ this.map = this.fillMapVertical(index_js_1.treeNode.getChildren(this.tree), cols, this.map);
115
+ }
116
+ else {
117
+ this.map = this.fillMap(index_js_1.treeNode.getChildren(this.tree), rows, this.map);
118
+ }
119
+ this.grid = Array.from(Array(rows)).map((rO, rowIndex) => Array.from(Array(cols)).map((cO, colIndex) => {
120
+ const key = keyCreator(rowIndex, colIndex);
121
+ const mapItem = this.map[key];
122
+ if (!mapItem) {
123
+ throw new Error(`Key "${key}" does not found in TreeService`);
124
+ }
125
+ return mapItem.node ? mapItem.node : mapItem.parent;
126
+ }));
127
+ return this.grid;
128
+ }
129
+ /**
130
+ * Returns part of current grid according to "from" - "to" position
131
+ *
132
+ * @param {number} from - start rows index for partial grid
133
+ * @param {number} to - stop rows index for partial grid
134
+ * @returns {Array<Array<TreeNode | string>>} - partial grid
135
+ */
136
+ getPartialGrid(from, to) {
137
+ if (!this.isVertical) {
138
+ throw new Error('"getPartialGrid" can only be used for "vertical" tree');
139
+ }
140
+ const cols = this.getTreeDeepsLength();
141
+ const treeChild = index_js_1.treeNode.getChildren(this.tree);
142
+ const { nodes, start, stop } = index_js_1.treeNode.getNodesByChildCount(treeChild, from, to);
143
+ this.fillMapVertical(nodes, cols, this.map, {
144
+ parentRowIndex: start,
145
+ parentColIndex: 0,
146
+ prevChildren: 0,
147
+ parentKey: '',
148
+ });
149
+ const finalFrom = Math.max(start, from);
150
+ const finalTo = Math.min(stop, to);
151
+ const finalCount = Math.max(0, finalTo - from);
152
+ return Array.from(Array(finalCount)).map((rO, rowIndex) => Array.from(Array(cols)).map((cO, colIndex) => {
153
+ const index = finalFrom + rowIndex;
154
+ const key = keyCreator(index, colIndex);
155
+ const mapItem = this.map[key];
156
+ if (!mapItem) {
157
+ throw new Error(`Key "${key}" does not found in TreeService`);
158
+ }
159
+ return mapItem.node ? mapItem.node : mapItem.parent || '';
160
+ }));
161
+ }
162
+ /**
163
+ * Returns part of current tree with possible cut nodes according to "from" - "to" position
164
+ *
165
+ * @param {number} from - start rows index for partial grid
166
+ * @param {number} [to] - stop rows index for partial grid
167
+ * @param {object} [options] - additional options
168
+ * @param {Function} [options.cloneFn] - replace default clone function with specific one
169
+ * @returns {Array<TreeNode>} - partial tree
170
+ */
171
+ getPartialTree(from, to, options) {
172
+ const treeChild = index_js_1.treeNode.getChildren(this.tree);
173
+ return index_js_1.treeNode.getCutNodesByChildCount(treeChild, from, to, options);
174
+ }
175
+ /**
176
+ * Returns TreeNode item if exist for appropriate coordinates (rowIndex, columnIndex)
177
+ *
178
+ * @param {number} rowIndex - row index
179
+ * @param {number} columnIndex - column index
180
+ * @returns {TreeNode|undefined} - TreeNode item
181
+ */
182
+ getTreeNode(rowIndex, columnIndex) {
183
+ const mapItem = this.getItem(rowIndex, columnIndex);
184
+ if (mapItem && mapItem.node) {
185
+ return mapItem.node;
186
+ }
187
+ return undefined;
188
+ }
189
+ /**
190
+ * Defines if cell with (rowIndex, columnIndex) coordinate is children cell or main one
191
+ *
192
+ * @param {number} rowIndex - row index of the cell
193
+ * @param {number} columnIndex - column index of the cell
194
+ * @returns {boolean} - true - if children, false if main one
195
+ */
196
+ isChildren(rowIndex, columnIndex) {
197
+ const item = this.getItem(rowIndex, columnIndex);
198
+ if (item) {
199
+ return item.isChild();
200
+ // eslint-disable-next-line max-lines
201
+ }
202
+ if (typeof this.deep === 'number') {
203
+ if ((this.isVertical ? columnIndex : rowIndex) < this.deep) {
204
+ return true;
205
+ }
206
+ }
207
+ throw new Error(`Item "${rowIndex}-${columnIndex}" does not found in TreeService`);
208
+ }
209
+ /**
210
+ * Defines if cell with (rowIndex, columnIndex) coordinate has children column/row cells or not
211
+ *
212
+ * @param {number} rowIndex - row index of the cell
213
+ * @param {number} columnIndex - column index of the cell
214
+ * @returns {boolean} - true - has children column/row cells, false - does not have
215
+ */
216
+ hasChildren(rowIndex, columnIndex) {
217
+ const item = this.getItem(rowIndex, columnIndex);
218
+ if (item) {
219
+ return item.hasChildren();
220
+ }
221
+ throw new Error(`Item "${rowIndex}-${columnIndex}" does not found in TreeService`);
222
+ }
223
+ /**
224
+ * Updates merge object for the cell if it has children cells
225
+ *
226
+ * @param {number} rowIndex - cell row index
227
+ * @param {number} columnIndex - cell column index
228
+ * @returns {object} - new merge object
229
+ */
230
+ getMainCellSpans(rowIndex, columnIndex) {
231
+ const spans = {};
232
+ const mainItem = this.getItem(rowIndex, columnIndex);
233
+ if (mainItem && mainItem.hasColCell()) {
234
+ spans.colSpan = mainItem.getColCell().length + 1;
235
+ }
236
+ if (mainItem && mainItem.hasRowCell()) {
237
+ spans.rowSpan = mainItem.getRowCell().length + 1;
238
+ }
239
+ return spans;
240
+ }
241
+ /**
242
+ * Align start index in case of long merged cell
243
+ *
244
+ * @param {number} startIndex - initial start index
245
+ * @param {boolean} isVertical - defines if it is vertical grid or not
246
+ * @returns {number} - new start index
247
+ */
248
+ alignStartIndex(startIndex, isVertical = false) {
249
+ let row = 0;
250
+ let col = startIndex;
251
+ if (isVertical) {
252
+ row = startIndex;
253
+ col = 0;
254
+ }
255
+ if (this.isVertical === isVertical) {
256
+ let curItem = this.getItem(row, col);
257
+ if (curItem && curItem.isChild()) {
258
+ curItem = this.getItemByKey(curItem.parent || '');
259
+ }
260
+ if (curItem) {
261
+ return isVertical ? curItem.rowIndex : curItem.colIndex;
262
+ }
263
+ }
264
+ return startIndex;
265
+ }
266
+ /**
267
+ * Align stop index in case of long merged cell
268
+ *
269
+ * @param {number} stopIndex - initial stop index
270
+ * @param {boolean} isVertical - defines if it is vertical grid or not
271
+ * @returns {number} - new stop index
272
+ */
273
+ alignStopIndex(stopIndex, isVertical = false) {
274
+ let row = 0;
275
+ let col = stopIndex;
276
+ if (isVertical) {
277
+ row = stopIndex;
278
+ col = 0;
279
+ }
280
+ if (this.isVertical === isVertical) {
281
+ let curItem = this.getItem(row, col);
282
+ if (curItem && curItem.isChild()) {
283
+ curItem = this.getItemByKey(curItem.parent || '');
284
+ }
285
+ if (curItem) {
286
+ return isVertical ? curItem.getStopRowIndex() : curItem.getStopColIndex();
287
+ }
288
+ }
289
+ return stopIndex;
290
+ }
291
+ /**
292
+ * Returns number of last children for the tree
293
+ *
294
+ * @param {Array<TreeNode> | TreeNode} item - tree node or list of nodes
295
+ * @param {{ callCount: number, clearCache: boolean }} options - options for state
296
+ * @returns {number} - count of last children
297
+ */
298
+ getTreeChildLength(item = index_js_1.treeNode.getChildren(this.tree), options) {
299
+ return index_js_1.treeNode.getChildLength(item, options);
300
+ }
301
+ /**
302
+ * Returns deep level of the tree
303
+ *
304
+ * @param {Array<TreeNode> | TreeNode} item - tree node or list of nodes
305
+ * @param {{ callCount: number, clearCache: boolean }} options - options for inner state
306
+ * @returns {number} - count of last children
307
+ */
308
+ getTreeDeepsLength(item = index_js_1.treeNode.getChildren(this.tree), options) {
309
+ if (typeof this.deep !== 'undefined' && this.deep !== undefined) {
310
+ return this.deep;
311
+ }
312
+ return index_js_1.treeNode.getDeepLength(item, options);
313
+ }
314
+ /**
315
+ * Returns array of last tree nodes
316
+ *
317
+ * @returns {Array<TreeNode>} - list of tree nodes
318
+ */
319
+ getLastLevelNodes() {
320
+ return this.lastLevel;
321
+ }
322
+ /**
323
+ * Extract 2D array of data base on columnsTreeService
324
+ *
325
+ * @param {TreeServiceI} columnsTreeService - tree service according to which align the data
326
+ * @returns {Array<Array<any>>} - 2D array of data
327
+ */
328
+ extractData(columnsTreeService) {
329
+ if (!columnsTreeService) {
330
+ return [];
331
+ }
332
+ const columsLastNodes = columnsTreeService.getLastLevelNodes();
333
+ const sortIndexes = columsLastNodes.map((node) => node.index);
334
+ return this.getLastLevelNodes().map((node) => {
335
+ if (typeof node.data === 'undefined') {
336
+ return [node.data];
337
+ }
338
+ if (sortIndexes) {
339
+ return sortIndexes.map((index) => {
340
+ let data;
341
+ if (typeof index !== 'undefined' && node.data) {
342
+ data = node.data[index];
343
+ }
344
+ return data;
345
+ });
346
+ }
347
+ return node.data;
348
+ });
349
+ }
350
+ /**
351
+ * Returns cell meta information
352
+ *
353
+ * @param {number} rowIndex - cell row index
354
+ * @param {number} columnIndex - cell column index
355
+ * @param {{ to: number }} [options] - additional configuration options
356
+ * @returns {{levels: Array<string>, siblings: Array<string>}} - meta information
357
+ */
358
+ // eslint-disable-next-line max-lines-per-function,sonarjs/cognitive-complexity
359
+ getMetadata(rowIndex, columnIndex, options) {
360
+ const levelCount = this.getTreeDeepsLength();
361
+ if (rowIndex === Infinity) {
362
+ // eslint-disable-next-line no-param-reassign
363
+ rowIndex = levelCount ? levelCount - 1 : levelCount;
364
+ }
365
+ if (columnIndex === Infinity) {
366
+ // eslint-disable-next-line no-param-reassign
367
+ columnIndex = levelCount ? levelCount - 1 : levelCount;
368
+ }
369
+ const key = `${rowIndex}-${columnIndex}`;
370
+ if (this.metadataCache[key]) {
371
+ return this.metadataCache[key];
372
+ }
373
+ let mapItem = this.getItemByKey(key);
374
+ if (!mapItem) {
375
+ throw new Error(`Can not find metadata info for ${key} cell`);
376
+ }
377
+ let nodeItem = mapItem ? mapItem.node : undefined;
378
+ // looking for parent
379
+ if (!nodeItem) {
380
+ mapItem = this.getItemByKey(mapItem.parent || '');
381
+ }
382
+ if (!mapItem) {
383
+ throw new Error(`Can not find metadata info for parent ${key} cell`);
384
+ }
385
+ nodeItem = mapItem ? mapItem.node : undefined;
386
+ const nextMapItem = this.getItemByKey(`${rowIndex + 1}-${columnIndex}`);
387
+ const nextNodeItem = nextMapItem ? nextMapItem.node : undefined;
388
+ // levels info
389
+ const level = (nodeItem && nodeItem.level) || 0;
390
+ const lastLevel = this.isVertical ? mapItem.getStopColIndex() : mapItem.getStopRowIndex();
391
+ // siblings info
392
+ let { indexInParent, siblingCount } = mapItem.getIndexInParent();
393
+ let lastIndexInParent = indexInParent;
394
+ // fix sibling for partial tree top/first level
395
+ if (level === 0) {
396
+ siblingCount = this.getTreeChildLength();
397
+ indexInParent = this.isVertical ? mapItem.rowIndex : mapItem.colIndex;
398
+ lastIndexInParent =
399
+ indexInParent +
400
+ (this.isVertical ? mapItem.getRowCell().length : mapItem.getColCell().length);
401
+ }
402
+ if (options) {
403
+ // pagination
404
+ const maxCount = options.to - options.from;
405
+ if (siblingCount <= maxCount && lastIndexInParent > maxCount - 1) {
406
+ lastIndexInParent = maxCount - 1;
407
+ }
408
+ }
409
+ const data = {
410
+ levels: [],
411
+ siblings: [],
412
+ root: undefined,
413
+ parent: undefined,
414
+ valueNode: this.valueNode,
415
+ nextNode: nextNodeItem,
416
+ };
417
+ const { indexDivergence } = nodeItem || {};
418
+ if (typeof indexDivergence === 'number') {
419
+ const siblingsStatus = indexDivergence === 0 ? constants_js_1.Position.EVEN : constants_js_1.Position.ODD;
420
+ data.siblings.push(siblingsStatus);
421
+ }
422
+ if (level === 0) {
423
+ data.levels.push(constants_js_1.Position.FIRST);
424
+ }
425
+ if (lastLevel === levelCount - 1) {
426
+ data.levels.push(constants_js_1.Position.LAST);
427
+ }
428
+ if (indexInParent === 0) {
429
+ data.siblings.push(constants_js_1.Position.FIRST);
430
+ }
431
+ if (lastIndexInParent === siblingCount - 1) {
432
+ data.siblings.push(constants_js_1.Position.LAST);
433
+ }
434
+ // get root node
435
+ if (nodeItem && level !== 0) {
436
+ const rootRowIndex = this.isVertical ? rowIndex : 0;
437
+ const rootColumnIndex = this.isVertical ? 0 : columnIndex;
438
+ data.root = this.getMetadata(rootRowIndex, rootColumnIndex, options);
439
+ }
440
+ const parentMapItem = this.getItemByKey(mapItem.parent || '');
441
+ // get parent node
442
+ if (parentMapItem && level !== 0) {
443
+ data.parent = this.getMetadata(parentMapItem.rowIndex, parentMapItem.colIndex, options);
444
+ }
445
+ if (options) {
446
+ // pagination
447
+ const startIndex = this.isVertical ? mapItem.rowIndex : mapItem.colIndex;
448
+ const stopIndex = this.isVertical ? mapItem.getStopRowIndex() : mapItem.getStopColIndex();
449
+ let parentStopIndex;
450
+ if (parentMapItem) {
451
+ parentStopIndex = this.isVertical
452
+ ? parentMapItem.getStopRowIndex()
453
+ : parentMapItem.getStopColIndex();
454
+ }
455
+ if (parentStopIndex !== undefined && parentStopIndex >= options.to - options.from) {
456
+ // item is cut
457
+ if (stopIndex >= options.to - options.from - 1 && !data.siblings.includes(constants_js_1.Position.LAST)) {
458
+ data.siblings.push(constants_js_1.Position.LAST);
459
+ }
460
+ }
461
+ if (startIndex === 0 && !data.siblings.includes(constants_js_1.Position.FIRST)) {
462
+ // in paginated case we always has min cell
463
+ data.siblings.push(constants_js_1.Position.FIRST);
464
+ }
465
+ }
466
+ this.metadataCache[key] = data;
467
+ return data;
468
+ }
469
+ /**
470
+ * Sets value node when it's single
471
+ *
472
+ * @param {TreeNode} valueNode - values measure node
473
+ * @returns {void}
474
+ */
475
+ setValueNode(valueNode) {
476
+ if (typeof valueNode === 'object') {
477
+ this.valueNode = valueNode;
478
+ }
479
+ }
480
+ /**
481
+ * Fills cache object with nodes by appropriate deep level
482
+ *
483
+ * @param {Array<TreeNode>} list - list of nodes to cache
484
+ * @param {Array<Array<TreeNode>>} cache - cache object
485
+ * @param {{level: number }} options - internal recursive state
486
+ * @returns {Array<Array<TreeNode>>} - cache object
487
+ *
488
+ * @private
489
+ */
490
+ cacheLevels(list, cache = [], options = { level: 0 }) {
491
+ const { level } = options;
492
+ list.forEach((item) => {
493
+ if (!cache[level]) {
494
+ // eslint-disable-next-line no-param-reassign
495
+ cache[level] = [];
496
+ }
497
+ index_js_1.treeNode.setLevel(item, level);
498
+ cache[level].push(item);
499
+ if (index_js_1.treeNode.hasChildren(item)) {
500
+ const childLevel = level + 1;
501
+ this.cacheLevels(index_js_1.treeNode.getChildren(item), cache, { level: childLevel });
502
+ }
503
+ else {
504
+ this.lastLevel.push(item);
505
+ }
506
+ });
507
+ return cache;
508
+ }
509
+ /**
510
+ * Fill horizontal grid map according to tree structure
511
+ *
512
+ * @param {Array<TreeNode>} children - list of tree nodes
513
+ * @param {number} rows - deep level rows
514
+ * @param {object} map - map object to fill
515
+ * @param {{parentColIndex: number, prevChildren: number}} initState - state object for
516
+ * recursive calls
517
+ * @returns {object} - map object
518
+ *
519
+ * @private
520
+ */
521
+ fillMap(children, rows, map = {}, initState) {
522
+ const state = initState || {
523
+ parentRowIndex: 0,
524
+ parentColIndex: 0,
525
+ prevChildren: 0,
526
+ parentKey: '',
527
+ };
528
+ const childCount = children.length;
529
+ children.forEach((item, colIndex) => {
530
+ const { parentRowIndex, parentColIndex, prevChildren, parentKey } = state;
531
+ const rowIndex = index_js_1.treeNode.getLevel(item);
532
+ const rowStart = rowIndex + parentRowIndex;
533
+ const colStart = colIndex + parentColIndex + prevChildren;
534
+ const mainKey = keyCreator(rowStart, colStart);
535
+ const mapMainItem = this.createTreeCellMap({
536
+ rowIndex: rowStart,
537
+ colIndex: colStart,
538
+ node: item,
539
+ parent: parentKey,
540
+ });
541
+ mapMainItem.setIndexInParent(colIndex, childCount);
542
+ map[mainKey] = mapMainItem;
543
+ let col = 0;
544
+ let row = 0;
545
+ if (index_js_1.treeNode.hasChildren(item)) {
546
+ col = this.getTreeChildLength(item);
547
+ if (typeof item.minLevel === 'number') {
548
+ // min level in case values offset
549
+ row = item.minLevel + 1 - rowStart || 0;
550
+ }
551
+ }
552
+ else {
553
+ row = (rows || 0) - (rowStart || 0);
554
+ }
555
+ if (col > 1 || row > 1) {
556
+ // if has merged cells
557
+ this.fillChildMap(map, mainKey, rowStart, colStart, row, col);
558
+ }
559
+ if (index_js_1.treeNode.hasChildren(item)) {
560
+ const childState = Object.assign(Object.assign({}, state), { parentRowIndex: row > 1 ? row - 1 : 0, parentColIndex: colIndex + parentColIndex, parentKey: mainKey });
561
+ this.fillMap(index_js_1.treeNode.getChildren(item), rows, map, childState);
562
+ if (col > 1) {
563
+ state.prevChildren += col - 1;
564
+ }
565
+ }
566
+ });
567
+ return map;
568
+ }
569
+ /**
570
+ * Fill vertical grid map according to tree structure
571
+ *
572
+ * @param {Array<TreeNode>} children - list of tree nodes
573
+ * @param {number} cols - deep level columns
574
+ * @param {TreeCellMapCache} map - map object to fill
575
+ * @param {FillMapState} initState - state object for
576
+ * recursive calls
577
+ * @returns {object} - map object
578
+ *
579
+ * @private
580
+ */
581
+ fillMapVertical(children, cols, map = {}, initState) {
582
+ const state = initState || {
583
+ parentRowIndex: 0,
584
+ parentColIndex: 0,
585
+ prevChildren: 0,
586
+ parentKey: '',
587
+ };
588
+ const childCount = children.length;
589
+ children.forEach((item, rowIndex) => {
590
+ if (item.isMapped) {
591
+ state.parentRowIndex += index_js_1.treeNode.getChildLength(item) - 1;
592
+ return;
593
+ }
594
+ item.isMapped = true;
595
+ const { parentRowIndex, prevChildren, parentKey } = state;
596
+ const colIndex = index_js_1.treeNode.getLevel(item);
597
+ const rowStart = rowIndex + parentRowIndex + prevChildren;
598
+ const mainKey = keyCreator(rowStart, colIndex);
599
+ const mapMainItem = this.createTreeCellMap({
600
+ rowIndex: rowStart,
601
+ colIndex,
602
+ node: item,
603
+ parent: parentKey,
604
+ });
605
+ mapMainItem.setIndexInParent(rowIndex, childCount);
606
+ map[mainKey] = mapMainItem;
607
+ let col = 0;
608
+ let row = 0;
609
+ if (index_js_1.treeNode.hasChildren(item)) {
610
+ row = this.getTreeChildLength(item);
611
+ }
612
+ else {
613
+ col = (cols || 0) - (colIndex || 0);
614
+ }
615
+ if (col > 1 || row > 1) {
616
+ // if has merged cells
617
+ this.fillChildMap(map, mainKey, rowStart, colIndex, row, col);
618
+ }
619
+ if (index_js_1.treeNode.hasChildren(item)) {
620
+ const childState = Object.assign(Object.assign({}, state), { parentRowIndex: rowIndex + parentRowIndex, parentKey: mainKey });
621
+ this.fillMapVertical(index_js_1.treeNode.getChildren(item), cols, map, childState);
622
+ if (row > 1) {
623
+ state.prevChildren += row - 1;
624
+ }
625
+ }
626
+ });
627
+ return map;
628
+ }
629
+ /**
630
+ * Fill child items in map according to main cell merged row and col
631
+ *
632
+ * @param {object} map - map object to fill
633
+ * @param {string} mainKey - main cell key in map
634
+ * @param {number} rowStart - main cell row index
635
+ * @param {number} colStart - main cell column index
636
+ * @param {number} row - merged rows count
637
+ * @param {number} col - merged columns count
638
+ * @returns {void}
639
+ *
640
+ * @private
641
+ */
642
+ fillChildMap(map, mainKey, rowStart, colStart, row, col) {
643
+ const mapMainItem = map[mainKey];
644
+ const rowsCount = Math.max(1, row);
645
+ const colsCount = Math.max(1, col);
646
+ Array.from(Array(rowsCount)).forEach((r, rowAddIndex) => {
647
+ Array.from(Array(colsCount)).forEach((c, colAddIndex) => {
648
+ if (rowAddIndex === 0 && colAddIndex === 0) {
649
+ // skip main item
650
+ return;
651
+ }
652
+ const childRowIndex = rowStart + rowAddIndex;
653
+ const childColIndex = colStart + colAddIndex;
654
+ const childKey = keyCreator(childRowIndex, childColIndex);
655
+ const childColItem = this.createTreeCellMap({
656
+ rowIndex: childRowIndex,
657
+ colIndex: childColIndex,
658
+ parent: mainKey,
659
+ });
660
+ map[childKey] = childColItem;
661
+ if (rowAddIndex !== 0 && colAddIndex !== 0) {
662
+ // skip middle items
663
+ return;
664
+ }
665
+ if (colAddIndex === 0) {
666
+ mapMainItem.addRowCell(childColItem);
667
+ }
668
+ if (rowAddIndex === 0) {
669
+ mapMainItem.addColCell(childColItem);
670
+ }
671
+ });
672
+ });
673
+ }
674
+ /**
675
+ * Creates TreeCellMap instance
676
+ *
677
+ * @param {object} options - instance options
678
+ * @param {number} options.rowIndex - row index of cell map instance
679
+ * @param {number} options.colIndex - row index of cell map instance
680
+ * @param {TreeNode} [options.node] - TreeNode for main cell
681
+ * @param {string} [options.parent] - parent key for child item
682
+ * @returns {TreeCellMap} - TreeCellMap instance
683
+ *
684
+ * @private
685
+ */
686
+ // eslint-disable-next-line class-methods-use-this
687
+ createTreeCellMap({ rowIndex, colIndex, node, parent, }) {
688
+ return new TreeCellMap_js_1.TreeCellMap(rowIndex, colIndex, node, parent);
689
+ }
690
+ /**
691
+ * Returns TreeCellMapI item by key string
692
+ *
693
+ * @param {string} key - map key string
694
+ * @returns {TreeCellMapI|undefined} - TreeCellMapI instance or undefined
695
+ *
696
+ * @private
697
+ */
698
+ getItemByKey(key) {
699
+ return this.map[key];
700
+ }
701
+ /**
702
+ * Returns TreeCellMapI item by (row, col) coordinate
703
+ *
704
+ * @param {number} row - cell row index
705
+ * @param {number} col - cell column index
706
+ * @returns {TreeCellMapI|undefined} - TreeCellMapI instance or undefined
707
+ *
708
+ * @private
709
+ */
710
+ getItem(row, col) {
711
+ const key = keyCreator(row, col);
712
+ return this.getItemByKey(key);
713
+ }
714
+ }
715
+ exports.AbstractTreeService = AbstractTreeService;
716
+ exports.default = AbstractTreeService;