@deephaven/iris-grid 0.13.3-beta.2 → 0.13.5

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 (184) hide show
  1. package/dist/AdvancedFilterCreator.d.ts +63 -69
  2. package/dist/AdvancedFilterCreator.d.ts.map +1 -1
  3. package/dist/AdvancedFilterCreator.js +73 -79
  4. package/dist/AdvancedFilterCreator.js.map +1 -1
  5. package/dist/AdvancedFilterCreatorSelectValue.d.ts +45 -45
  6. package/dist/AdvancedFilterCreatorSelectValue.d.ts.map +1 -1
  7. package/dist/AdvancedFilterCreatorSelectValue.js +36 -32
  8. package/dist/AdvancedFilterCreatorSelectValue.js.map +1 -1
  9. package/dist/AdvancedFilterCreatorSelectValueList.d.ts +52 -47
  10. package/dist/AdvancedFilterCreatorSelectValueList.d.ts.map +1 -1
  11. package/dist/AdvancedFilterCreatorSelectValueList.js +39 -24
  12. package/dist/AdvancedFilterCreatorSelectValueList.js.map +1 -1
  13. package/dist/ColumnStatistics.d.ts +22 -34
  14. package/dist/ColumnStatistics.d.ts.map +1 -1
  15. package/dist/ColumnStatistics.js +12 -8
  16. package/dist/ColumnStatistics.js.map +1 -1
  17. package/dist/CrossColumnSearch.d.ts +24 -26
  18. package/dist/CrossColumnSearch.d.ts.map +1 -1
  19. package/dist/CrossColumnSearch.js +13 -9
  20. package/dist/CrossColumnSearch.js.map +1 -1
  21. package/dist/FilterInputField.d.ts +51 -48
  22. package/dist/FilterInputField.d.ts.map +1 -1
  23. package/dist/FilterInputField.js +27 -30
  24. package/dist/FilterInputField.js.map +1 -1
  25. package/dist/IrisGrid.d.ts +453 -409
  26. package/dist/IrisGrid.d.ts.map +1 -1
  27. package/dist/IrisGrid.js +449 -514
  28. package/dist/IrisGrid.js.map +1 -1
  29. package/dist/IrisGridCellOverflowModal.d.ts +1 -1
  30. package/dist/IrisGridCellOverflowModal.d.ts.map +1 -1
  31. package/dist/IrisGridCellOverflowModal.js.map +1 -1
  32. package/dist/IrisGridCopyHandler.d.ts +46 -52
  33. package/dist/IrisGridCopyHandler.d.ts.map +1 -1
  34. package/dist/IrisGridCopyHandler.js +38 -22
  35. package/dist/IrisGridCopyHandler.js.map +1 -1
  36. package/dist/IrisGridMetricCalculator.d.ts +4 -5
  37. package/dist/IrisGridMetricCalculator.d.ts.map +1 -1
  38. package/dist/IrisGridMetricCalculator.js +1 -5
  39. package/dist/IrisGridMetricCalculator.js.map +1 -1
  40. package/dist/IrisGridModel.d.ts +35 -37
  41. package/dist/IrisGridModel.d.ts.map +1 -1
  42. package/dist/IrisGridModel.js +3 -19
  43. package/dist/IrisGridModel.js.map +1 -1
  44. package/dist/IrisGridModelFactory.d.ts +5 -7
  45. package/dist/IrisGridModelFactory.d.ts.map +1 -1
  46. package/dist/IrisGridModelFactory.js +5 -5
  47. package/dist/IrisGridModelFactory.js.map +1 -1
  48. package/dist/IrisGridModelUpdater.d.ts +11 -13
  49. package/dist/IrisGridModelUpdater.d.ts.map +1 -1
  50. package/dist/IrisGridModelUpdater.js.map +1 -1
  51. package/dist/IrisGridPartitionSelector.d.ts +39 -38
  52. package/dist/IrisGridPartitionSelector.d.ts.map +1 -1
  53. package/dist/IrisGridPartitionSelector.js +24 -18
  54. package/dist/IrisGridPartitionSelector.js.map +1 -1
  55. package/dist/IrisGridProxyModel.d.ts +32 -111
  56. package/dist/IrisGridProxyModel.d.ts.map +1 -1
  57. package/dist/IrisGridProxyModel.js +170 -212
  58. package/dist/IrisGridProxyModel.js.map +1 -1
  59. package/dist/IrisGridRenderer.d.ts +31 -59
  60. package/dist/IrisGridRenderer.d.ts.map +1 -1
  61. package/dist/IrisGridRenderer.js +46 -92
  62. package/dist/IrisGridRenderer.js.map +1 -1
  63. package/dist/IrisGridTableModel.d.ts +147 -48
  64. package/dist/IrisGridTableModel.d.ts.map +1 -1
  65. package/dist/IrisGridTableModel.js +1381 -58
  66. package/dist/IrisGridTableModel.js.map +1 -1
  67. package/dist/IrisGridTestUtils.d.ts +14 -18
  68. package/dist/IrisGridTestUtils.d.ts.map +1 -1
  69. package/dist/IrisGridTestUtils.js +1 -29
  70. package/dist/IrisGridTestUtils.js.map +1 -1
  71. package/dist/IrisGridTheme.d.ts +3 -35
  72. package/dist/IrisGridTheme.d.ts.map +1 -1
  73. package/dist/IrisGridTheme.js.map +1 -1
  74. package/dist/IrisGridTreeTableModel.d.ts +7 -26
  75. package/dist/IrisGridTreeTableModel.d.ts.map +1 -1
  76. package/dist/IrisGridTreeTableModel.js +14 -24
  77. package/dist/IrisGridTreeTableModel.js.map +1 -1
  78. package/dist/IrisGridUtils.d.ts +162 -257
  79. package/dist/IrisGridUtils.d.ts.map +1 -1
  80. package/dist/IrisGridUtils.js +95 -132
  81. package/dist/IrisGridUtils.js.map +1 -1
  82. package/dist/MissingKeyError.d.ts +3 -5
  83. package/dist/MissingKeyError.d.ts.map +1 -1
  84. package/dist/MissingKeyError.js.map +1 -1
  85. package/dist/PartitionSelectorSearch.d.ts +40 -61
  86. package/dist/PartitionSelectorSearch.d.ts.map +1 -1
  87. package/dist/PartitionSelectorSearch.js +15 -25
  88. package/dist/PartitionSelectorSearch.js.map +1 -1
  89. package/dist/PendingDataBottomBar.d.ts +6 -3
  90. package/dist/PendingDataBottomBar.d.ts.map +1 -1
  91. package/dist/PendingDataBottomBar.js.map +1 -1
  92. package/dist/TableViewportUpdater.d.ts +55 -39
  93. package/dist/TableViewportUpdater.d.ts.map +1 -1
  94. package/dist/TableViewportUpdater.js +64 -42
  95. package/dist/TableViewportUpdater.js.map +1 -1
  96. package/dist/TreeTableViewportUpdater.d.ts +37 -29
  97. package/dist/TreeTableViewportUpdater.d.ts.map +1 -1
  98. package/dist/TreeTableViewportUpdater.js +50 -39
  99. package/dist/TreeTableViewportUpdater.js.map +1 -1
  100. package/dist/index.d.ts +0 -9
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +0 -9
  103. package/dist/index.js.map +1 -1
  104. package/dist/mousehandlers/IrisGridCellOverflowMouseHandler.d.ts.map +1 -1
  105. package/dist/mousehandlers/IrisGridCellOverflowMouseHandler.js.map +1 -1
  106. package/dist/mousehandlers/IrisGridColumnSelectMouseHandler.d.ts +1 -1
  107. package/dist/mousehandlers/IrisGridColumnSelectMouseHandler.d.ts.map +1 -1
  108. package/dist/mousehandlers/IrisGridColumnSelectMouseHandler.js +0 -2
  109. package/dist/mousehandlers/IrisGridColumnSelectMouseHandler.js.map +1 -1
  110. package/dist/mousehandlers/IrisGridColumnTooltipMouseHandler.js +1 -1
  111. package/dist/mousehandlers/IrisGridColumnTooltipMouseHandler.js.map +1 -1
  112. package/dist/mousehandlers/IrisGridContextMenuHandler.d.ts +130 -41
  113. package/dist/mousehandlers/IrisGridContextMenuHandler.d.ts.map +1 -1
  114. package/dist/mousehandlers/IrisGridContextMenuHandler.js +317 -426
  115. package/dist/mousehandlers/IrisGridContextMenuHandler.js.map +1 -1
  116. package/dist/mousehandlers/IrisGridFilterMouseHandler.d.ts.map +1 -1
  117. package/dist/mousehandlers/IrisGridFilterMouseHandler.js +2 -2
  118. package/dist/mousehandlers/IrisGridFilterMouseHandler.js.map +1 -1
  119. package/dist/mousehandlers/IrisGridSortMouseHandler.js +1 -1
  120. package/dist/mousehandlers/IrisGridSortMouseHandler.js.map +1 -1
  121. package/dist/mousehandlers/PendingMouseHandler.d.ts +4 -8
  122. package/dist/mousehandlers/PendingMouseHandler.d.ts.map +1 -1
  123. package/dist/mousehandlers/PendingMouseHandler.js +5 -4
  124. package/dist/mousehandlers/PendingMouseHandler.js.map +1 -1
  125. package/dist/sidebar/ChartBuilder.d.ts +33 -48
  126. package/dist/sidebar/ChartBuilder.d.ts.map +1 -1
  127. package/dist/sidebar/ChartBuilder.js +27 -28
  128. package/dist/sidebar/ChartBuilder.js.map +1 -1
  129. package/dist/sidebar/CustomColumnBuilder.d.ts +41 -51
  130. package/dist/sidebar/CustomColumnBuilder.d.ts.map +1 -1
  131. package/dist/sidebar/CustomColumnBuilder.js +18 -22
  132. package/dist/sidebar/CustomColumnBuilder.js.map +1 -1
  133. package/dist/sidebar/CustomColumnInput.d.ts +36 -26
  134. package/dist/sidebar/CustomColumnInput.d.ts.map +1 -1
  135. package/dist/sidebar/CustomColumnInput.js +20 -11
  136. package/dist/sidebar/CustomColumnInput.js.map +1 -1
  137. package/dist/sidebar/InputEditor.d.ts +35 -34
  138. package/dist/sidebar/InputEditor.d.ts.map +1 -1
  139. package/dist/sidebar/InputEditor.js +24 -43
  140. package/dist/sidebar/InputEditor.js.map +1 -1
  141. package/dist/sidebar/RollupRows.d.ts +52 -67
  142. package/dist/sidebar/RollupRows.d.ts.map +1 -1
  143. package/dist/sidebar/RollupRows.js +53 -51
  144. package/dist/sidebar/RollupRows.js.map +1 -1
  145. package/dist/sidebar/SelectDistinctBuilder.d.ts +21 -27
  146. package/dist/sidebar/SelectDistinctBuilder.d.ts.map +1 -1
  147. package/dist/sidebar/SelectDistinctBuilder.js +10 -6
  148. package/dist/sidebar/SelectDistinctBuilder.js.map +1 -1
  149. package/dist/sidebar/TableCsvExporter.d.ts +39 -42
  150. package/dist/sidebar/TableCsvExporter.d.ts.map +1 -1
  151. package/dist/sidebar/TableCsvExporter.js +20 -12
  152. package/dist/sidebar/TableCsvExporter.js.map +1 -1
  153. package/dist/sidebar/TableSaver.d.ts +60 -59
  154. package/dist/sidebar/TableSaver.d.ts.map +1 -1
  155. package/dist/sidebar/TableSaver.js +68 -154
  156. package/dist/sidebar/TableSaver.js.map +1 -1
  157. package/dist/sidebar/VisibilityOrderingBuilder.d.ts +45 -56
  158. package/dist/sidebar/VisibilityOrderingBuilder.d.ts.map +1 -1
  159. package/dist/sidebar/VisibilityOrderingBuilder.js +29 -34
  160. package/dist/sidebar/VisibilityOrderingBuilder.js.map +1 -1
  161. package/dist/sidebar/aggregations/Aggregations.d.ts.map +1 -1
  162. package/dist/sidebar/aggregations/Aggregations.js.map +1 -1
  163. package/dist/sidebar/conditional-formatting/ConditionalFormattingMenu.d.ts +1 -2
  164. package/dist/sidebar/conditional-formatting/ConditionalFormattingMenu.d.ts.map +1 -1
  165. package/dist/sidebar/conditional-formatting/ConditionalFormattingMenu.js.map +1 -1
  166. package/dist/sidebar/conditional-formatting/ConditionalFormattingUtils.d.ts +5 -6
  167. package/dist/sidebar/conditional-formatting/ConditionalFormattingUtils.d.ts.map +1 -1
  168. package/dist/sidebar/conditional-formatting/ConditionalFormattingUtils.js +0 -5
  169. package/dist/sidebar/conditional-formatting/ConditionalFormattingUtils.js.map +1 -1
  170. package/dist/sidebar/icons/index.d.ts +7 -7
  171. package/dist/sidebar/icons/index.d.ts.map +1 -1
  172. package/dist/sidebar/icons/index.js.map +1 -1
  173. package/dist/sidebar/index.d.ts +12 -12
  174. package/dist/sidebar/index.d.ts.map +1 -1
  175. package/dist/sidebar/index.js.map +1 -1
  176. package/package.json +16 -17
  177. package/dist/CommonTypes.d.ts +0 -58
  178. package/dist/CommonTypes.d.ts.map +0 -1
  179. package/dist/CommonTypes.js +0 -2
  180. package/dist/CommonTypes.js.map +0 -1
  181. package/dist/IrisGridTableModelTemplate.d.ts +0 -219
  182. package/dist/IrisGridTableModelTemplate.d.ts.map +0 -1
  183. package/dist/IrisGridTableModelTemplate.js +0 -1623
  184. package/dist/IrisGridTableModelTemplate.js.map +0 -1
@@ -1,24 +1,14 @@
1
1
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
2
 
3
3
  import { PureComponent } from 'react';
4
- import { WritableStream as ponyfillWritableStream } from 'web-streams-polyfill/ponyfill';
4
+ import PropTypes from 'prop-types';
5
+ import { WritableStream as ponyfillWritableStream } from 'web-streams-polyfill/dist/ponyfill.js';
5
6
  import dh from '@deephaven/jsapi-shim';
7
+ import { Formatter, FormatterUtils } from '@deephaven/jsapi-utils';
6
8
  import Log from '@deephaven/log';
7
9
  import { memoizeClear } from '@deephaven/grid';
8
- import { FormatterUtils } from '@deephaven/jsapi-utils';
9
- import { PromiseUtils, assertNotNull } from '@deephaven/utils';
10
+ import { PromiseUtils } from '@deephaven/utils';
10
11
  var log = Log.module('TableSaver');
11
-
12
- function isUpdateEventData(data) {
13
- return data.added !== undefined;
14
- }
15
-
16
- function assertIsUpdateEventData(data) {
17
- if (!isUpdateEventData(data)) {
18
- throw new Error('event is not UpdateEventData');
19
- }
20
- }
21
-
22
12
  export default class TableSaver extends PureComponent {
23
13
  static csvEscapeString(str) {
24
14
  return "\"".concat(str.replace(/"/g, '""'), "\"");
@@ -27,54 +17,6 @@ export default class TableSaver extends PureComponent {
27
17
  constructor(props) {
28
18
  super(props);
29
19
 
30
- _defineProperty(this, "sw", void 0);
31
-
32
- _defineProperty(this, "port", void 0);
33
-
34
- _defineProperty(this, "fileWriter", void 0);
35
-
36
- _defineProperty(this, "table", void 0);
37
-
38
- _defineProperty(this, "tableSubscription", void 0);
39
-
40
- _defineProperty(this, "columns", void 0);
41
-
42
- _defineProperty(this, "fileName", void 0);
43
-
44
- _defineProperty(this, "chunkRows", void 0);
45
-
46
- _defineProperty(this, "gridRanges", void 0);
47
-
48
- _defineProperty(this, "gridRangeCounter", void 0);
49
-
50
- _defineProperty(this, "rangedSnapshotsTotal", void 0);
51
-
52
- _defineProperty(this, "rangedSnapshotCounter", void 0);
53
-
54
- _defineProperty(this, "snapshotsTotal", void 0);
55
-
56
- _defineProperty(this, "snapshotCounter", void 0);
57
-
58
- _defineProperty(this, "snapshotsBuffer", void 0);
59
-
60
- _defineProperty(this, "currentSnapshotIndex", void 0);
61
-
62
- _defineProperty(this, "snapshotPending", void 0);
63
-
64
- _defineProperty(this, "cancelableSnapshots", void 0);
65
-
66
- _defineProperty(this, "WritableStream", window.WritableStream || ponyfillWritableStream);
67
-
68
- _defineProperty(this, "streamTimeout", void 0);
69
-
70
- _defineProperty(this, "snapshotHandlerTimeout", void 0);
71
-
72
- _defineProperty(this, "downloadStartTime", void 0);
73
-
74
- _defineProperty(this, "iframes", void 0);
75
-
76
- _defineProperty(this, "useBlobFallback", void 0);
77
-
78
20
  _defineProperty(this, "getCachedCustomColumnFormatFlag", memoizeClear(FormatterUtils.isCustomColumnFormatDefined, {
79
21
  max: 10000
80
22
  }));
@@ -83,6 +25,14 @@ export default class TableSaver extends PureComponent {
83
25
  this.handleSnapshotResolved = this.handleSnapshotResolved.bind(this);
84
26
  this.handleDownloadTimeout = this.handleDownloadTimeout.bind(this);
85
27
  this.state = {};
28
+ this.sw = null;
29
+ this.port = null;
30
+ this.fileWriter = null;
31
+ this.table = null;
32
+ this.tableSubscription = null;
33
+ this.columns = null;
34
+ this.fileName = null;
35
+ this.chunkRows = null;
86
36
  this.gridRanges = [];
87
37
  this.gridRangeCounter = 0;
88
38
  this.rangedSnapshotsTotal = [];
@@ -99,8 +49,11 @@ export default class TableSaver extends PureComponent {
99
49
  // If the stream doesn't pull for long enough time, chances are the stream is already canceled, so we stop the stream.
100
50
  // Issue ticket on Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=638494
101
51
 
52
+ this.streamTimeout = null;
53
+ this.snapshotHandlerTimeout = null;
54
+ this.downloadStartTime = null;
102
55
  this.iframes = [];
103
- this.useBlobFallback = false;
56
+ this.useBlobFallback = !!window.safari;
104
57
  }
105
58
 
106
59
  componentDidMount() {
@@ -125,8 +78,8 @@ export default class TableSaver extends PureComponent {
125
78
  });
126
79
  }
127
80
 
128
- if (this.streamTimeout) clearTimeout(this.streamTimeout);
129
- if (this.snapshotHandlerTimeout) clearTimeout(this.snapshotHandlerTimeout);
81
+ clearTimeout(this.streamTimeout);
82
+ clearTimeout(this.snapshotHandlerTimeout);
130
83
  }
131
84
 
132
85
  createWriterStream(port) {
@@ -146,8 +99,6 @@ export default class TableSaver extends PureComponent {
146
99
 
147
100
  if (useBlob) {
148
101
  streamConfig.write = chunk => {
149
- assertNotNull(encode);
150
-
151
102
  if (chunk.header !== undefined) {
152
103
  chunks.push(encode(chunk.header));
153
104
  }
@@ -158,7 +109,6 @@ export default class TableSaver extends PureComponent {
158
109
  };
159
110
 
160
111
  streamConfig.close = () => {
161
- assertNotNull(fileName);
162
112
  var blob = new Blob(chunks, {
163
113
  type: 'application/octet-stream; charset=utf-8'
164
114
  });
@@ -253,10 +203,7 @@ export default class TableSaver extends PureComponent {
253
203
  } = this.props;
254
204
  onDownloadCompleted();
255
205
  this.resetTableSaver();
256
-
257
- if (this.downloadStartTime) {
258
- log.info("download finished, total elapsed time ".concat((Date.now() - this.downloadStartTime) / 1000, " seconds"));
259
- }
206
+ log.info("download finished, total elapsed time ".concat((Date.now() - this.downloadStartTime) / 1000, " seconds"));
260
207
  }
261
208
 
262
209
  cancelDownload() {
@@ -274,7 +221,7 @@ export default class TableSaver extends PureComponent {
274
221
 
275
222
  this.cancelableSnapshots.forEach(cancelable => {
276
223
  if (cancelable) {
277
- cancelable.catch(() => null);
224
+ cancelable.catch(() => {});
278
225
  cancelable.cancel();
279
226
  }
280
227
  });
@@ -286,10 +233,10 @@ export default class TableSaver extends PureComponent {
286
233
  }
287
234
 
288
235
  resetTableSaver() {
289
- this.table = undefined;
290
- this.tableSubscription = undefined;
291
- this.columns = undefined;
292
- this.chunkRows = undefined;
236
+ this.table = null;
237
+ this.tableSubscription = null;
238
+ this.columns = null;
239
+ this.chunkRows = null;
293
240
  this.gridRanges = [];
294
241
  this.gridRangeCounter = 0;
295
242
  this.rangedSnapshotsTotal = [];
@@ -300,17 +247,10 @@ export default class TableSaver extends PureComponent {
300
247
  this.currentSnapshotIndex = 0;
301
248
  this.snapshotPending = 0;
302
249
  this.cancelableSnapshots = [];
303
-
304
- if (this.streamTimeout != null) {
305
- clearTimeout(this.streamTimeout);
306
- }
307
-
308
- if (this.snapshotHandlerTimeout != null) {
309
- clearTimeout(this.snapshotHandlerTimeout);
310
- }
311
-
312
- this.streamTimeout = undefined;
313
- this.snapshotHandlerTimeout = undefined;
250
+ clearTimeout(this.streamTimeout);
251
+ clearTimeout(this.snapshotHandlerTimeout);
252
+ this.streamTimeout = null;
253
+ this.snapshotHandlerTimeout = null;
314
254
  }
315
255
 
316
256
  handleDownloadTimeout() {
@@ -319,35 +259,24 @@ export default class TableSaver extends PureComponent {
319
259
  }
320
260
 
321
261
  writeTableHeader() {
322
- var _this$fileWriter;
323
-
324
262
  var headerString = '';
325
263
 
326
- if (this.columns) {
327
- for (var i = 0; i < this.columns.length; i += 1) {
328
- headerString += this.columns[i].name;
329
- headerString += i === this.columns.length - 1 ? '\n' : ',';
330
- }
264
+ for (var i = 0; i < this.columns.length; i += 1) {
265
+ headerString += this.columns[i].name;
266
+ headerString += i === this.columns.length - 1 ? '\n' : ',';
331
267
  }
332
268
 
333
- (_this$fileWriter = this.fileWriter) === null || _this$fileWriter === void 0 ? void 0 : _this$fileWriter.write({
269
+ this.fileWriter.write({
334
270
  header: headerString
335
- }).then(() => null);
271
+ }).then(() => {});
336
272
  }
337
273
 
338
274
  startWriteTableBody() {
339
- if (this.columns && this.gridRanges) {
340
- this.chunkRows = Math.floor(TableSaver.DOWNLOAD_CELL_CHUNK / this.columns.length);
341
- this.rangedSnapshotsTotal = this.gridRanges.map(range => {
342
- assertNotNull(range.endRow);
343
- assertNotNull(range.startRow);
344
- assertNotNull(this.chunkRows);
345
- return Math.ceil((range.endRow - range.startRow + 1) / this.chunkRows);
346
- });
347
- this.snapshotsTotal = this.rangedSnapshotsTotal.reduce((total, snapshotCount) => total + snapshotCount);
348
- log.info("start writing table, total snapshots: ", this.snapshotsTotal);
349
- this.makeSnapshot(Math.min(TableSaver.SNAPSHOT_BUFFER_SIZE, this.snapshotsTotal));
350
- }
275
+ this.chunkRows = Math.floor(TableSaver.DOWNLOAD_CELL_CHUNK / this.columns.length);
276
+ this.rangedSnapshotsTotal = this.gridRanges.map(range => Math.ceil((range.endRow - range.startRow + 1) / this.chunkRows));
277
+ this.snapshotsTotal = this.rangedSnapshotsTotal.reduce((total, snapshotCount) => total + snapshotCount);
278
+ log.info("start writing table, total snapshots: ", this.snapshotsTotal);
279
+ this.makeSnapshot(Math.min(TableSaver.SNAPSHOT_BUFFER_SIZE, this.snapshotsTotal));
351
280
  }
352
281
 
353
282
  writeCsvTable() {
@@ -358,37 +287,33 @@ export default class TableSaver extends PureComponent {
358
287
  writeSnapshot(snapshotIndex, snapshotStartRow, snapshotEndRow) {
359
288
  if (this.currentSnapshotIndex === snapshotIndex && this.fileWriter) {
360
289
  while (this.snapshotsBuffer.has(this.currentSnapshotIndex)) {
361
- var n = this.snapshotsBuffer.get(this.currentSnapshotIndex);
362
- assertNotNull(n);
363
290
  this.fileWriter.write({
364
- rows: this.convertSnapshotIntoCsv(n)
291
+ rows: this.convertSnapshotIntoCsv(this.snapshotsBuffer.get(this.currentSnapshotIndex), snapshotStartRow, snapshotEndRow)
365
292
  });
366
293
  this.snapshotsBuffer.delete(this.currentSnapshotIndex);
367
294
  this.currentSnapshotIndex += 1;
368
295
  this.updateDownloadProgress(snapshotIndex);
369
296
  }
370
297
 
371
- if (this.snapshotsTotal && this.currentSnapshotIndex >= this.snapshotsTotal) {
298
+ if (this.currentSnapshotIndex >= this.snapshotsTotal) {
372
299
  this.finishDownload();
373
300
  return;
374
301
  }
375
302
  }
376
303
 
377
- if (this.snapshotCounter && this.snapshotsTotal && this.snapshotCounter < this.snapshotsTotal) {
304
+ if (this.snapshotCounter < this.snapshotsTotal) {
378
305
  log.debug2("\n current range index: ".concat(this.gridRangeCounter, ", \n snapshotIndexCounter: ").concat(this.snapshotCounter, ", \n currentRangedSnapshotIndex : ").concat(this.rangedSnapshotCounter, ", \n snapshotpending: ").concat(this.snapshotPending, ", \n buffered ").concat(this.snapshotsBuffer.size, "\n making ").concat(Math.min(TableSaver.SNAPSHOT_BUFFER_SIZE - this.snapshotsBuffer.size - this.snapshotPending, this.snapshotsTotal - this.snapshotCounter), " more snapshots\n "));
379
306
  this.makeSnapshot(Math.min(TableSaver.SNAPSHOT_BUFFER_SIZE - this.snapshotsBuffer.size - this.snapshotPending, this.snapshotsTotal - this.snapshotCounter));
380
307
  }
381
308
  }
382
309
 
383
310
  updateDownloadProgress(snapshotIndex) {
384
- if (snapshotIndex != null && this.snapshotsTotal != null && this.downloadStartTime != null) {
385
- var {
386
- onDownloadProgressUpdate
387
- } = this.props;
388
- var downloadProgress = Math.floor(snapshotIndex * 100 / this.snapshotsTotal);
389
- var estimateTime = snapshotIndex > 1 ? Math.floor((Date.now() - this.downloadStartTime) * (this.snapshotsTotal - snapshotIndex) / snapshotIndex / 1000) : null;
390
- onDownloadProgressUpdate(downloadProgress, estimateTime);
391
- }
311
+ var {
312
+ onDownloadProgressUpdate
313
+ } = this.props;
314
+ var downloadProgress = Math.floor(snapshotIndex * 100 / this.snapshotsTotal);
315
+ var estimateTime = snapshotIndex > 1 ? Math.floor((Date.now() - this.downloadStartTime) * (this.snapshotsTotal - snapshotIndex) / snapshotIndex / 1000) : null;
316
+ onDownloadProgressUpdate(downloadProgress, estimateTime);
392
317
  }
393
318
 
394
319
  convertSnapshotIntoCsv(snapshot) {
@@ -403,14 +328,10 @@ export default class TableSaver extends PureComponent {
403
328
  rows.push(snapshotIterator.next().value);
404
329
  }
405
330
 
406
- assertNotNull(this.columns);
407
-
408
331
  for (var i = 0; i < rows.length; i += 1) {
409
332
  var rowIdx = rows[i];
410
333
 
411
334
  for (var j = 0; j < this.columns.length; j += 1) {
412
- var _this$columns;
413
-
414
335
  var {
415
336
  type,
416
337
  name
@@ -423,16 +344,9 @@ export default class TableSaver extends PureComponent {
423
344
  formatOverride = (cellFormat === null || cellFormat === void 0 ? void 0 : cellFormat.formatString) != null ? cellFormat : null;
424
345
  }
425
346
 
426
- var cellData = null;
427
-
428
- if (formatOverride) {
429
- cellData = formatter.getFormattedString(snapshot.getData(rowIdx, this.columns[j]), type, name, formatOverride);
430
- } else {
431
- cellData = formatter.getFormattedString(snapshot.getData(rowIdx, this.columns[j]), type, name);
432
- }
433
-
347
+ var cellData = formatter.getFormattedString(snapshot.getData(rowIdx, this.columns[j]), type, name, formatOverride);
434
348
  csvString += TableSaver.csvEscapeString(cellData);
435
- csvString += j === ((_this$columns = this.columns) === null || _this$columns === void 0 ? void 0 : _this$columns.length) - 1 ? '\n' : ',';
349
+ csvString += j === this.columns.length - 1 ? '\n' : ',';
436
350
  }
437
351
  }
438
352
 
@@ -446,25 +360,15 @@ export default class TableSaver extends PureComponent {
446
360
  return;
447
361
  }
448
362
 
449
- assertNotNull(this.gridRangeCounter);
450
363
  var i = 0;
451
364
  var currentGridRange = this.gridRanges[this.gridRangeCounter];
452
- assertNotNull(this.tableSubscription);
453
- assertNotNull(this.columns);
454
365
 
455
366
  var _loop = function _loop() {
456
- assertNotNull(currentGridRange);
457
- assertNotNull(currentGridRange.startRow);
458
- assertNotNull(currentGridRange.endRow);
459
- assertNotNull(_this.rangedSnapshotCounter);
460
- assertNotNull(_this.chunkRows);
461
367
  var snapshotStartRow = currentGridRange.startRow + _this.rangedSnapshotCounter * _this.chunkRows;
462
368
  var snapshotEndRow = Math.min(snapshotStartRow + _this.chunkRows - 1, currentGridRange.endRow);
463
369
  var snapshotIndex = _this.snapshotCounter;
464
370
 
465
371
  _this.cancelableSnapshots.push(PromiseUtils.makeCancelable(_this.tableSubscription.snapshot(dh.RangeSet.ofRange(snapshotStartRow, snapshotEndRow), _this.columns).then(snapshot => {
466
- assertIsUpdateEventData(snapshot);
467
-
468
372
  _this.handleSnapshotResolved(snapshot, snapshotIndex, snapshotStartRow, snapshotEndRow);
469
373
 
470
374
  return snapshotIndex;
@@ -512,10 +416,7 @@ export default class TableSaver extends PureComponent {
512
416
 
513
417
  if (readableStreamPulling) {
514
418
  if (!this.useBlobFallback) {
515
- if (this.streamTimeout != null) {
516
- clearTimeout(this.streamTimeout);
517
- }
518
-
419
+ clearTimeout(this.streamTimeout);
519
420
  this.streamTimeout = setTimeout(this.handleDownloadTimeout, TableSaver.STREAM_TIMEOUT);
520
421
  }
521
422
  }
@@ -536,7 +437,12 @@ export default class TableSaver extends PureComponent {
536
437
  var iframe = document.createElement('iframe');
537
438
  iframe.hidden = true;
538
439
  iframe.src = "download/".concat(src);
440
+ iframe.loaded = false;
539
441
  iframe.name = 'iframe';
442
+ iframe.isIframe = true;
443
+ iframe.addEventListener('load', () => {
444
+ iframe.loaded = true;
445
+ }, false);
540
446
  document.body.appendChild(iframe);
541
447
  this.iframes.push(iframe);
542
448
  }
@@ -555,11 +461,19 @@ _defineProperty(TableSaver, "STREAM_TIMEOUT", 8000);
555
461
 
556
462
  _defineProperty(TableSaver, "SNAPSHOT_HANDLER_TIMEOUT", 5);
557
463
 
558
- _defineProperty(TableSaver, "defaultProps", {
464
+ TableSaver.propTypes = {
465
+ getDownloadWorker: PropTypes.func,
466
+ isDownloading: PropTypes.bool,
467
+ onDownloadCompleted: PropTypes.func,
468
+ onDownloadCanceled: PropTypes.func,
469
+ onDownloadProgressUpdate: PropTypes.func,
470
+ formatter: PropTypes.instanceOf(Formatter).isRequired
471
+ };
472
+ TableSaver.defaultProps = {
559
473
  getDownloadWorker: () => Promise.reject(new Error('Download worker not provided')),
560
474
  isDownloading: false,
561
- onDownloadCompleted: () => undefined,
562
- onDownloadCanceled: () => undefined,
563
- onDownloadProgressUpdate: () => undefined
564
- });
475
+ onDownloadCompleted: () => {},
476
+ onDownloadCanceled: () => {},
477
+ onDownloadProgressUpdate: () => {}
478
+ };
565
479
  //# sourceMappingURL=TableSaver.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/sidebar/TableSaver.tsx"],"names":["PureComponent","WritableStream","ponyfillWritableStream","dh","Log","memoizeClear","FormatterUtils","PromiseUtils","assertNotNull","log","module","isUpdateEventData","data","added","undefined","assertIsUpdateEventData","Error","TableSaver","csvEscapeString","str","replace","constructor","props","window","isCustomColumnFormatDefined","max","handlePortMessage","bind","handleSnapshotResolved","handleDownloadTimeout","state","gridRanges","gridRangeCounter","rangedSnapshotsTotal","rangedSnapshotCounter","snapshotsTotal","snapshotCounter","snapshotsBuffer","Map","currentSnapshotIndex","snapshotPending","cancelableSnapshots","iframes","useBlobFallback","componentDidMount","getDownloadWorker","then","sw","info","postMessage","catch","error","warn","componentWillUnmount","length","forEach","iframe","remove","streamTimeout","clearTimeout","snapshotHandlerTimeout","createWriterStream","port","useBlob","chunks","encode","TextEncoder","prototype","fileName","streamConfig","write","chunk","header","push","rows","close","blob","Blob","type","link","document","createElement","href","URL","createObjectURL","download","click","abort","cancel","end","startDownload","frozenTable","tableSubscription","isDownloading","downloadStartTime","Date","now","table","columns","encodedFileName","encodeURIComponent","escape","messageChannel","MessageChannel","port1","fileWriter","getWriter","writeCsvTable","port2","onmessage","finishDownload","onDownloadCompleted","resetTableSaver","cancelDownload","cancelable","onDownloadCanceled","chunkRows","writeTableHeader","headerString","i","name","startWriteTableBody","Math","floor","DOWNLOAD_CELL_CHUNK","map","range","endRow","startRow","ceil","reduce","total","snapshotCount","makeSnapshot","min","SNAPSHOT_BUFFER_SIZE","writeSnapshot","snapshotIndex","snapshotStartRow","snapshotEndRow","has","n","get","convertSnapshotIntoCsv","delete","updateDownloadProgress","debug2","size","onDownloadProgressUpdate","downloadProgress","estimateTime","snapshot","csvString","snapshotIterator","iterator","formatter","hasNext","next","value","rowIdx","j","hasCustomColumnFormat","getCachedCustomColumnFormatFlag","formatOverride","cellFormat","getFormat","formatString","cellData","getFormattedString","getData","currentGridRange","makeCancelable","RangeSet","ofRange","err","val","readableStreamPulling","makeIframe","setTimeout","STREAM_TIMEOUT","set","SNAPSHOT_HANDLER_TIMEOUT","src","hidden","body","appendChild","render","Promise","reject"],"mappings":";;AAAA,SAASA,aAAT,QAA8B,OAA9B;AACA,SAASC,cAAc,IAAIC,sBAA3B,QAAyD,+BAAzD;AACA,OAAOC,EAAP,MAMO,uBANP;AAOA,OAAOC,GAAP,MAAgB,gBAAhB;AACA,SAAoCC,YAApC,QAAwD,iBAAxD;AAEA,SAAoBC,cAApB,QAA0C,wBAA1C;AACA,SAEEC,YAFF,EAGEC,aAHF,QAIO,kBAJP;AAMA,IAAMC,GAAG,GAAGL,GAAG,CAACM,MAAJ,CAAW,YAAX,CAAZ;;AAcA,SAASC,iBAAT,CAA2BC,IAA3B,EAAqE;AACnE,SAAQA,IAAD,CAA0BC,KAA1B,KAAoCC,SAA3C;AACD;;AAED,SAASC,uBAAT,CACEH,IADF,EAEmC;AACjC,MAAI,CAACD,iBAAiB,CAACC,IAAD,CAAtB,EAA8B;AAC5B,UAAM,IAAII,KAAJ,CAAU,8BAAV,CAAN;AACD;AACF;;AAED,eAAe,MAAMC,UAAN,SAAyBjB,aAAzB,CAGb;AAkBsB,SAAfkB,eAAe,CAACC,GAAD,EAAsB;AAC1C,uBAAWA,GAAG,CAACC,OAAJ,CAAY,IAAZ,EAAkB,IAAlB,CAAX;AACD;;AAEDC,EAAAA,WAAW,CAACC,KAAD,EAAyB;AAClC,UAAMA,KAAN;;AADkC;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA,4CAiGnBC,MAAM,CAACtB,cAAP,IAAyBC,sBAjGN;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA,6DAiHFG,YAAY,CAC5CC,cAAc,CAACkB,2BAD6B,EAE5C;AAAEC,MAAAA,GAAG,EAAE;AAAP,KAF4C,CAjHV;;AAGlC,SAAKC,iBAAL,GAAyB,KAAKA,iBAAL,CAAuBC,IAAvB,CAA4B,IAA5B,CAAzB;AACA,SAAKC,sBAAL,GAA8B,KAAKA,sBAAL,CAA4BD,IAA5B,CAAiC,IAAjC,CAA9B;AACA,SAAKE,qBAAL,GAA6B,KAAKA,qBAAL,CAA2BF,IAA3B,CAAgC,IAAhC,CAA7B;AAEA,SAAKG,KAAL,GAAa,EAAb;AAEA,SAAKC,UAAL,GAAkB,EAAlB;AACA,SAAKC,gBAAL,GAAwB,CAAxB;AACA,SAAKC,oBAAL,GAA4B,EAA5B;AACA,SAAKC,qBAAL,GAA6B,CAA7B;AAEA,SAAKC,cAAL,GAAsB,CAAtB;AACA,SAAKC,eAAL,GAAuB,CAAvB;AACA,SAAKC,eAAL,GAAuB,IAAIC,GAAJ,EAAvB;AAEA,SAAKC,oBAAL,GAA4B,CAA5B;AACA,SAAKC,eAAL,GAAuB,CAAvB;AACA,SAAKC,mBAAL,GAA2B,EAA3B,CApBkC,CAsBlC;;AACA,SAAKxC,cAAL,GAAsBsB,MAAM,CAACtB,cAAP,IAAyBC,sBAA/C,CAvBkC,CAyBlC;AACA;AACA;AACA;;AAEA,SAAKwC,OAAL,GAAe,EAAf;AAEA,SAAKC,eAAL,GAAuB,KAAvB;AACD;;AAEDC,EAAAA,iBAAiB,GAAS;AACxB,QAAM;AAAEC,MAAAA;AAAF,QAAwB,KAAKvB,KAAnC;AACAuB,IAAAA,iBAAiB,GACdC,IADH,CACQC,EAAE,IAAI;AACVtC,MAAAA,GAAG,CAACuC,IAAJ,CAAS,6BAAT;AACA,WAAKD,EAAL,GAAUA,EAAV;AACA,WAAKA,EAAL,CAAQE,WAAR,CAAoB,MAApB,EAHU,CAGmB;AAC9B,KALH,EAMGC,KANH,CAMSC,KAAK,IAAI;AACd;AACA1C,MAAAA,GAAG,CAAC2C,IAAJ,CAAS,gCAAT,EAA2CD,KAA3C;AACA,WAAKR,eAAL,GAAuB,IAAvB;AACD,KAVH;AAWD;;AAEDU,EAAAA,oBAAoB,GAAS;AAC3B,QAAI,KAAKX,OAAL,CAAaY,MAAb,GAAsB,CAA1B,EAA6B;AAC3B,WAAKZ,OAAL,CAAaa,OAAb,CAAqBC,MAAM,IAAI;AAC7BA,QAAAA,MAAM,CAACC,MAAP;AACD,OAFD;AAGD;;AACD,QAAI,KAAKC,aAAT,EAAwBC,YAAY,CAAC,KAAKD,aAAN,CAAZ;AACxB,QAAI,KAAKE,sBAAT,EAAiCD,YAAY,CAAC,KAAKC,sBAAN,CAAZ;AAClC;;AA4DDC,EAAAA,kBAAkB,CAACC,IAAD,EAAmD;AACnE;AACA,QAAMC,OAAO,GAAG,KAAKpB,eAArB;AACA,QAAMqB,MAAM,GAAG,EAAf;AACA,QAAIC,MAA+C,GAAG,IAAtD;;AACA,QAAIF,OAAJ,EAAa;AACXE,MAAAA,MAAM,GAAGC,WAAW,CAACC,SAAZ,CAAsBF,MAAtB,CAA6BtC,IAA7B,CAAkC,IAAIuC,WAAJ,EAAlC,CAAT;AACD;;AACD,QAAM;AAAEE,MAAAA;AAAF,QAAe,IAArB;AAEA,QAAMC,YAAY,GAAG,EAArB;;AACA,QAAIN,OAAJ,EAAa;AACXM,MAAAA,YAAY,CAACC,KAAb,GAAsBC,KAAD,IAA+C;AAClE/D,QAAAA,aAAa,CAACyD,MAAD,CAAb;;AACA,YAAIM,KAAK,CAACC,MAAN,KAAiB1D,SAArB,EAAgC;AAC9BkD,UAAAA,MAAM,CAACS,IAAP,CAAYR,MAAM,CAACM,KAAK,CAACC,MAAP,CAAlB;AACD;;AACD,YAAID,KAAK,CAACG,IAAN,KAAe5D,SAAnB,EAA8B;AAC5BkD,UAAAA,MAAM,CAACS,IAAP,CAAYR,MAAM,CAACM,KAAK,CAACG,IAAP,CAAlB;AACD;AACF,OARD;;AASAL,MAAAA,YAAY,CAACM,KAAb,GAAqB,MAAM;AACzBnE,QAAAA,aAAa,CAAC4D,QAAD,CAAb;AACA,YAAMQ,IAAI,GAAG,IAAIC,IAAJ,CAASb,MAAT,EAAiB;AAC5Bc,UAAAA,IAAI,EAAE;AADsB,SAAjB,CAAb;AAGA,YAAMC,IAAI,GAAGC,QAAQ,CAACC,aAAT,CAAuB,GAAvB,CAAb;AACAF,QAAAA,IAAI,CAACG,IAAL,GAAYC,GAAG,CAACC,eAAJ,CAAoBR,IAApB,CAAZ;AACAG,QAAAA,IAAI,CAACM,QAAL,GAAgBjB,QAAhB;AACAW,QAAAA,IAAI,CAACO,KAAL;AACD,OATD;;AAUAjB,MAAAA,YAAY,CAACkB,KAAb,GAAqB,MAAM;AACzBzB,QAAAA,IAAI,CAACb,WAAL,CAAiB;AAAEuC,UAAAA,MAAM,EAAE;AAAV,SAAjB;AACA1B,QAAAA,IAAI,CAACa,KAAL;AACD,OAHD;AAID,KAxBD,MAwBO;AACLN,MAAAA,YAAY,CAACC,KAAb,GAAsBC,KAAD,IAAoB;AACvCT,QAAAA,IAAI,CAACb,WAAL,CAAiBsB,KAAjB;AACD,OAFD;;AAGAF,MAAAA,YAAY,CAACM,KAAb,GAAqB,MAAM;AACzBb,QAAAA,IAAI,CAACb,WAAL,CAAiB;AAAEwC,UAAAA,GAAG,EAAE;AAAP,SAAjB;AACA3B,QAAAA,IAAI,CAACa,KAAL;AACD,OAHD;;AAIAN,MAAAA,YAAY,CAACkB,KAAb,GAAqB,MAAM;AACzBzB,QAAAA,IAAI,CAACb,WAAL,CAAiB;AAAEuC,UAAAA,MAAM,EAAE;AAAV,SAAjB;AACA1B,QAAAA,IAAI,CAACa,KAAL;AACD,OAHD;AAID;;AAED,WAAO,IAAI,KAAK1E,cAAT,CAAwBoE,YAAxB,CAAP;AACD;;AAEDqB,EAAAA,aAAa,CACXtB,QADW,EAEXuB,WAFW,EAGXC,iBAHW,EAIX7D,UAJW,EAKL;AACN;AACA,QAAM;AAAE8D,MAAAA;AAAF,QAAoB,KAAKvE,KAA/B;;AACA,QAAIuE,aAAJ,EAAmB;AACjB;AACD;;AAED,SAAKC,iBAAL,GAAyBC,IAAI,CAACC,GAAL,EAAzB;AACAvF,IAAAA,GAAG,CAACuC,IAAJ,6BAA8BoB,QAA9B;AAEA,SAAK6B,KAAL,GAAaN,WAAb;AACA,SAAKO,OAAL,GAAeP,WAAW,CAACO,OAA3B;AACA,SAAKN,iBAAL,GAAyBA,iBAAzB;AACA,SAAK7D,UAAL,GAAkBA,UAAlB,CAbM,CAeN;;AACA,QAAMoE,eAAe,GAAGC,kBAAkB,CAAChC,QAAQ,CAAChD,OAAT,CAAiB,KAAjB,EAAwB,GAAxB,CAAD,CAAlB,CACrBA,OADqB,CACb,QADa,EACHiF,MADG,EAErBjF,OAFqB,CAEb,KAFa,EAEN,KAFM,CAAxB;AAIA,QAAMkF,cAAc,GAAG,IAAIC,cAAJ,EAAvB;AACA,SAAKzC,IAAL,GAAYwC,cAAc,CAACE,KAA3B;AACA,SAAKpC,QAAL,GAAgBA,QAAhB;AACA,SAAKqC,UAAL,GAAkB,KAAK5C,kBAAL,CAAwB,KAAKC,IAA7B,EAAmC4C,SAAnC,EAAlB,CAvBM,CAyBN;;AACA,QAAI,KAAK/D,eAAT,EAA0B;AACxB,WAAKgE,aAAL;AACA;AACD;;AAED,QAAI,KAAK5D,EAAT,EAAa;AACX;AACA,WAAKA,EAAL,CAAQE,WAAR,CAAoB;AAAEkD,QAAAA;AAAF,OAApB,EAAyC,CAACG,cAAc,CAACM,KAAhB,CAAzC;AACD;;AACD,SAAK9C,IAAL,CAAU+C,SAAV,GAAsB,KAAKnF,iBAA3B;AACD;;AAEDoF,EAAAA,cAAc,GAAS;AACrB,QAAI,KAAKb,KAAT,EAAgB;AACd,WAAKA,KAAL,CAAWtB,KAAX;AACD;;AACD,QAAI,KAAKiB,iBAAT,EAA4B;AAC1B,WAAKA,iBAAL,CAAuBjB,KAAvB;AACD;;AACD,QAAI,KAAK8B,UAAT,EAAqB;AACnB,WAAKA,UAAL,CAAgB9B,KAAhB;AACD;;AAED,QAAM;AAAEoC,MAAAA;AAAF,QAA0B,KAAKzF,KAArC;AACAyF,IAAAA,mBAAmB;AACnB,SAAKC,eAAL;;AAEA,QAAI,KAAKlB,iBAAT,EAA4B;AAC1BrF,MAAAA,GAAG,CAACuC,IAAJ,iDAEI,CAAC+C,IAAI,CAACC,GAAL,KAAa,KAAKF,iBAAnB,IAAwC,IAF5C;AAKD;AACF;;AAEDmB,EAAAA,cAAc,GAAS;AACrB,QAAI,KAAKhB,KAAT,EAAgB;AACd,WAAKA,KAAL,CAAWtB,KAAX;AACD;;AACD,QAAI,KAAKiB,iBAAT,EAA4B;AAC1B,WAAKA,iBAAL,CAAuBjB,KAAvB;AACD;;AACD,QAAI,KAAK8B,UAAT,EAAqB;AACnB,WAAKA,UAAL,CAAgBlB,KAAhB;AACD;;AAED,SAAK9C,mBAAL,CAAyBc,OAAzB,CAAiC2D,UAAU,IAAI;AAC7C,UAAIA,UAAJ,EAAgB;AACdA,QAAAA,UAAU,CAAChE,KAAX,CAAiB,MAAM,IAAvB;AACAgE,QAAAA,UAAU,CAAC1B,MAAX;AACD;AACF,KALD;AAMA,QAAM;AAAE2B,MAAAA;AAAF,QAAyB,KAAK7F,KAApC;AACA6F,IAAAA,kBAAkB;AAClB,SAAKH,eAAL;AACD;;AAEDA,EAAAA,eAAe,GAAS;AACtB,SAAKf,KAAL,GAAanF,SAAb;AACA,SAAK8E,iBAAL,GAAyB9E,SAAzB;AACA,SAAKoF,OAAL,GAAepF,SAAf;AACA,SAAKsG,SAAL,GAAiBtG,SAAjB;AAEA,SAAKiB,UAAL,GAAkB,EAAlB;AACA,SAAKC,gBAAL,GAAwB,CAAxB;AACA,SAAKC,oBAAL,GAA4B,EAA5B;AACA,SAAKC,qBAAL,GAA6B,CAA7B;AAEA,SAAKC,cAAL,GAAsB,CAAtB;AACA,SAAKC,eAAL,GAAuB,CAAvB;AACA,SAAKC,eAAL,GAAuB,IAAIC,GAAJ,EAAvB;AAEA,SAAKC,oBAAL,GAA4B,CAA5B;AACA,SAAKC,eAAL,GAAuB,CAAvB;AACA,SAAKC,mBAAL,GAA2B,EAA3B;;AAEA,QAAI,KAAKiB,aAAL,IAAsB,IAA1B,EAAgC;AAC9BC,MAAAA,YAAY,CAAC,KAAKD,aAAN,CAAZ;AACD;;AAED,QAAI,KAAKE,sBAAL,IAA+B,IAAnC,EAAyC;AACvCD,MAAAA,YAAY,CAAC,KAAKC,sBAAN,CAAZ;AACD;;AACD,SAAKF,aAAL,GAAqB5C,SAArB;AACA,SAAK8C,sBAAL,GAA8B9C,SAA9B;AACD;;AAEDe,EAAAA,qBAAqB,GAAS;AAC5BpB,IAAAA,GAAG,CAACuC,IAAJ,CAAS,mBAAT;AACA,SAAKiE,cAAL;AACD;;AAEDI,EAAAA,gBAAgB,GAAS;AAAA;;AACvB,QAAIC,YAAY,GAAG,EAAnB;;AACA,QAAI,KAAKpB,OAAT,EAAkB;AAChB,WAAK,IAAIqB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG,KAAKrB,OAAL,CAAa5C,MAAjC,EAAyCiE,CAAC,IAAI,CAA9C,EAAiD;AAC/CD,QAAAA,YAAY,IAAI,KAAKpB,OAAL,CAAaqB,CAAb,EAAgBC,IAAhC;AACAF,QAAAA,YAAY,IAAIC,CAAC,KAAK,KAAKrB,OAAL,CAAa5C,MAAb,GAAsB,CAA5B,GAAgC,IAAhC,GAAuC,GAAvD;AACD;AACF;;AACD,6BAAKmD,UAAL,sEAAiBnC,KAAjB,CAAuB;AAAEE,MAAAA,MAAM,EAAE8C;AAAV,KAAvB,EAAiDxE,IAAjD,CAAsD,MAAM,IAA5D;AACD;;AAED2E,EAAAA,mBAAmB,GAAS;AAC1B,QAAI,KAAKvB,OAAL,IAAgB,KAAKnE,UAAzB,EAAqC;AACnC,WAAKqF,SAAL,GAAiBM,IAAI,CAACC,KAAL,CACf1G,UAAU,CAAC2G,mBAAX,GAAiC,KAAK1B,OAAL,CAAa5C,MAD/B,CAAjB;AAIA,WAAKrB,oBAAL,GAA4B,KAAKF,UAAL,CAAgB8F,GAAhB,CAAqBC,KAAD,IAAsB;AACpEtH,QAAAA,aAAa,CAACsH,KAAK,CAACC,MAAP,CAAb;AACAvH,QAAAA,aAAa,CAACsH,KAAK,CAACE,QAAP,CAAb;AACAxH,QAAAA,aAAa,CAAC,KAAK4G,SAAN,CAAb;AAEA,eAAOM,IAAI,CAACO,IAAL,CAAU,CAACH,KAAK,CAACC,MAAN,GAAeD,KAAK,CAACE,QAArB,GAAgC,CAAjC,IAAsC,KAAKZ,SAArD,CAAP;AACD,OAN2B,CAA5B;AAOA,WAAKjF,cAAL,GAAsB,KAAKF,oBAAL,CAA0BiG,MAA1B,CACpB,CAACC,KAAD,EAAgBC,aAAhB,KAA0CD,KAAK,GAAGC,aAD9B,CAAtB;AAIA3H,MAAAA,GAAG,CAACuC,IAAJ,2CAAmD,KAAKb,cAAxD;AAEA,WAAKkG,YAAL,CACEX,IAAI,CAACY,GAAL,CAASrH,UAAU,CAACsH,oBAApB,EAA0C,KAAKpG,cAA/C,CADF;AAGD;AACF;;AAEDwE,EAAAA,aAAa,GAAS;AACpB,SAAKU,gBAAL;AACA,SAAKI,mBAAL;AACD;;AAEDe,EAAAA,aAAa,CACXC,aADW,EAEXC,gBAFW,EAGXC,cAHW,EAIL;AACN,QAAI,KAAKpG,oBAAL,KAA8BkG,aAA9B,IAA+C,KAAKhC,UAAxD,EAAoE;AAClE,aAAO,KAAKpE,eAAL,CAAqBuG,GAArB,CAAyB,KAAKrG,oBAA9B,CAAP,EAA4D;AAC1D,YAAMsG,CAAC,GAAG,KAAKxG,eAAL,CAAqByG,GAArB,CAAyB,KAAKvG,oBAA9B,CAAV;AACA/B,QAAAA,aAAa,CAACqI,CAAD,CAAb;AACA,aAAKpC,UAAL,CAAgBnC,KAAhB,CAAsB;AACpBI,UAAAA,IAAI,EAAE,KAAKqE,sBAAL,CAA4BF,CAA5B;AADc,SAAtB;AAGA,aAAKxG,eAAL,CAAqB2G,MAArB,CAA4B,KAAKzG,oBAAjC;AACA,aAAKA,oBAAL,IAA6B,CAA7B;AAEA,aAAK0G,sBAAL,CAA4BR,aAA5B;AACD;;AACD,UACE,KAAKtG,cAAL,IACA,KAAKI,oBAAL,IAA6B,KAAKJ,cAFpC,EAGE;AACA,aAAK2E,cAAL;AACA;AACD;AACF;;AAED,QACE,KAAK1E,eAAL,IACA,KAAKD,cADL,IAEA,KAAKC,eAAL,GAAuB,KAAKD,cAH9B,EAIE;AACA1B,MAAAA,GAAG,CAACyI,MAAJ,0CAEyB,KAAKlH,gBAF9B,+CAG0B,KAAKI,eAH/B,sDAIiC,KAAKF,qBAJtC,0CAKqB,KAAKM,eAL1B,kCAMa,KAAKH,eAAL,CAAqB8G,IANlC,8BAOWzB,IAAI,CAACY,GAAL,CACPrH,UAAU,CAACsH,oBAAX,GACE,KAAKlG,eAAL,CAAqB8G,IADvB,GAEE,KAAK3G,eAHA,EAIP,KAAKL,cAAL,GAAsB,KAAKC,eAJpB,CAPX;AAeA,WAAKiG,YAAL,CACEX,IAAI,CAACY,GAAL,CACErH,UAAU,CAACsH,oBAAX,GACE,KAAKlG,eAAL,CAAqB8G,IADvB,GAEE,KAAK3G,eAHT,EAIE,KAAKL,cAAL,GAAsB,KAAKC,eAJ7B,CADF;AAQD;AACF;;AAED6G,EAAAA,sBAAsB,CAACR,aAAD,EAAsC;AAC1D,QACEA,aAAa,IAAI,IAAjB,IACA,KAAKtG,cAAL,IAAuB,IADvB,IAEA,KAAK2D,iBAAL,IAA0B,IAH5B,EAIE;AACA,UAAM;AAAEsD,QAAAA;AAAF,UAA+B,KAAK9H,KAA1C;AACA,UAAM+H,gBAAgB,GAAG3B,IAAI,CAACC,KAAL,CACtBc,aAAa,GAAG,GAAjB,GAAwB,KAAKtG,cADN,CAAzB;AAGA,UAAMmH,YAAY,GAChBb,aAAa,GAAG,CAAhB,GACIf,IAAI,CAACC,KAAL,CACG,CAAC5B,IAAI,CAACC,GAAL,KAAa,KAAKF,iBAAnB,KACE,KAAK3D,cAAL,GAAsBsG,aADxB,CAAD,GAEEA,aAFF,GAGE,IAJJ,CADJ,GAOI,IARN;AAUAW,MAAAA,wBAAwB,CAACC,gBAAD,EAAmBC,YAAnB,CAAxB;AACD;AACF;;AAEDP,EAAAA,sBAAsB,CAACQ,QAAD,EAAoC;AACxD,QAAIC,SAAS,GAAG,EAAhB;AACA,QAAMC,gBAAgB,GAAGF,QAAQ,CAAC1I,KAAT,CAAe6I,QAAf,EAAzB;AACA,QAAM;AAAEC,MAAAA;AAAF,QAAgB,KAAKrI,KAA3B;AAEA,QAAMoD,IAAI,GAAG,EAAb;;AACA,WAAO+E,gBAAgB,CAACG,OAAjB,EAAP,EAAmC;AACjClF,MAAAA,IAAI,CAACD,IAAL,CAAUgF,gBAAgB,CAACI,IAAjB,GAAwBC,KAAlC;AACD;;AAEDtJ,IAAAA,aAAa,CAAC,KAAK0F,OAAN,CAAb;;AAEA,SAAK,IAAIqB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG7C,IAAI,CAACpB,MAAzB,EAAiCiE,CAAC,IAAI,CAAtC,EAAyC;AACvC,UAAMwC,MAAM,GAAGrF,IAAI,CAAC6C,CAAD,CAAnB;;AACA,WAAK,IAAIyC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG,KAAK9D,OAAL,CAAa5C,MAAjC,EAAyC0G,CAAC,IAAI,CAA9C,EAAiD;AAAA;;AAC/C,YAAM;AAAElF,UAAAA,IAAF;AAAQ0C,UAAAA;AAAR,YAAiB,KAAKtB,OAAL,CAAa8D,CAAb,CAAvB;AACA,YAAMC,qBAAqB,GAAG,KAAKC,+BAAL,CAC5BP,SAD4B,EAE5BnC,IAF4B,EAG5B1C,IAH4B,CAA9B;AAKA,YAAIqF,cAAc,GAAG,IAArB;;AACA,YAAI,CAACF,qBAAL,EAA4B;AAC1B,cAAMG,UAAU,GAAGb,QAAQ,CAACc,SAAT,CAAmBN,MAAnB,EAA2B,KAAK7D,OAAL,CAAa8D,CAAb,CAA3B,CAAnB;AACAG,UAAAA,cAAc,GAAG,CAAAC,UAAU,SAAV,IAAAA,UAAU,WAAV,YAAAA,UAAU,CAAEE,YAAZ,KAA4B,IAA5B,GAAmCF,UAAnC,GAAgD,IAAjE;AACD;;AACD,YAAIG,QAAQ,GAAG,IAAf;;AACA,YAAIJ,cAAJ,EAAoB;AAClBI,UAAAA,QAAQ,GAAGZ,SAAS,CAACa,kBAAV,CACTjB,QAAQ,CAACkB,OAAT,CAAiBV,MAAjB,EAAyB,KAAK7D,OAAL,CAAa8D,CAAb,CAAzB,CADS,EAETlF,IAFS,EAGT0C,IAHS,EAIT2C,cAJS,CAAX;AAMD,SAPD,MAOO;AACLI,UAAAA,QAAQ,GAAGZ,SAAS,CAACa,kBAAV,CACTjB,QAAQ,CAACkB,OAAT,CAAiBV,MAAjB,EAAyB,KAAK7D,OAAL,CAAa8D,CAAb,CAAzB,CADS,EAETlF,IAFS,EAGT0C,IAHS,CAAX;AAKD;;AACDgC,QAAAA,SAAS,IAAIvI,UAAU,CAACC,eAAX,CAA2BqJ,QAA3B,CAAb;AACAf,QAAAA,SAAS,IAAIQ,CAAC,KAAK,uBAAK9D,OAAL,gEAAc5C,MAAd,IAAuB,CAA7B,GAAiC,IAAjC,GAAwC,GAArD;AACD;AACF;;AAED,WAAOkG,SAAP;AACD;;AAEDnB,EAAAA,YAAY,CAACQ,CAAD,EAAkB;AAAA;;AAC5B,QAAIA,CAAC,IAAI,CAAT,EAAY;AACV;AACD;;AACDrI,IAAAA,aAAa,CAAC,KAAKwB,gBAAN,CAAb;AACA,QAAIuF,CAAC,GAAG,CAAR;AACA,QAAImD,gBAAgB,GAAG,KAAK3I,UAAL,CAAgB,KAAKC,gBAArB,CAAvB;AAEAxB,IAAAA,aAAa,CAAC,KAAKoF,iBAAN,CAAb;AACApF,IAAAA,aAAa,CAAC,KAAK0F,OAAN,CAAb;;AAT4B;AAW1B1F,MAAAA,aAAa,CAACkK,gBAAD,CAAb;AACAlK,MAAAA,aAAa,CAACkK,gBAAgB,CAAC1C,QAAlB,CAAb;AACAxH,MAAAA,aAAa,CAACkK,gBAAgB,CAAC3C,MAAlB,CAAb;AACAvH,MAAAA,aAAa,CAAC,KAAI,CAAC0B,qBAAN,CAAb;AACA1B,MAAAA,aAAa,CAAC,KAAI,CAAC4G,SAAN,CAAb;AACA,UAAMsB,gBAAgB,GACpBgC,gBAAgB,CAAC1C,QAAjB,GAA4B,KAAI,CAAC9F,qBAAL,GAA6B,KAAI,CAACkF,SADhE;AAEA,UAAMuB,cAAc,GAAGjB,IAAI,CAACY,GAAL,CACrBI,gBAAgB,GAAG,KAAI,CAACtB,SAAxB,GAAoC,CADf,EAErBsD,gBAAgB,CAAC3C,MAFI,CAAvB;AAKA,UAAMU,aAAa,GAAG,KAAI,CAACrG,eAA3B;;AACA,MAAA,KAAI,CAACK,mBAAL,CAAyBgC,IAAzB,CACElE,YAAY,CAACoK,cAAb,CACE,KAAI,CAAC/E,iBAAL,CACG2D,QADH,CAEIpJ,EAAE,CAACyK,QAAH,CAAYC,OAAZ,CAAoBnC,gBAApB,EAAsCC,cAAtC,CAFJ,EAGI,KAAI,CAACzC,OAHT,EAKGpD,IALH,CAKQyG,QAAQ,IAAI;AAChBxI,QAAAA,uBAAuB,CAACwI,QAAD,CAAvB;;AACA,QAAA,KAAI,CAAC3H,sBAAL,CACE2H,QADF,EAEEd,aAFF,EAGEC,gBAHF,EAIEC,cAJF;;AAOA,eAAOF,aAAP;AACD,OAfH,EAgBGvF,KAhBH,CAgBS4H,GAAG,IAAI;AACZrK,QAAAA,GAAG,CAAC0C,KAAJ,CAAU2H,GAAV;AACD,OAlBH,CADF,EAoBEC,GAAG,IAAI;AACLtK,QAAAA,GAAG,CAACuC,IAAJ,oBAAqB+H,GAArB;AACD,OAtBH,CADF;;AA2BA,MAAA,KAAI,CAAC7I,qBAAL,IAA8B,CAA9B;AACA,MAAA,KAAI,CAACE,eAAL,IAAwB,CAAxB;AACA,MAAA,KAAI,CAACI,eAAL,IAAwB,CAAxB;;AAEA,UACE,KAAI,CAACN,qBAAL,IACA,KAAI,CAACD,oBAAL,CAA0B,KAAI,CAACD,gBAA/B,CAFF,EAGE;AACA,QAAA,KAAI,CAACA,gBAAL,IAAyB,CAAzB;AACA,QAAA,KAAI,CAACE,qBAAL,GAA6B,CAA7B;AACAwI,QAAAA,gBAAgB,GAAG,KAAI,CAAC3I,UAAL,CAAgB,KAAI,CAACC,gBAArB,CAAnB;AACD;;AACDuF,MAAAA,CAAC,IAAI,CAAL;AA/D0B;;AAU5B,WAAOA,CAAC,GAAGsB,CAAX,EAAc;AAAA;AAsDb;AACF;;AAEDnH,EAAAA,iBAAiB,OAKP;AAAA,QALQ;AAChBd,MAAAA;AADgB,KAKR;AACR,QAAM;AAAEyE,MAAAA,QAAF;AAAY2F,MAAAA;AAAZ,QAAsCpK,IAA5C;;AACA,QAAI,KAAK+B,eAAT,EAA0B;AACxB;AACD;;AACD,QAAI0C,QAAJ,EAAc;AACZ,WAAK4F,UAAL,WAAmB5F,QAAnB;AACA,WAAKsB,aAAL;AACD;;AACD,QAAIqE,qBAAJ,EAA2B;AACzB,UAAI,CAAC,KAAKrI,eAAV,EAA2B;AACzB,YAAI,KAAKe,aAAL,IAAsB,IAA1B,EAAgC;AAC9BC,UAAAA,YAAY,CAAC,KAAKD,aAAN,CAAZ;AACD;;AACD,aAAKA,aAAL,GAAqBwH,UAAU,CAC7B,KAAKrJ,qBADwB,EAE7BZ,UAAU,CAACkK,cAFkB,CAA/B;AAID;AACF;AACF;;AAEDvJ,EAAAA,sBAAsB,CACpB2H,QADoB,EAEpBd,aAFoB,EAGpBC,gBAHoB,EAIpBC,cAJoB,EAKd;AACN;AACA,SAAK/E,sBAAL,GAA8BsH,UAAU,CAAC,MAAM;AAC7C,WAAK7I,eAAL,CAAqB+I,GAArB,CAAyB3C,aAAzB,EAAwCc,QAAxC;AACA,WAAK/G,eAAL,IAAwB,CAAxB;AACA,WAAKgG,aAAL,CAAmBC,aAAnB,EAAkCC,gBAAlC,EAAoDC,cAApD;AACA,WAAKlG,mBAAL,CAAyBgG,aAAzB,IAA0C,IAA1C;AACD,KALuC,EAKrCxH,UAAU,CAACoK,wBAL0B,CAAxC;AAMD;;AAEDJ,EAAAA,UAAU,CAACK,GAAD,EAAoB;AAC5B;AACA,QAAM9H,MAAM,GAAGwB,QAAQ,CAACC,aAAT,CAAuB,QAAvB,CAAf;AACAzB,IAAAA,MAAM,CAAC+H,MAAP,GAAgB,IAAhB;AACA/H,IAAAA,MAAM,CAAC8H,GAAP,sBAAyBA,GAAzB;AACA9H,IAAAA,MAAM,CAACgE,IAAP,GAAc,QAAd;AACAxC,IAAAA,QAAQ,CAACwG,IAAT,CAAcC,WAAd,CAA0BjI,MAA1B;AACA,SAAKd,OAAL,CAAa+B,IAAb,CAAkBjB,MAAlB;AACD;;AAEDkI,EAAAA,MAAM,GAAS;AACb,WAAO,IAAP;AACD;;AAhmBD;;gBAHmBzK,U,yBAIU,I;;gBAJVA,U,0BAMW,C;;gBANXA,U,oBAQK,I;;gBARLA,U,8BAUe,C;;gBAVfA,U,kBAYG;AACpB4B,EAAAA,iBAAiB,EAAE,MACjB8I,OAAO,CAACC,MAAR,CAAe,IAAI5K,KAAJ,CAAU,8BAAV,CAAf,CAFkB;AAGpB6E,EAAAA,aAAa,EAAE,KAHK;AAIpBkB,EAAAA,mBAAmB,EAAE,MAAYjG,SAJb;AAKpBqG,EAAAA,kBAAkB,EAAE,MAAYrG,SALZ;AAMpBsI,EAAAA,wBAAwB,EAAE,MAAYtI;AANlB,C","sourcesContent":["import { PureComponent } from 'react';\nimport { WritableStream as ponyfillWritableStream } from 'web-streams-polyfill/ponyfill';\nimport dh, {\n Column,\n Table,\n TableData,\n TableViewportSubscription,\n UpdateEventData,\n} from '@deephaven/jsapi-shim';\nimport Log from '@deephaven/log';\nimport { GridRange, GridRangeIndex, memoizeClear } from '@deephaven/grid';\n\nimport { Formatter, FormatterUtils } from '@deephaven/jsapi-utils';\nimport {\n CancelablePromise,\n PromiseUtils,\n assertNotNull,\n} from '@deephaven/utils';\n\nconst log = Log.module('TableSaver');\n\ninterface TableSaverProps {\n getDownloadWorker: () => Promise<ServiceWorker>;\n isDownloading: boolean;\n onDownloadCompleted: () => void;\n onDownloadCanceled: () => void;\n onDownloadProgressUpdate: (\n progress: number,\n estimatedTime: number | null\n ) => void;\n formatter: Formatter;\n}\n\nfunction isUpdateEventData(data: TableData): data is UpdateEventData {\n return (data as UpdateEventData).added !== undefined;\n}\n\nfunction assertIsUpdateEventData(\n data: TableData\n): asserts data is UpdateEventData {\n if (!isUpdateEventData(data)) {\n throw new Error('event is not UpdateEventData');\n }\n}\n\nexport default class TableSaver extends PureComponent<\n TableSaverProps,\n Record<string, never>\n> {\n static DOWNLOAD_CELL_CHUNK = 6000;\n\n static SNAPSHOT_BUFFER_SIZE = 5;\n\n static STREAM_TIMEOUT = 8000;\n\n static SNAPSHOT_HANDLER_TIMEOUT = 5;\n\n static defaultProps = {\n getDownloadWorker: (): Promise<never> =>\n Promise.reject(new Error('Download worker not provided')),\n isDownloading: false,\n onDownloadCompleted: (): void => undefined,\n onDownloadCanceled: (): void => undefined,\n onDownloadProgressUpdate: (): void => undefined,\n };\n\n static csvEscapeString(str: string): string {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n\n constructor(props: TableSaverProps) {\n super(props);\n\n this.handlePortMessage = this.handlePortMessage.bind(this);\n this.handleSnapshotResolved = this.handleSnapshotResolved.bind(this);\n this.handleDownloadTimeout = this.handleDownloadTimeout.bind(this);\n\n this.state = {};\n\n this.gridRanges = [];\n this.gridRangeCounter = 0;\n this.rangedSnapshotsTotal = [];\n this.rangedSnapshotCounter = 0;\n\n this.snapshotsTotal = 0;\n this.snapshotCounter = 0;\n this.snapshotsBuffer = new Map();\n\n this.currentSnapshotIndex = 0;\n this.snapshotPending = 0;\n this.cancelableSnapshots = [];\n\n // WritableStream is not supported in Firefox (also IE) yet. use ponyfillWritableStream instead\n this.WritableStream = window.WritableStream || ponyfillWritableStream;\n\n // Due to an open issue in Chromium, readableStream.cancel() is never called when a user cancel the stream from Chromium's UI and the stream goes on even it's canceled.\n // Instead, we monitor the pull() behavior from the readableStream called when the stream wants more data to write.\n // If the stream doesn't pull for long enough time, chances are the stream is already canceled, so we stop the stream.\n // Issue ticket on Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=638494\n\n this.iframes = [];\n\n this.useBlobFallback = false;\n }\n\n componentDidMount(): void {\n const { getDownloadWorker } = this.props;\n getDownloadWorker()\n .then(sw => {\n log.info('found active service worker');\n this.sw = sw;\n this.sw.postMessage('ping'); // just to activate the service worker\n })\n .catch(error => {\n // if service worker is not available, use blob as fallback to download table csv\n log.warn('Download csv is not optimized.', error);\n this.useBlobFallback = true;\n });\n }\n\n componentWillUnmount(): void {\n if (this.iframes.length > 0) {\n this.iframes.forEach(iframe => {\n iframe.remove();\n });\n }\n if (this.streamTimeout) clearTimeout(this.streamTimeout);\n if (this.snapshotHandlerTimeout) clearTimeout(this.snapshotHandlerTimeout);\n }\n\n sw?: ServiceWorker;\n\n port?: MessagePort;\n\n fileWriter?: WritableStreamDefaultWriter<unknown>;\n\n table?: Table;\n\n tableSubscription?: TableViewportSubscription;\n\n columns?: Column[];\n\n fileName?: string;\n\n chunkRows?: number;\n\n gridRanges: GridRange[];\n\n gridRangeCounter?: number;\n\n rangedSnapshotsTotal: number[];\n\n rangedSnapshotCounter?: number;\n\n snapshotsTotal: number;\n\n snapshotCounter: number;\n\n snapshotsBuffer: Map<number, UpdateEventData>;\n\n currentSnapshotIndex: number;\n\n snapshotPending: number;\n\n cancelableSnapshots: (CancelablePromise<unknown> | null)[];\n\n // WritableStream is not supported in Firefox (also IE) yet. use ponyfillWritableStream instead\n WritableStream = window.WritableStream || ponyfillWritableStream;\n\n // Due to an open issue in Chromium, readableStream.cancel() is never called when a user cancel the stream from Chromium's UI and the stream goes on even it's canceled.\n // Instead, we monitor the pull() behavior from the readableStream called when the stream wants more data to write.\n // If the stream doesn't pull for long enough time, chances are the stream is already canceled, so we stop the stream.\n // Issue ticket on Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=638494\n streamTimeout?: ReturnType<typeof setTimeout>;\n\n snapshotHandlerTimeout?: ReturnType<typeof setTimeout>;\n\n downloadStartTime?: number;\n\n iframes: HTMLIFrameElement[];\n\n useBlobFallback: boolean;\n\n getCachedCustomColumnFormatFlag = memoizeClear(\n FormatterUtils.isCustomColumnFormatDefined,\n { max: 10000 }\n );\n\n createWriterStream(port: MessagePort): WritableStream<ServiceWorker> {\n // use blob fall back if it's safari\n const useBlob = this.useBlobFallback;\n const chunks = [] as BlobPart[];\n let encode: ((input?: string) => Uint8Array) | null = null;\n if (useBlob) {\n encode = TextEncoder.prototype.encode.bind(new TextEncoder());\n }\n const { fileName } = this;\n\n const streamConfig = {} as UnderlyingSink;\n if (useBlob) {\n streamConfig.write = (chunk: { rows?: string; header?: string }) => {\n assertNotNull(encode);\n if (chunk.header !== undefined) {\n chunks.push(encode(chunk.header));\n }\n if (chunk.rows !== undefined) {\n chunks.push(encode(chunk.rows));\n }\n };\n streamConfig.close = () => {\n assertNotNull(fileName);\n const blob = new Blob(chunks, {\n type: 'application/octet-stream; charset=utf-8',\n });\n const link = document.createElement('a');\n link.href = URL.createObjectURL(blob);\n link.download = fileName;\n link.click();\n };\n streamConfig.abort = () => {\n port.postMessage({ cancel: true });\n port.close();\n };\n } else {\n streamConfig.write = (chunk: unknown) => {\n port.postMessage(chunk);\n };\n streamConfig.close = () => {\n port.postMessage({ end: true });\n port.close();\n };\n streamConfig.abort = () => {\n port.postMessage({ cancel: true });\n port.close();\n };\n }\n\n return new this.WritableStream(streamConfig);\n }\n\n startDownload(\n fileName: string,\n frozenTable: Table,\n tableSubscription: TableViewportSubscription,\n gridRanges: GridRange[]\n ): void {\n // don't trigger another download when a download is ongoing\n const { isDownloading } = this.props;\n if (isDownloading) {\n return;\n }\n\n this.downloadStartTime = Date.now();\n log.info(`start downloading ${fileName}`);\n\n this.table = frozenTable;\n this.columns = frozenTable.columns;\n this.tableSubscription = tableSubscription;\n this.gridRanges = gridRanges;\n\n // Make filename RFC5987 compatible\n const encodedFileName = encodeURIComponent(fileName.replace(/\\//g, ':'))\n .replace(/['()]/g, escape)\n .replace(/\\*/g, '%2A');\n\n const messageChannel = new MessageChannel();\n this.port = messageChannel.port1;\n this.fileName = fileName;\n this.fileWriter = this.createWriterStream(this.port).getWriter();\n\n // if the browser doesn't support stream or there's no active service worker, use blobs for table download\n if (this.useBlobFallback) {\n this.writeCsvTable();\n return;\n }\n\n if (this.sw) {\n // send file name and port to service worker\n this.sw.postMessage({ encodedFileName }, [messageChannel.port2]);\n }\n this.port.onmessage = this.handlePortMessage;\n }\n\n finishDownload(): void {\n if (this.table) {\n this.table.close();\n }\n if (this.tableSubscription) {\n this.tableSubscription.close();\n }\n if (this.fileWriter) {\n this.fileWriter.close();\n }\n\n const { onDownloadCompleted } = this.props;\n onDownloadCompleted();\n this.resetTableSaver();\n\n if (this.downloadStartTime) {\n log.info(\n `download finished, total elapsed time ${\n (Date.now() - this.downloadStartTime) / 1000\n } seconds`\n );\n }\n }\n\n cancelDownload(): void {\n if (this.table) {\n this.table.close();\n }\n if (this.tableSubscription) {\n this.tableSubscription.close();\n }\n if (this.fileWriter) {\n this.fileWriter.abort();\n }\n\n this.cancelableSnapshots.forEach(cancelable => {\n if (cancelable) {\n cancelable.catch(() => null);\n cancelable.cancel();\n }\n });\n const { onDownloadCanceled } = this.props;\n onDownloadCanceled();\n this.resetTableSaver();\n }\n\n resetTableSaver(): void {\n this.table = undefined;\n this.tableSubscription = undefined;\n this.columns = undefined;\n this.chunkRows = undefined;\n\n this.gridRanges = [];\n this.gridRangeCounter = 0;\n this.rangedSnapshotsTotal = [];\n this.rangedSnapshotCounter = 0;\n\n this.snapshotsTotal = 0;\n this.snapshotCounter = 0;\n this.snapshotsBuffer = new Map();\n\n this.currentSnapshotIndex = 0;\n this.snapshotPending = 0;\n this.cancelableSnapshots = [];\n\n if (this.streamTimeout != null) {\n clearTimeout(this.streamTimeout);\n }\n\n if (this.snapshotHandlerTimeout != null) {\n clearTimeout(this.snapshotHandlerTimeout);\n }\n this.streamTimeout = undefined;\n this.snapshotHandlerTimeout = undefined;\n }\n\n handleDownloadTimeout(): void {\n log.info('download canceled');\n this.cancelDownload();\n }\n\n writeTableHeader(): void {\n let headerString = '';\n if (this.columns) {\n for (let i = 0; i < this.columns.length; i += 1) {\n headerString += this.columns[i].name;\n headerString += i === this.columns.length - 1 ? '\\n' : ',';\n }\n }\n this.fileWriter?.write({ header: headerString }).then(() => null);\n }\n\n startWriteTableBody(): void {\n if (this.columns && this.gridRanges) {\n this.chunkRows = Math.floor(\n TableSaver.DOWNLOAD_CELL_CHUNK / this.columns.length\n );\n\n this.rangedSnapshotsTotal = this.gridRanges.map((range: GridRange) => {\n assertNotNull(range.endRow);\n assertNotNull(range.startRow);\n assertNotNull(this.chunkRows);\n\n return Math.ceil((range.endRow - range.startRow + 1) / this.chunkRows);\n });\n this.snapshotsTotal = this.rangedSnapshotsTotal.reduce(\n (total: number, snapshotCount: number) => total + snapshotCount\n );\n\n log.info(`start writing table, total snapshots: `, this.snapshotsTotal);\n\n this.makeSnapshot(\n Math.min(TableSaver.SNAPSHOT_BUFFER_SIZE, this.snapshotsTotal)\n );\n }\n }\n\n writeCsvTable(): void {\n this.writeTableHeader();\n this.startWriteTableBody();\n }\n\n writeSnapshot(\n snapshotIndex: number,\n snapshotStartRow: GridRangeIndex,\n snapshotEndRow: GridRangeIndex\n ): void {\n if (this.currentSnapshotIndex === snapshotIndex && this.fileWriter) {\n while (this.snapshotsBuffer.has(this.currentSnapshotIndex)) {\n const n = this.snapshotsBuffer.get(this.currentSnapshotIndex);\n assertNotNull(n);\n this.fileWriter.write({\n rows: this.convertSnapshotIntoCsv(n),\n });\n this.snapshotsBuffer.delete(this.currentSnapshotIndex);\n this.currentSnapshotIndex += 1;\n\n this.updateDownloadProgress(snapshotIndex);\n }\n if (\n this.snapshotsTotal &&\n this.currentSnapshotIndex >= this.snapshotsTotal\n ) {\n this.finishDownload();\n return;\n }\n }\n\n if (\n this.snapshotCounter &&\n this.snapshotsTotal &&\n this.snapshotCounter < this.snapshotsTotal\n ) {\n log.debug2(\n `\n current range index: ${this.gridRangeCounter}, \n snapshotIndexCounter: ${this.snapshotCounter}, \n currentRangedSnapshotIndex : ${this.rangedSnapshotCounter}, \n snapshotpending: ${this.snapshotPending}, \n buffered ${this.snapshotsBuffer.size}\n making ${Math.min(\n TableSaver.SNAPSHOT_BUFFER_SIZE -\n this.snapshotsBuffer.size -\n this.snapshotPending,\n this.snapshotsTotal - this.snapshotCounter\n )} more snapshots\n `\n );\n this.makeSnapshot(\n Math.min(\n TableSaver.SNAPSHOT_BUFFER_SIZE -\n this.snapshotsBuffer.size -\n this.snapshotPending,\n this.snapshotsTotal - this.snapshotCounter\n )\n );\n }\n }\n\n updateDownloadProgress(snapshotIndex: GridRangeIndex): void {\n if (\n snapshotIndex != null &&\n this.snapshotsTotal != null &&\n this.downloadStartTime != null\n ) {\n const { onDownloadProgressUpdate } = this.props;\n const downloadProgress = Math.floor(\n (snapshotIndex * 100) / this.snapshotsTotal\n );\n const estimateTime =\n snapshotIndex > 1\n ? Math.floor(\n ((Date.now() - this.downloadStartTime) *\n (this.snapshotsTotal - snapshotIndex)) /\n snapshotIndex /\n 1000\n )\n : null;\n\n onDownloadProgressUpdate(downloadProgress, estimateTime);\n }\n }\n\n convertSnapshotIntoCsv(snapshot: UpdateEventData): string {\n let csvString = '';\n const snapshotIterator = snapshot.added.iterator();\n const { formatter } = this.props;\n\n const rows = [];\n while (snapshotIterator.hasNext()) {\n rows.push(snapshotIterator.next().value);\n }\n\n assertNotNull(this.columns);\n\n for (let i = 0; i < rows.length; i += 1) {\n const rowIdx = rows[i];\n for (let j = 0; j < this.columns.length; j += 1) {\n const { type, name } = this.columns[j];\n const hasCustomColumnFormat = this.getCachedCustomColumnFormatFlag(\n formatter,\n name,\n type\n );\n let formatOverride = null;\n if (!hasCustomColumnFormat) {\n const cellFormat = snapshot.getFormat(rowIdx, this.columns[j]);\n formatOverride = cellFormat?.formatString != null ? cellFormat : null;\n }\n let cellData = null;\n if (formatOverride) {\n cellData = formatter.getFormattedString(\n snapshot.getData(rowIdx, this.columns[j]),\n type,\n name,\n formatOverride\n );\n } else {\n cellData = formatter.getFormattedString(\n snapshot.getData(rowIdx, this.columns[j]),\n type,\n name\n );\n }\n csvString += TableSaver.csvEscapeString(cellData);\n csvString += j === this.columns?.length - 1 ? '\\n' : ',';\n }\n }\n\n return csvString;\n }\n\n makeSnapshot(n: number): void {\n if (n <= 0) {\n return;\n }\n assertNotNull(this.gridRangeCounter);\n let i = 0;\n let currentGridRange = this.gridRanges[this.gridRangeCounter];\n\n assertNotNull(this.tableSubscription);\n assertNotNull(this.columns);\n while (i < n) {\n assertNotNull(currentGridRange);\n assertNotNull(currentGridRange.startRow);\n assertNotNull(currentGridRange.endRow);\n assertNotNull(this.rangedSnapshotCounter);\n assertNotNull(this.chunkRows);\n const snapshotStartRow =\n currentGridRange.startRow + this.rangedSnapshotCounter * this.chunkRows;\n const snapshotEndRow = Math.min(\n snapshotStartRow + this.chunkRows - 1,\n currentGridRange.endRow\n );\n\n const snapshotIndex = this.snapshotCounter;\n this.cancelableSnapshots.push(\n PromiseUtils.makeCancelable(\n this.tableSubscription\n .snapshot(\n dh.RangeSet.ofRange(snapshotStartRow, snapshotEndRow),\n this.columns\n )\n .then(snapshot => {\n assertIsUpdateEventData(snapshot);\n this.handleSnapshotResolved(\n snapshot,\n snapshotIndex,\n snapshotStartRow,\n snapshotEndRow\n );\n\n return snapshotIndex;\n })\n .catch(err => {\n log.error(err);\n }),\n val => {\n log.info(`snapshot ${val} has been canceled`);\n }\n )\n );\n\n this.rangedSnapshotCounter += 1;\n this.snapshotCounter += 1;\n this.snapshotPending += 1;\n\n if (\n this.rangedSnapshotCounter >=\n this.rangedSnapshotsTotal[this.gridRangeCounter]\n ) {\n this.gridRangeCounter += 1;\n this.rangedSnapshotCounter = 0;\n currentGridRange = this.gridRanges[this.gridRangeCounter];\n }\n i += 1;\n }\n }\n\n handlePortMessage({\n data,\n }: MessageEvent<{\n download: unknown;\n readableStreamPulling: unknown;\n }>): void {\n const { download, readableStreamPulling } = data;\n if (this.useBlobFallback) {\n return;\n }\n if (download) {\n this.makeIframe(`${download}`);\n this.writeCsvTable();\n }\n if (readableStreamPulling) {\n if (!this.useBlobFallback) {\n if (this.streamTimeout != null) {\n clearTimeout(this.streamTimeout);\n }\n this.streamTimeout = setTimeout(\n this.handleDownloadTimeout,\n TableSaver.STREAM_TIMEOUT\n );\n }\n }\n }\n\n handleSnapshotResolved(\n snapshot: UpdateEventData,\n snapshotIndex: number,\n snapshotStartRow: GridRangeIndex,\n snapshotEndRow: GridRangeIndex\n ): void {\n // use time out to break writeSnapshot into an individual task in browser with timeout, so there's window for the browser to update table in needed.\n this.snapshotHandlerTimeout = setTimeout(() => {\n this.snapshotsBuffer.set(snapshotIndex, snapshot);\n this.snapshotPending -= 1;\n this.writeSnapshot(snapshotIndex, snapshotStartRow, snapshotEndRow);\n this.cancelableSnapshots[snapshotIndex] = null;\n }, TableSaver.SNAPSHOT_HANDLER_TIMEOUT);\n }\n\n makeIframe(src: string): void {\n // make a return value and make it static method\n const iframe = document.createElement('iframe');\n iframe.hidden = true;\n iframe.src = `download/${src}`;\n iframe.name = 'iframe';\n document.body.appendChild(iframe);\n this.iframes.push(iframe);\n }\n\n render(): null {\n return null;\n }\n}\n"],"file":"TableSaver.js"}
1
+ {"version":3,"sources":["../../src/sidebar/TableSaver.jsx"],"names":["PureComponent","PropTypes","WritableStream","ponyfillWritableStream","dh","Formatter","FormatterUtils","Log","memoizeClear","PromiseUtils","log","module","TableSaver","csvEscapeString","str","replace","constructor","props","isCustomColumnFormatDefined","max","handlePortMessage","bind","handleSnapshotResolved","handleDownloadTimeout","state","sw","port","fileWriter","table","tableSubscription","columns","fileName","chunkRows","gridRanges","gridRangeCounter","rangedSnapshotsTotal","rangedSnapshotCounter","snapshotsTotal","snapshotCounter","snapshotsBuffer","Map","currentSnapshotIndex","snapshotPending","cancelableSnapshots","window","streamTimeout","snapshotHandlerTimeout","downloadStartTime","iframes","useBlobFallback","safari","componentDidMount","getDownloadWorker","then","info","postMessage","catch","error","warn","componentWillUnmount","length","forEach","iframe","remove","clearTimeout","createWriterStream","useBlob","chunks","encode","TextEncoder","prototype","streamConfig","write","chunk","header","undefined","push","rows","close","blob","Blob","type","link","document","createElement","href","URL","createObjectURL","download","click","abort","cancel","end","startDownload","frozenTable","isDownloading","Date","now","encodedFileName","encodeURIComponent","escape","messageChannel","MessageChannel","port1","getWriter","writeCsvTable","port2","onmessage","finishDownload","onDownloadCompleted","resetTableSaver","cancelDownload","cancelable","onDownloadCanceled","writeTableHeader","headerString","i","name","startWriteTableBody","Math","floor","DOWNLOAD_CELL_CHUNK","map","range","ceil","endRow","startRow","reduce","total","snapshotCount","makeSnapshot","min","SNAPSHOT_BUFFER_SIZE","writeSnapshot","snapshotIndex","snapshotStartRow","snapshotEndRow","has","convertSnapshotIntoCsv","get","delete","updateDownloadProgress","debug2","size","onDownloadProgressUpdate","downloadProgress","estimateTime","snapshot","csvString","snapshotIterator","added","iterator","formatter","hasNext","next","value","rowIdx","j","hasCustomColumnFormat","getCachedCustomColumnFormatFlag","formatOverride","cellFormat","getFormat","formatString","cellData","getFormattedString","getData","n","currentGridRange","makeCancelable","RangeSet","ofRange","err","val","data","readableStreamPulling","makeIframe","setTimeout","STREAM_TIMEOUT","set","SNAPSHOT_HANDLER_TIMEOUT","src","hidden","loaded","isIframe","addEventListener","body","appendChild","render","propTypes","func","bool","instanceOf","isRequired","defaultProps","Promise","reject","Error"],"mappings":"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","sourcesContent":["import { PureComponent } from 'react';\nimport PropTypes from 'prop-types';\nimport { WritableStream as ponyfillWritableStream } from 'web-streams-polyfill/dist/ponyfill.js';\nimport dh from '@deephaven/jsapi-shim';\nimport { Formatter, FormatterUtils } from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport { memoizeClear } from '@deephaven/grid';\nimport { PromiseUtils } from '@deephaven/utils';\n\nconst log = Log.module('TableSaver');\n\nexport default class TableSaver extends PureComponent {\n static DOWNLOAD_CELL_CHUNK = 6000;\n\n static SNAPSHOT_BUFFER_SIZE = 5;\n\n static STREAM_TIMEOUT = 8000;\n\n static SNAPSHOT_HANDLER_TIMEOUT = 5;\n\n static csvEscapeString(str) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n\n constructor(props) {\n super(props);\n\n this.handlePortMessage = this.handlePortMessage.bind(this);\n this.handleSnapshotResolved = this.handleSnapshotResolved.bind(this);\n this.handleDownloadTimeout = this.handleDownloadTimeout.bind(this);\n\n this.state = {};\n\n this.sw = null;\n this.port = null;\n this.fileWriter = null;\n\n this.table = null;\n this.tableSubscription = null;\n this.columns = null;\n\n this.fileName = null;\n\n this.chunkRows = null;\n\n this.gridRanges = [];\n this.gridRangeCounter = 0;\n this.rangedSnapshotsTotal = [];\n this.rangedSnapshotCounter = 0;\n\n this.snapshotsTotal = 0;\n this.snapshotCounter = 0;\n this.snapshotsBuffer = new Map();\n\n this.currentSnapshotIndex = 0;\n this.snapshotPending = 0;\n this.cancelableSnapshots = [];\n\n // WritableStream is not supported in Firefox (also IE) yet. use ponyfillWritableStream instead\n this.WritableStream = window.WritableStream || ponyfillWritableStream;\n\n // Due to an open issue in Chromium, readableStream.cancel() is never called when a user cancel the stream from Chromium's UI and the stream goes on even it's canceled.\n // Instead, we monitor the pull() behavior from the readableStream called when the stream wants more data to write.\n // If the stream doesn't pull for long enough time, chances are the stream is already canceled, so we stop the stream.\n // Issue ticket on Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=638494\n this.streamTimeout = null;\n\n this.snapshotHandlerTimeout = null;\n\n this.downloadStartTime = null;\n\n this.iframes = [];\n\n this.useBlobFallback = !!window.safari;\n }\n\n componentDidMount() {\n const { getDownloadWorker } = this.props;\n getDownloadWorker()\n .then(sw => {\n log.info('found active service worker');\n this.sw = sw;\n this.sw.postMessage('ping'); // just to activate the service worker\n })\n .catch(error => {\n // if service worker is not available, use blob as fallback to download table csv\n log.warn('Download csv is not optimized.', error);\n this.useBlobFallback = true;\n });\n }\n\n componentWillUnmount() {\n if (this.iframes.length > 0) {\n this.iframes.forEach(iframe => {\n iframe.remove();\n });\n }\n clearTimeout(this.streamTimeout);\n clearTimeout(this.snapshotHandlerTimeout);\n }\n\n getCachedCustomColumnFormatFlag = memoizeClear(\n FormatterUtils.isCustomColumnFormatDefined,\n { max: 10000 }\n );\n\n createWriterStream(port) {\n // use blob fall back if it's safari\n const useBlob = this.useBlobFallback;\n const chunks = [];\n let encode = null;\n if (useBlob) {\n encode = TextEncoder.prototype.encode.bind(new TextEncoder());\n }\n const { fileName } = this;\n\n const streamConfig = {};\n if (useBlob) {\n streamConfig.write = chunk => {\n if (chunk.header !== undefined) {\n chunks.push(encode(chunk.header));\n }\n if (chunk.rows !== undefined) {\n chunks.push(encode(chunk.rows));\n }\n };\n streamConfig.close = () => {\n const blob = new Blob(chunks, {\n type: 'application/octet-stream; charset=utf-8',\n });\n const link = document.createElement('a');\n link.href = URL.createObjectURL(blob);\n link.download = fileName;\n link.click();\n };\n streamConfig.abort = () => {\n port.postMessage({ cancel: true });\n port.close();\n };\n } else {\n streamConfig.write = chunk => {\n port.postMessage(chunk);\n };\n streamConfig.close = () => {\n port.postMessage({ end: true });\n port.close();\n };\n streamConfig.abort = () => {\n port.postMessage({ cancel: true });\n port.close();\n };\n }\n\n return new this.WritableStream(streamConfig);\n }\n\n startDownload(fileName, frozenTable, tableSubscription, gridRanges) {\n // don't trigger another download when a download is ongoing\n const { isDownloading } = this.props;\n if (isDownloading) {\n return;\n }\n\n this.downloadStartTime = Date.now();\n log.info(`start downloading ${fileName}`);\n\n this.table = frozenTable;\n this.columns = frozenTable.columns;\n this.tableSubscription = tableSubscription;\n this.gridRanges = gridRanges;\n\n // Make filename RFC5987 compatible\n const encodedFileName = encodeURIComponent(fileName.replace(/\\//g, ':'))\n .replace(/['()]/g, escape)\n .replace(/\\*/g, '%2A');\n\n const messageChannel = new MessageChannel();\n this.port = messageChannel.port1;\n this.fileName = fileName;\n this.fileWriter = this.createWriterStream(this.port).getWriter();\n\n // if the browser doesn't support stream or there's no active service worker, use blobs for table download\n if (this.useBlobFallback) {\n this.writeCsvTable();\n return;\n }\n\n if (this.sw) {\n // send file name and port to service worker\n this.sw.postMessage({ encodedFileName }, [messageChannel.port2]);\n }\n this.port.onmessage = this.handlePortMessage;\n }\n\n finishDownload() {\n if (this.table) {\n this.table.close();\n }\n if (this.tableSubscription) {\n this.tableSubscription.close();\n }\n if (this.fileWriter) {\n this.fileWriter.close();\n }\n\n const { onDownloadCompleted } = this.props;\n onDownloadCompleted();\n this.resetTableSaver();\n\n log.info(\n `download finished, total elapsed time ${\n (Date.now() - this.downloadStartTime) / 1000\n } seconds`\n );\n }\n\n cancelDownload() {\n if (this.table) {\n this.table.close();\n }\n if (this.tableSubscription) {\n this.tableSubscription.close();\n }\n if (this.fileWriter) {\n this.fileWriter.abort();\n }\n\n this.cancelableSnapshots.forEach(cancelable => {\n if (cancelable) {\n cancelable.catch(() => {});\n cancelable.cancel();\n }\n });\n const { onDownloadCanceled } = this.props;\n onDownloadCanceled();\n this.resetTableSaver();\n }\n\n resetTableSaver() {\n this.table = null;\n this.tableSubscription = null;\n this.columns = null;\n this.chunkRows = null;\n\n this.gridRanges = [];\n this.gridRangeCounter = 0;\n this.rangedSnapshotsTotal = [];\n this.rangedSnapshotCounter = 0;\n\n this.snapshotsTotal = 0;\n this.snapshotCounter = 0;\n this.snapshotsBuffer = new Map();\n\n this.currentSnapshotIndex = 0;\n this.snapshotPending = 0;\n this.cancelableSnapshots = [];\n\n clearTimeout(this.streamTimeout);\n clearTimeout(this.snapshotHandlerTimeout);\n this.streamTimeout = null;\n this.snapshotHandlerTimeout = null;\n }\n\n handleDownloadTimeout() {\n log.info('download canceled');\n this.cancelDownload();\n }\n\n writeTableHeader() {\n let headerString = '';\n for (let i = 0; i < this.columns.length; i += 1) {\n headerString += this.columns[i].name;\n headerString += i === this.columns.length - 1 ? '\\n' : ',';\n }\n this.fileWriter.write({ header: headerString }).then(() => {});\n }\n\n startWriteTableBody() {\n this.chunkRows = Math.floor(\n TableSaver.DOWNLOAD_CELL_CHUNK / this.columns.length\n );\n\n this.rangedSnapshotsTotal = this.gridRanges.map(range =>\n Math.ceil((range.endRow - range.startRow + 1) / this.chunkRows)\n );\n this.snapshotsTotal = this.rangedSnapshotsTotal.reduce(\n (total, snapshotCount) => total + snapshotCount\n );\n\n log.info(`start writing table, total snapshots: `, this.snapshotsTotal);\n\n this.makeSnapshot(\n Math.min(TableSaver.SNAPSHOT_BUFFER_SIZE, this.snapshotsTotal)\n );\n }\n\n writeCsvTable() {\n this.writeTableHeader();\n this.startWriteTableBody();\n }\n\n writeSnapshot(snapshotIndex, snapshotStartRow, snapshotEndRow) {\n if (this.currentSnapshotIndex === snapshotIndex && this.fileWriter) {\n while (this.snapshotsBuffer.has(this.currentSnapshotIndex)) {\n this.fileWriter.write({\n rows: this.convertSnapshotIntoCsv(\n this.snapshotsBuffer.get(this.currentSnapshotIndex),\n snapshotStartRow,\n snapshotEndRow\n ),\n });\n this.snapshotsBuffer.delete(this.currentSnapshotIndex);\n this.currentSnapshotIndex += 1;\n\n this.updateDownloadProgress(snapshotIndex);\n }\n if (this.currentSnapshotIndex >= this.snapshotsTotal) {\n this.finishDownload();\n return;\n }\n }\n\n if (this.snapshotCounter < this.snapshotsTotal) {\n log.debug2(\n `\n current range index: ${this.gridRangeCounter}, \n snapshotIndexCounter: ${this.snapshotCounter}, \n currentRangedSnapshotIndex : ${this.rangedSnapshotCounter}, \n snapshotpending: ${this.snapshotPending}, \n buffered ${this.snapshotsBuffer.size}\n making ${Math.min(\n TableSaver.SNAPSHOT_BUFFER_SIZE -\n this.snapshotsBuffer.size -\n this.snapshotPending,\n this.snapshotsTotal - this.snapshotCounter\n )} more snapshots\n `\n );\n this.makeSnapshot(\n Math.min(\n TableSaver.SNAPSHOT_BUFFER_SIZE -\n this.snapshotsBuffer.size -\n this.snapshotPending,\n this.snapshotsTotal - this.snapshotCounter\n )\n );\n }\n }\n\n updateDownloadProgress(snapshotIndex) {\n const { onDownloadProgressUpdate } = this.props;\n const downloadProgress = Math.floor(\n (snapshotIndex * 100) / this.snapshotsTotal\n );\n const estimateTime =\n snapshotIndex > 1\n ? Math.floor(\n ((Date.now() - this.downloadStartTime) *\n (this.snapshotsTotal - snapshotIndex)) /\n snapshotIndex /\n 1000\n )\n : null;\n\n onDownloadProgressUpdate(downloadProgress, estimateTime);\n }\n\n convertSnapshotIntoCsv(snapshot) {\n let csvString = '';\n const snapshotIterator = snapshot.added.iterator();\n const { formatter } = this.props;\n\n const rows = [];\n while (snapshotIterator.hasNext()) {\n rows.push(snapshotIterator.next().value);\n }\n\n for (let i = 0; i < rows.length; i += 1) {\n const rowIdx = rows[i];\n for (let j = 0; j < this.columns.length; j += 1) {\n const { type, name } = this.columns[j];\n const hasCustomColumnFormat = this.getCachedCustomColumnFormatFlag(\n formatter,\n name,\n type\n );\n let formatOverride = null;\n if (!hasCustomColumnFormat) {\n const cellFormat = snapshot.getFormat(rowIdx, this.columns[j]);\n formatOverride = cellFormat?.formatString != null ? cellFormat : null;\n }\n const cellData = formatter.getFormattedString(\n snapshot.getData(rowIdx, this.columns[j]),\n type,\n name,\n formatOverride\n );\n csvString += TableSaver.csvEscapeString(cellData);\n csvString += j === this.columns.length - 1 ? '\\n' : ',';\n }\n }\n\n return csvString;\n }\n\n makeSnapshot(n) {\n if (n <= 0) {\n return;\n }\n let i = 0;\n let currentGridRange = this.gridRanges[this.gridRangeCounter];\n while (i < n) {\n const snapshotStartRow =\n currentGridRange.startRow + this.rangedSnapshotCounter * this.chunkRows;\n const snapshotEndRow = Math.min(\n snapshotStartRow + this.chunkRows - 1,\n currentGridRange.endRow\n );\n\n const snapshotIndex = this.snapshotCounter;\n this.cancelableSnapshots.push(\n PromiseUtils.makeCancelable(\n this.tableSubscription\n .snapshot(\n dh.RangeSet.ofRange(snapshotStartRow, snapshotEndRow),\n this.columns\n )\n .then(snapshot => {\n this.handleSnapshotResolved(\n snapshot,\n snapshotIndex,\n snapshotStartRow,\n snapshotEndRow\n );\n\n return snapshotIndex;\n })\n .catch(err => {\n log.error(err);\n }),\n val => {\n log.info(`snapshot ${val} has been canceled`);\n }\n )\n );\n\n this.rangedSnapshotCounter += 1;\n this.snapshotCounter += 1;\n this.snapshotPending += 1;\n\n if (\n this.rangedSnapshotCounter >=\n this.rangedSnapshotsTotal[this.gridRangeCounter]\n ) {\n this.gridRangeCounter += 1;\n this.rangedSnapshotCounter = 0;\n currentGridRange = this.gridRanges[this.gridRangeCounter];\n }\n i += 1;\n }\n }\n\n handlePortMessage({ data }) {\n const { download, readableStreamPulling } = data;\n if (this.useBlobFallback) {\n return;\n }\n if (download) {\n this.makeIframe(`${download}`);\n this.writeCsvTable();\n }\n if (readableStreamPulling) {\n if (!this.useBlobFallback) {\n clearTimeout(this.streamTimeout);\n\n this.streamTimeout = setTimeout(\n this.handleDownloadTimeout,\n TableSaver.STREAM_TIMEOUT\n );\n }\n }\n }\n\n handleSnapshotResolved(\n snapshot,\n snapshotIndex,\n snapshotStartRow,\n snapshotEndRow\n ) {\n // use time out to break writeSnapshot into an individual task in browser with timeout, so there's window for the browser to update table in needed.\n this.snapshotHandlerTimeout = setTimeout(() => {\n this.snapshotsBuffer.set(snapshotIndex, snapshot);\n this.snapshotPending -= 1;\n this.writeSnapshot(snapshotIndex, snapshotStartRow, snapshotEndRow);\n this.cancelableSnapshots[snapshotIndex] = null;\n }, TableSaver.SNAPSHOT_HANDLER_TIMEOUT);\n }\n\n makeIframe(src) {\n // make a return value and make it static method\n const iframe = document.createElement('iframe');\n iframe.hidden = true;\n iframe.src = `download/${src}`;\n iframe.loaded = false;\n iframe.name = 'iframe';\n iframe.isIframe = true;\n iframe.addEventListener(\n 'load',\n () => {\n iframe.loaded = true;\n },\n false\n );\n document.body.appendChild(iframe);\n this.iframes.push(iframe);\n }\n\n render() {\n return null;\n }\n}\n\nTableSaver.propTypes = {\n getDownloadWorker: PropTypes.func,\n isDownloading: PropTypes.bool,\n onDownloadCompleted: PropTypes.func,\n onDownloadCanceled: PropTypes.func,\n onDownloadProgressUpdate: PropTypes.func,\n formatter: PropTypes.instanceOf(Formatter).isRequired,\n};\n\nTableSaver.defaultProps = {\n getDownloadWorker: () =>\n Promise.reject(new Error('Download worker not provided')),\n isDownloading: false,\n onDownloadCompleted: () => {},\n onDownloadCanceled: () => {},\n onDownloadProgressUpdate: () => {},\n};\n"],"file":"TableSaver.js"}