@deephaven/iris-grid 0.13.3-treemap.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AdvancedFilterCreator.d.ts +69 -63
- package/dist/AdvancedFilterCreator.d.ts.map +1 -1
- package/dist/AdvancedFilterCreator.js +79 -73
- package/dist/AdvancedFilterCreator.js.map +1 -1
- package/dist/AdvancedFilterCreatorSelectValue.d.ts +45 -45
- package/dist/AdvancedFilterCreatorSelectValue.d.ts.map +1 -1
- package/dist/AdvancedFilterCreatorSelectValue.js +32 -36
- package/dist/AdvancedFilterCreatorSelectValue.js.map +1 -1
- package/dist/AdvancedFilterCreatorSelectValueList.d.ts +47 -52
- package/dist/AdvancedFilterCreatorSelectValueList.d.ts.map +1 -1
- package/dist/AdvancedFilterCreatorSelectValueList.js +24 -39
- package/dist/AdvancedFilterCreatorSelectValueList.js.map +1 -1
- package/dist/ColumnStatistics.d.ts +34 -22
- package/dist/ColumnStatistics.d.ts.map +1 -1
- package/dist/ColumnStatistics.js +8 -12
- package/dist/ColumnStatistics.js.map +1 -1
- package/dist/CommonTypes.d.ts +58 -0
- package/dist/CommonTypes.d.ts.map +1 -0
- package/dist/CommonTypes.js +2 -0
- package/dist/CommonTypes.js.map +1 -0
- package/dist/CrossColumnSearch.d.ts +26 -24
- package/dist/CrossColumnSearch.d.ts.map +1 -1
- package/dist/CrossColumnSearch.js +9 -13
- package/dist/CrossColumnSearch.js.map +1 -1
- package/dist/FilterInputField.d.ts +48 -51
- package/dist/FilterInputField.d.ts.map +1 -1
- package/dist/FilterInputField.js +30 -27
- package/dist/FilterInputField.js.map +1 -1
- package/dist/IrisGrid.d.ts +409 -453
- package/dist/IrisGrid.d.ts.map +1 -1
- package/dist/IrisGrid.js +514 -449
- package/dist/IrisGrid.js.map +1 -1
- package/dist/IrisGridCellOverflowModal.d.ts +1 -1
- package/dist/IrisGridCellOverflowModal.d.ts.map +1 -1
- package/dist/IrisGridCellOverflowModal.js.map +1 -1
- package/dist/IrisGridCopyHandler.d.ts +52 -46
- package/dist/IrisGridCopyHandler.d.ts.map +1 -1
- package/dist/IrisGridCopyHandler.js +22 -38
- package/dist/IrisGridCopyHandler.js.map +1 -1
- package/dist/IrisGridMetricCalculator.d.ts +5 -4
- package/dist/IrisGridMetricCalculator.d.ts.map +1 -1
- package/dist/IrisGridMetricCalculator.js +5 -1
- package/dist/IrisGridMetricCalculator.js.map +1 -1
- package/dist/IrisGridModel.d.ts +37 -35
- package/dist/IrisGridModel.d.ts.map +1 -1
- package/dist/IrisGridModel.js +19 -3
- package/dist/IrisGridModel.js.map +1 -1
- package/dist/IrisGridModelFactory.d.ts +7 -5
- package/dist/IrisGridModelFactory.d.ts.map +1 -1
- package/dist/IrisGridModelFactory.js +5 -5
- package/dist/IrisGridModelFactory.js.map +1 -1
- package/dist/IrisGridModelUpdater.d.ts +13 -11
- package/dist/IrisGridModelUpdater.d.ts.map +1 -1
- package/dist/IrisGridModelUpdater.js.map +1 -1
- package/dist/IrisGridPartitionSelector.d.ts +38 -39
- package/dist/IrisGridPartitionSelector.d.ts.map +1 -1
- package/dist/IrisGridPartitionSelector.js +18 -24
- package/dist/IrisGridPartitionSelector.js.map +1 -1
- package/dist/IrisGridProxyModel.d.ts +111 -32
- package/dist/IrisGridProxyModel.d.ts.map +1 -1
- package/dist/IrisGridProxyModel.js +212 -170
- package/dist/IrisGridProxyModel.js.map +1 -1
- package/dist/IrisGridRenderer.d.ts +59 -31
- package/dist/IrisGridRenderer.d.ts.map +1 -1
- package/dist/IrisGridRenderer.js +92 -46
- package/dist/IrisGridRenderer.js.map +1 -1
- package/dist/IrisGridTableModel.d.ts +48 -147
- package/dist/IrisGridTableModel.d.ts.map +1 -1
- package/dist/IrisGridTableModel.js +58 -1381
- package/dist/IrisGridTableModel.js.map +1 -1
- package/dist/IrisGridTableModelTemplate.d.ts +219 -0
- package/dist/IrisGridTableModelTemplate.d.ts.map +1 -0
- package/dist/IrisGridTableModelTemplate.js +1623 -0
- package/dist/IrisGridTableModelTemplate.js.map +1 -0
- package/dist/IrisGridTestUtils.d.ts +18 -14
- package/dist/IrisGridTestUtils.d.ts.map +1 -1
- package/dist/IrisGridTestUtils.js +29 -1
- package/dist/IrisGridTestUtils.js.map +1 -1
- package/dist/IrisGridTheme.d.ts +35 -3
- package/dist/IrisGridTheme.d.ts.map +1 -1
- package/dist/IrisGridTheme.js.map +1 -1
- package/dist/IrisGridTreeTableModel.d.ts +26 -7
- package/dist/IrisGridTreeTableModel.d.ts.map +1 -1
- package/dist/IrisGridTreeTableModel.js +24 -14
- package/dist/IrisGridTreeTableModel.js.map +1 -1
- package/dist/IrisGridUtils.d.ts +257 -162
- package/dist/IrisGridUtils.d.ts.map +1 -1
- package/dist/IrisGridUtils.js +132 -95
- package/dist/IrisGridUtils.js.map +1 -1
- package/dist/MissingKeyError.d.ts +5 -3
- package/dist/MissingKeyError.d.ts.map +1 -1
- package/dist/MissingKeyError.js.map +1 -1
- package/dist/PartitionSelectorSearch.d.ts +61 -40
- package/dist/PartitionSelectorSearch.d.ts.map +1 -1
- package/dist/PartitionSelectorSearch.js +25 -15
- package/dist/PartitionSelectorSearch.js.map +1 -1
- package/dist/PendingDataBottomBar.d.ts +3 -6
- package/dist/PendingDataBottomBar.d.ts.map +1 -1
- package/dist/PendingDataBottomBar.js.map +1 -1
- package/dist/TableViewportUpdater.d.ts +39 -55
- package/dist/TableViewportUpdater.d.ts.map +1 -1
- package/dist/TableViewportUpdater.js +42 -64
- package/dist/TableViewportUpdater.js.map +1 -1
- package/dist/TreeTableViewportUpdater.d.ts +29 -37
- package/dist/TreeTableViewportUpdater.d.ts.map +1 -1
- package/dist/TreeTableViewportUpdater.js +39 -50
- package/dist/TreeTableViewportUpdater.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/mousehandlers/IrisGridCellOverflowMouseHandler.d.ts.map +1 -1
- package/dist/mousehandlers/IrisGridCellOverflowMouseHandler.js.map +1 -1
- package/dist/mousehandlers/IrisGridColumnSelectMouseHandler.d.ts +1 -1
- package/dist/mousehandlers/IrisGridColumnSelectMouseHandler.d.ts.map +1 -1
- package/dist/mousehandlers/IrisGridColumnSelectMouseHandler.js +2 -0
- package/dist/mousehandlers/IrisGridColumnSelectMouseHandler.js.map +1 -1
- package/dist/mousehandlers/IrisGridColumnTooltipMouseHandler.js +1 -1
- package/dist/mousehandlers/IrisGridColumnTooltipMouseHandler.js.map +1 -1
- package/dist/mousehandlers/IrisGridContextMenuHandler.d.ts +41 -130
- package/dist/mousehandlers/IrisGridContextMenuHandler.d.ts.map +1 -1
- package/dist/mousehandlers/IrisGridContextMenuHandler.js +426 -317
- package/dist/mousehandlers/IrisGridContextMenuHandler.js.map +1 -1
- package/dist/mousehandlers/IrisGridFilterMouseHandler.d.ts.map +1 -1
- package/dist/mousehandlers/IrisGridFilterMouseHandler.js +2 -2
- package/dist/mousehandlers/IrisGridFilterMouseHandler.js.map +1 -1
- package/dist/mousehandlers/IrisGridSortMouseHandler.js +1 -1
- package/dist/mousehandlers/IrisGridSortMouseHandler.js.map +1 -1
- package/dist/mousehandlers/PendingMouseHandler.d.ts +8 -4
- package/dist/mousehandlers/PendingMouseHandler.d.ts.map +1 -1
- package/dist/mousehandlers/PendingMouseHandler.js +4 -5
- package/dist/mousehandlers/PendingMouseHandler.js.map +1 -1
- package/dist/sidebar/ChartBuilder.d.ts +48 -33
- package/dist/sidebar/ChartBuilder.d.ts.map +1 -1
- package/dist/sidebar/ChartBuilder.js +28 -27
- package/dist/sidebar/ChartBuilder.js.map +1 -1
- package/dist/sidebar/CustomColumnBuilder.d.ts +51 -41
- package/dist/sidebar/CustomColumnBuilder.d.ts.map +1 -1
- package/dist/sidebar/CustomColumnBuilder.js +22 -18
- package/dist/sidebar/CustomColumnBuilder.js.map +1 -1
- package/dist/sidebar/CustomColumnInput.d.ts +26 -36
- package/dist/sidebar/CustomColumnInput.d.ts.map +1 -1
- package/dist/sidebar/CustomColumnInput.js +11 -20
- package/dist/sidebar/CustomColumnInput.js.map +1 -1
- package/dist/sidebar/InputEditor.d.ts +34 -35
- package/dist/sidebar/InputEditor.d.ts.map +1 -1
- package/dist/sidebar/InputEditor.js +43 -24
- package/dist/sidebar/InputEditor.js.map +1 -1
- package/dist/sidebar/RollupRows.d.ts +67 -52
- package/dist/sidebar/RollupRows.d.ts.map +1 -1
- package/dist/sidebar/RollupRows.js +51 -53
- package/dist/sidebar/RollupRows.js.map +1 -1
- package/dist/sidebar/SelectDistinctBuilder.d.ts +27 -21
- package/dist/sidebar/SelectDistinctBuilder.d.ts.map +1 -1
- package/dist/sidebar/SelectDistinctBuilder.js +6 -10
- package/dist/sidebar/SelectDistinctBuilder.js.map +1 -1
- package/dist/sidebar/TableCsvExporter.d.ts +42 -39
- package/dist/sidebar/TableCsvExporter.d.ts.map +1 -1
- package/dist/sidebar/TableCsvExporter.js +12 -20
- package/dist/sidebar/TableCsvExporter.js.map +1 -1
- package/dist/sidebar/TableSaver.d.ts +59 -60
- package/dist/sidebar/TableSaver.d.ts.map +1 -1
- package/dist/sidebar/TableSaver.js +154 -68
- package/dist/sidebar/TableSaver.js.map +1 -1
- package/dist/sidebar/VisibilityOrderingBuilder.d.ts +56 -45
- package/dist/sidebar/VisibilityOrderingBuilder.d.ts.map +1 -1
- package/dist/sidebar/VisibilityOrderingBuilder.js +34 -29
- package/dist/sidebar/VisibilityOrderingBuilder.js.map +1 -1
- package/dist/sidebar/aggregations/Aggregations.d.ts.map +1 -1
- package/dist/sidebar/aggregations/Aggregations.js.map +1 -1
- package/dist/sidebar/conditional-formatting/ConditionalFormattingMenu.d.ts +2 -1
- package/dist/sidebar/conditional-formatting/ConditionalFormattingMenu.d.ts.map +1 -1
- package/dist/sidebar/conditional-formatting/ConditionalFormattingMenu.js.map +1 -1
- package/dist/sidebar/conditional-formatting/ConditionalFormattingUtils.d.ts +6 -5
- package/dist/sidebar/conditional-formatting/ConditionalFormattingUtils.d.ts.map +1 -1
- package/dist/sidebar/conditional-formatting/ConditionalFormattingUtils.js +5 -0
- package/dist/sidebar/conditional-formatting/ConditionalFormattingUtils.js.map +1 -1
- package/dist/sidebar/icons/index.d.ts +7 -7
- package/dist/sidebar/icons/index.d.ts.map +1 -1
- package/dist/sidebar/icons/index.js.map +1 -1
- package/dist/sidebar/index.d.ts +12 -12
- package/dist/sidebar/index.d.ts.map +1 -1
- package/dist/sidebar/index.js.map +1 -1
- package/package.json +17 -16
|
@@ -1,14 +1,24 @@
|
|
|
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
|
|
5
|
-
import { WritableStream as ponyfillWritableStream } from 'web-streams-polyfill/dist/ponyfill.js';
|
|
4
|
+
import { WritableStream as ponyfillWritableStream } from 'web-streams-polyfill/ponyfill';
|
|
6
5
|
import dh from '@deephaven/jsapi-shim';
|
|
7
|
-
import { Formatter, FormatterUtils } from '@deephaven/jsapi-utils';
|
|
8
6
|
import Log from '@deephaven/log';
|
|
9
7
|
import { memoizeClear } from '@deephaven/grid';
|
|
10
|
-
import {
|
|
8
|
+
import { FormatterUtils } from '@deephaven/jsapi-utils';
|
|
9
|
+
import { PromiseUtils, assertNotNull } from '@deephaven/utils';
|
|
11
10
|
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
|
+
|
|
12
22
|
export default class TableSaver extends PureComponent {
|
|
13
23
|
static csvEscapeString(str) {
|
|
14
24
|
return "\"".concat(str.replace(/"/g, '""'), "\"");
|
|
@@ -17,6 +27,54 @@ export default class TableSaver extends PureComponent {
|
|
|
17
27
|
constructor(props) {
|
|
18
28
|
super(props);
|
|
19
29
|
|
|
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
|
+
|
|
20
78
|
_defineProperty(this, "getCachedCustomColumnFormatFlag", memoizeClear(FormatterUtils.isCustomColumnFormatDefined, {
|
|
21
79
|
max: 10000
|
|
22
80
|
}));
|
|
@@ -25,14 +83,6 @@ export default class TableSaver extends PureComponent {
|
|
|
25
83
|
this.handleSnapshotResolved = this.handleSnapshotResolved.bind(this);
|
|
26
84
|
this.handleDownloadTimeout = this.handleDownloadTimeout.bind(this);
|
|
27
85
|
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;
|
|
36
86
|
this.gridRanges = [];
|
|
37
87
|
this.gridRangeCounter = 0;
|
|
38
88
|
this.rangedSnapshotsTotal = [];
|
|
@@ -49,11 +99,8 @@ export default class TableSaver extends PureComponent {
|
|
|
49
99
|
// If the stream doesn't pull for long enough time, chances are the stream is already canceled, so we stop the stream.
|
|
50
100
|
// Issue ticket on Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=638494
|
|
51
101
|
|
|
52
|
-
this.streamTimeout = null;
|
|
53
|
-
this.snapshotHandlerTimeout = null;
|
|
54
|
-
this.downloadStartTime = null;
|
|
55
102
|
this.iframes = [];
|
|
56
|
-
this.useBlobFallback =
|
|
103
|
+
this.useBlobFallback = false;
|
|
57
104
|
}
|
|
58
105
|
|
|
59
106
|
componentDidMount() {
|
|
@@ -78,8 +125,8 @@ export default class TableSaver extends PureComponent {
|
|
|
78
125
|
});
|
|
79
126
|
}
|
|
80
127
|
|
|
81
|
-
clearTimeout(this.streamTimeout);
|
|
82
|
-
clearTimeout(this.snapshotHandlerTimeout);
|
|
128
|
+
if (this.streamTimeout) clearTimeout(this.streamTimeout);
|
|
129
|
+
if (this.snapshotHandlerTimeout) clearTimeout(this.snapshotHandlerTimeout);
|
|
83
130
|
}
|
|
84
131
|
|
|
85
132
|
createWriterStream(port) {
|
|
@@ -99,6 +146,8 @@ export default class TableSaver extends PureComponent {
|
|
|
99
146
|
|
|
100
147
|
if (useBlob) {
|
|
101
148
|
streamConfig.write = chunk => {
|
|
149
|
+
assertNotNull(encode);
|
|
150
|
+
|
|
102
151
|
if (chunk.header !== undefined) {
|
|
103
152
|
chunks.push(encode(chunk.header));
|
|
104
153
|
}
|
|
@@ -109,6 +158,7 @@ export default class TableSaver extends PureComponent {
|
|
|
109
158
|
};
|
|
110
159
|
|
|
111
160
|
streamConfig.close = () => {
|
|
161
|
+
assertNotNull(fileName);
|
|
112
162
|
var blob = new Blob(chunks, {
|
|
113
163
|
type: 'application/octet-stream; charset=utf-8'
|
|
114
164
|
});
|
|
@@ -203,7 +253,10 @@ export default class TableSaver extends PureComponent {
|
|
|
203
253
|
} = this.props;
|
|
204
254
|
onDownloadCompleted();
|
|
205
255
|
this.resetTableSaver();
|
|
206
|
-
|
|
256
|
+
|
|
257
|
+
if (this.downloadStartTime) {
|
|
258
|
+
log.info("download finished, total elapsed time ".concat((Date.now() - this.downloadStartTime) / 1000, " seconds"));
|
|
259
|
+
}
|
|
207
260
|
}
|
|
208
261
|
|
|
209
262
|
cancelDownload() {
|
|
@@ -221,7 +274,7 @@ export default class TableSaver extends PureComponent {
|
|
|
221
274
|
|
|
222
275
|
this.cancelableSnapshots.forEach(cancelable => {
|
|
223
276
|
if (cancelable) {
|
|
224
|
-
cancelable.catch(() =>
|
|
277
|
+
cancelable.catch(() => null);
|
|
225
278
|
cancelable.cancel();
|
|
226
279
|
}
|
|
227
280
|
});
|
|
@@ -233,10 +286,10 @@ export default class TableSaver extends PureComponent {
|
|
|
233
286
|
}
|
|
234
287
|
|
|
235
288
|
resetTableSaver() {
|
|
236
|
-
this.table =
|
|
237
|
-
this.tableSubscription =
|
|
238
|
-
this.columns =
|
|
239
|
-
this.chunkRows =
|
|
289
|
+
this.table = undefined;
|
|
290
|
+
this.tableSubscription = undefined;
|
|
291
|
+
this.columns = undefined;
|
|
292
|
+
this.chunkRows = undefined;
|
|
240
293
|
this.gridRanges = [];
|
|
241
294
|
this.gridRangeCounter = 0;
|
|
242
295
|
this.rangedSnapshotsTotal = [];
|
|
@@ -247,10 +300,17 @@ export default class TableSaver extends PureComponent {
|
|
|
247
300
|
this.currentSnapshotIndex = 0;
|
|
248
301
|
this.snapshotPending = 0;
|
|
249
302
|
this.cancelableSnapshots = [];
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
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;
|
|
254
314
|
}
|
|
255
315
|
|
|
256
316
|
handleDownloadTimeout() {
|
|
@@ -259,24 +319,35 @@ export default class TableSaver extends PureComponent {
|
|
|
259
319
|
}
|
|
260
320
|
|
|
261
321
|
writeTableHeader() {
|
|
322
|
+
var _this$fileWriter;
|
|
323
|
+
|
|
262
324
|
var headerString = '';
|
|
263
325
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
+
}
|
|
267
331
|
}
|
|
268
332
|
|
|
269
|
-
this.fileWriter.write({
|
|
333
|
+
(_this$fileWriter = this.fileWriter) === null || _this$fileWriter === void 0 ? void 0 : _this$fileWriter.write({
|
|
270
334
|
header: headerString
|
|
271
|
-
}).then(() =>
|
|
335
|
+
}).then(() => null);
|
|
272
336
|
}
|
|
273
337
|
|
|
274
338
|
startWriteTableBody() {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
+
}
|
|
280
351
|
}
|
|
281
352
|
|
|
282
353
|
writeCsvTable() {
|
|
@@ -287,33 +358,37 @@ export default class TableSaver extends PureComponent {
|
|
|
287
358
|
writeSnapshot(snapshotIndex, snapshotStartRow, snapshotEndRow) {
|
|
288
359
|
if (this.currentSnapshotIndex === snapshotIndex && this.fileWriter) {
|
|
289
360
|
while (this.snapshotsBuffer.has(this.currentSnapshotIndex)) {
|
|
361
|
+
var n = this.snapshotsBuffer.get(this.currentSnapshotIndex);
|
|
362
|
+
assertNotNull(n);
|
|
290
363
|
this.fileWriter.write({
|
|
291
|
-
rows: this.convertSnapshotIntoCsv(
|
|
364
|
+
rows: this.convertSnapshotIntoCsv(n)
|
|
292
365
|
});
|
|
293
366
|
this.snapshotsBuffer.delete(this.currentSnapshotIndex);
|
|
294
367
|
this.currentSnapshotIndex += 1;
|
|
295
368
|
this.updateDownloadProgress(snapshotIndex);
|
|
296
369
|
}
|
|
297
370
|
|
|
298
|
-
if (this.currentSnapshotIndex >= this.snapshotsTotal) {
|
|
371
|
+
if (this.snapshotsTotal && this.currentSnapshotIndex >= this.snapshotsTotal) {
|
|
299
372
|
this.finishDownload();
|
|
300
373
|
return;
|
|
301
374
|
}
|
|
302
375
|
}
|
|
303
376
|
|
|
304
|
-
if (this.snapshotCounter < this.snapshotsTotal) {
|
|
377
|
+
if (this.snapshotCounter && this.snapshotsTotal && this.snapshotCounter < this.snapshotsTotal) {
|
|
305
378
|
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 "));
|
|
306
379
|
this.makeSnapshot(Math.min(TableSaver.SNAPSHOT_BUFFER_SIZE - this.snapshotsBuffer.size - this.snapshotPending, this.snapshotsTotal - this.snapshotCounter));
|
|
307
380
|
}
|
|
308
381
|
}
|
|
309
382
|
|
|
310
383
|
updateDownloadProgress(snapshotIndex) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
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
|
+
}
|
|
317
392
|
}
|
|
318
393
|
|
|
319
394
|
convertSnapshotIntoCsv(snapshot) {
|
|
@@ -328,10 +403,14 @@ export default class TableSaver extends PureComponent {
|
|
|
328
403
|
rows.push(snapshotIterator.next().value);
|
|
329
404
|
}
|
|
330
405
|
|
|
406
|
+
assertNotNull(this.columns);
|
|
407
|
+
|
|
331
408
|
for (var i = 0; i < rows.length; i += 1) {
|
|
332
409
|
var rowIdx = rows[i];
|
|
333
410
|
|
|
334
411
|
for (var j = 0; j < this.columns.length; j += 1) {
|
|
412
|
+
var _this$columns;
|
|
413
|
+
|
|
335
414
|
var {
|
|
336
415
|
type,
|
|
337
416
|
name
|
|
@@ -344,9 +423,16 @@ export default class TableSaver extends PureComponent {
|
|
|
344
423
|
formatOverride = (cellFormat === null || cellFormat === void 0 ? void 0 : cellFormat.formatString) != null ? cellFormat : null;
|
|
345
424
|
}
|
|
346
425
|
|
|
347
|
-
var cellData =
|
|
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
|
+
|
|
348
434
|
csvString += TableSaver.csvEscapeString(cellData);
|
|
349
|
-
csvString += j === this.columns.length - 1 ? '\n' : ',';
|
|
435
|
+
csvString += j === ((_this$columns = this.columns) === null || _this$columns === void 0 ? void 0 : _this$columns.length) - 1 ? '\n' : ',';
|
|
350
436
|
}
|
|
351
437
|
}
|
|
352
438
|
|
|
@@ -360,15 +446,25 @@ export default class TableSaver extends PureComponent {
|
|
|
360
446
|
return;
|
|
361
447
|
}
|
|
362
448
|
|
|
449
|
+
assertNotNull(this.gridRangeCounter);
|
|
363
450
|
var i = 0;
|
|
364
451
|
var currentGridRange = this.gridRanges[this.gridRangeCounter];
|
|
452
|
+
assertNotNull(this.tableSubscription);
|
|
453
|
+
assertNotNull(this.columns);
|
|
365
454
|
|
|
366
455
|
var _loop = function _loop() {
|
|
456
|
+
assertNotNull(currentGridRange);
|
|
457
|
+
assertNotNull(currentGridRange.startRow);
|
|
458
|
+
assertNotNull(currentGridRange.endRow);
|
|
459
|
+
assertNotNull(_this.rangedSnapshotCounter);
|
|
460
|
+
assertNotNull(_this.chunkRows);
|
|
367
461
|
var snapshotStartRow = currentGridRange.startRow + _this.rangedSnapshotCounter * _this.chunkRows;
|
|
368
462
|
var snapshotEndRow = Math.min(snapshotStartRow + _this.chunkRows - 1, currentGridRange.endRow);
|
|
369
463
|
var snapshotIndex = _this.snapshotCounter;
|
|
370
464
|
|
|
371
465
|
_this.cancelableSnapshots.push(PromiseUtils.makeCancelable(_this.tableSubscription.snapshot(dh.RangeSet.ofRange(snapshotStartRow, snapshotEndRow), _this.columns).then(snapshot => {
|
|
466
|
+
assertIsUpdateEventData(snapshot);
|
|
467
|
+
|
|
372
468
|
_this.handleSnapshotResolved(snapshot, snapshotIndex, snapshotStartRow, snapshotEndRow);
|
|
373
469
|
|
|
374
470
|
return snapshotIndex;
|
|
@@ -416,7 +512,10 @@ export default class TableSaver extends PureComponent {
|
|
|
416
512
|
|
|
417
513
|
if (readableStreamPulling) {
|
|
418
514
|
if (!this.useBlobFallback) {
|
|
419
|
-
|
|
515
|
+
if (this.streamTimeout != null) {
|
|
516
|
+
clearTimeout(this.streamTimeout);
|
|
517
|
+
}
|
|
518
|
+
|
|
420
519
|
this.streamTimeout = setTimeout(this.handleDownloadTimeout, TableSaver.STREAM_TIMEOUT);
|
|
421
520
|
}
|
|
422
521
|
}
|
|
@@ -437,12 +536,7 @@ export default class TableSaver extends PureComponent {
|
|
|
437
536
|
var iframe = document.createElement('iframe');
|
|
438
537
|
iframe.hidden = true;
|
|
439
538
|
iframe.src = "download/".concat(src);
|
|
440
|
-
iframe.loaded = false;
|
|
441
539
|
iframe.name = 'iframe';
|
|
442
|
-
iframe.isIframe = true;
|
|
443
|
-
iframe.addEventListener('load', () => {
|
|
444
|
-
iframe.loaded = true;
|
|
445
|
-
}, false);
|
|
446
540
|
document.body.appendChild(iframe);
|
|
447
541
|
this.iframes.push(iframe);
|
|
448
542
|
}
|
|
@@ -461,19 +555,11 @@ _defineProperty(TableSaver, "STREAM_TIMEOUT", 8000);
|
|
|
461
555
|
|
|
462
556
|
_defineProperty(TableSaver, "SNAPSHOT_HANDLER_TIMEOUT", 5);
|
|
463
557
|
|
|
464
|
-
TableSaver
|
|
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 = {
|
|
558
|
+
_defineProperty(TableSaver, "defaultProps", {
|
|
473
559
|
getDownloadWorker: () => Promise.reject(new Error('Download worker not provided')),
|
|
474
560
|
isDownloading: false,
|
|
475
|
-
onDownloadCompleted: () =>
|
|
476
|
-
onDownloadCanceled: () =>
|
|
477
|
-
onDownloadProgressUpdate: () =>
|
|
478
|
-
};
|
|
561
|
+
onDownloadCompleted: () => undefined,
|
|
562
|
+
onDownloadCanceled: () => undefined,
|
|
563
|
+
onDownloadProgressUpdate: () => undefined
|
|
564
|
+
});
|
|
479
565
|
//# sourceMappingURL=TableSaver.js.map
|
|
@@ -1 +1 @@
|
|
|
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"}
|
|
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":"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","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"}
|