Skip to content

Commit b762c71

Browse files
authored
Merge pull request #1840 from Kitware/better-bundle-size-management
Better bundle size management
2 parents b670afa + 88c10ef commit b762c71

File tree

12 files changed

+266
-166
lines changed

12 files changed

+266
-166
lines changed

Diff for: .eslintrc.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const path = require('path');
22
const prettierConf = require('./prettier.config.js');
33

44
module.exports = {
5-
extends: ['airbnb', 'prettier'],
5+
extends: ['airbnb/base', 'prettier'],
66
rules: {
77
'prettier/prettier': ['error', prettierConf],
88

Diff for: Sources/IO/Core/DataAccessHelper/HtmlDataAccessHelper.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import macro from 'vtk.js/Sources/macro';
44
import Base64 from 'vtk.js/Sources/Common/Core/Base64';
55
import Endian from 'vtk.js/Sources/Common/Core/Endian';
66
import { DataTypeByteSize } from 'vtk.js/Sources/Common/Core/DataArray/Constants';
7+
import { registerType } from 'vtk.js/Sources/IO/Core/DataAccessHelper';
78

89
const { vtkErrorMacro, vtkDebugMacro } = macro;
910

@@ -131,10 +132,14 @@ function fetchImage(instance = {}, url, options = {}) {
131132

132133
// ----------------------------------------------------------------------------
133134

134-
// Export fetch methods
135-
export default {
135+
const HtmlDataAccessHelper = {
136136
fetchJSON,
137137
fetchText,
138138
fetchArray,
139139
fetchImage,
140140
};
141+
142+
registerType('html', (options) => HtmlDataAccessHelper);
143+
144+
// Export fetch methods
145+
export default HtmlDataAccessHelper;

Diff for: Sources/IO/Core/DataAccessHelper/HttpDataAccessHelper.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import pako from 'pako';
33
import macro from 'vtk.js/Sources/macro';
44
import Endian from 'vtk.js/Sources/Common/Core/Endian';
55
import { DataTypeByteSize } from 'vtk.js/Sources/Common/Core/DataArray/Constants';
6+
import { registerType } from 'vtk.js/Sources/IO/Core/DataAccessHelper';
67

78
const { vtkErrorMacro, vtkDebugMacro } = macro;
89

@@ -221,15 +222,18 @@ function fetchImage(instance = {}, url, options = {}) {
221222
img.src = url;
222223
});
223224
}
225+
/* eslint-enable prefer-promise-reject-errors */
224226

225227
// ----------------------------------------------------------------------------
226228

227-
export default {
229+
const HttpDataAccessHelper = {
228230
fetchArray,
229231
fetchJSON,
230232
fetchText,
231233
fetchBinary, // Only for HTTP
232234
fetchImage,
233235
};
234236

235-
/* eslint-enable prefer-promise-reject-errors */
237+
registerType('http', (options) => HttpDataAccessHelper);
238+
239+
export default HttpDataAccessHelper;

Diff for: Sources/IO/Core/DataAccessHelper/JSZipDataAccessHelper.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import pako from 'pako';
44
import macro from 'vtk.js/Sources/macro';
55
import Endian from 'vtk.js/Sources/Common/Core/Endian';
66
import { DataTypeByteSize } from 'vtk.js/Sources/Common/Core/DataArray/Constants';
7+
import { registerType } from 'vtk.js/Sources/IO/Core/DataAccessHelper';
78

89
const { vtkErrorMacro, vtkDebugMacro } = macro;
910

@@ -245,6 +246,10 @@ function create(createOptions) {
245246
};
246247
}
247248

248-
export default {
249+
const JSZipDataAccessHelper = {
249250
create,
250251
};
252+
253+
registerType('zip', (options) => JSZipDataAccessHelper.create(options));
254+
255+
export default JSZipDataAccessHelper;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
import macro from 'vtk.js/Sources/macro';
2+
import Endian from 'vtk.js/Sources/Common/Core/Endian';
3+
import { DataTypeByteSize } from 'vtk.js/Sources/Common/Core/DataArray/Constants';
4+
import { registerType } from 'vtk.js/Sources/IO/Core/DataAccessHelper';
5+
6+
const { vtkErrorMacro, vtkDebugMacro } = macro;
7+
8+
const REJECT_COMPRESSION = () => {
9+
vtkErrorMacro(
10+
'LiteHttpDataAccessHelper does not support compression. Need to register HttpDataAccessHelper instead.'
11+
);
12+
return Promise.reject(
13+
new Error(
14+
'LiteHttpDataAccessHelper does not support compression. Need to register HttpDataAccessHelper instead.'
15+
)
16+
);
17+
};
18+
19+
/* eslint-disable prefer-promise-reject-errors */
20+
let requestCount = 0;
21+
22+
function openAsyncXHR(method, url, options = {}) {
23+
const xhr = new XMLHttpRequest();
24+
xhr.open(method, url, true);
25+
26+
if (options.headers) {
27+
Object.entries(options.headers).forEach(([key, value]) =>
28+
xhr.setRequestHeader(key, value)
29+
);
30+
}
31+
32+
if (options.progressCallback) {
33+
xhr.addEventListener('progress', options.progressCallback);
34+
}
35+
36+
return xhr;
37+
}
38+
39+
function fetchBinary(url, options = {}) {
40+
return new Promise((resolve, reject) => {
41+
const xhr = openAsyncXHR('GET', url, options);
42+
43+
xhr.onreadystatechange = (e) => {
44+
if (xhr.readyState === 4) {
45+
if (xhr.status === 200 || xhr.status === 0) {
46+
resolve(xhr.response);
47+
} else {
48+
reject({ xhr, e });
49+
}
50+
}
51+
};
52+
53+
// Make request
54+
xhr.responseType = 'arraybuffer';
55+
xhr.send();
56+
});
57+
}
58+
59+
function fetchArray(instance = {}, baseURL, array, options = {}) {
60+
if (options && options.compression) {
61+
return REJECT_COMPRESSION();
62+
}
63+
64+
if (array.ref && !array.ref.pending) {
65+
return new Promise((resolve, reject) => {
66+
const url = [baseURL, array.ref.basepath, array.ref.id].join('/');
67+
const xhr = openAsyncXHR('GET', url, options);
68+
69+
xhr.onreadystatechange = (e) => {
70+
if (xhr.readyState === 1) {
71+
array.ref.pending = true;
72+
if (++requestCount === 1 && instance.invokeBusy) {
73+
instance.invokeBusy(true);
74+
}
75+
}
76+
if (xhr.readyState === 4) {
77+
array.ref.pending = false;
78+
if (xhr.status === 200 || xhr.status === 0) {
79+
array.buffer = xhr.response;
80+
81+
if (array.ref.encode === 'JSON') {
82+
array.values = JSON.parse(array.buffer);
83+
} else {
84+
if (Endian.ENDIANNESS !== array.ref.encode && Endian.ENDIANNESS) {
85+
// Need to swap bytes
86+
vtkDebugMacro(`Swap bytes of ${array.name}`);
87+
Endian.swapBytes(
88+
array.buffer,
89+
DataTypeByteSize[array.dataType]
90+
);
91+
}
92+
93+
array.values = new window[array.dataType](array.buffer);
94+
}
95+
96+
if (array.values.length !== array.size) {
97+
vtkErrorMacro(
98+
`Error in FetchArray: ${array.name}, does not have the proper array size. Got ${array.values.length}, instead of ${array.size}`
99+
);
100+
}
101+
102+
// Done with the ref and work
103+
delete array.ref;
104+
if (--requestCount === 0 && instance.invokeBusy) {
105+
instance.invokeBusy(false);
106+
}
107+
if (instance.modified) {
108+
instance.modified();
109+
}
110+
resolve(array);
111+
} else {
112+
reject({ xhr, e });
113+
}
114+
}
115+
};
116+
117+
// Make request
118+
xhr.responseType = array.dataType !== 'string' ? 'arraybuffer' : 'text';
119+
xhr.send();
120+
});
121+
}
122+
123+
return Promise.resolve(array);
124+
}
125+
126+
// ----------------------------------------------------------------------------
127+
128+
function fetchJSON(instance = {}, url, options = {}) {
129+
if (options && options.compression) {
130+
return REJECT_COMPRESSION();
131+
}
132+
133+
return new Promise((resolve, reject) => {
134+
const xhr = openAsyncXHR('GET', url, options);
135+
136+
xhr.onreadystatechange = (e) => {
137+
if (xhr.readyState === 1) {
138+
if (++requestCount === 1 && instance.invokeBusy) {
139+
instance.invokeBusy(true);
140+
}
141+
}
142+
if (xhr.readyState === 4) {
143+
if (--requestCount === 0 && instance.invokeBusy) {
144+
instance.invokeBusy(false);
145+
}
146+
if (xhr.status === 200 || xhr.status === 0) {
147+
resolve(JSON.parse(xhr.responseText));
148+
} else {
149+
reject({ xhr, e });
150+
}
151+
}
152+
};
153+
154+
// Make request
155+
xhr.responseType = 'text';
156+
xhr.send();
157+
});
158+
}
159+
160+
// ----------------------------------------------------------------------------
161+
162+
function fetchText(instance = {}, url, options = {}) {
163+
if (options && options.compression) {
164+
return REJECT_COMPRESSION();
165+
}
166+
167+
return new Promise((resolve, reject) => {
168+
const xhr = openAsyncXHR('GET', url, options);
169+
170+
xhr.onreadystatechange = (e) => {
171+
if (xhr.readyState === 1) {
172+
if (++requestCount === 1 && instance.invokeBusy) {
173+
instance.invokeBusy(true);
174+
}
175+
}
176+
if (xhr.readyState === 4) {
177+
if (--requestCount === 0 && instance.invokeBusy) {
178+
instance.invokeBusy(false);
179+
}
180+
if (xhr.status === 200 || xhr.status === 0) {
181+
resolve(xhr.responseText);
182+
} else {
183+
reject({ xhr, e });
184+
}
185+
}
186+
};
187+
188+
// Make request
189+
xhr.responseType = 'text';
190+
xhr.send();
191+
});
192+
}
193+
194+
// ----------------------------------------------------------------------------
195+
196+
function fetchImage(instance = {}, url, options = {}) {
197+
return new Promise((resolve, reject) => {
198+
const img = new Image();
199+
if (options.crossOrigin) {
200+
img.crossOrigin = options.crossOrigin;
201+
}
202+
img.onload = () => resolve(img);
203+
img.onerror = reject;
204+
img.src = url;
205+
});
206+
}
207+
/* eslint-enable prefer-promise-reject-errors */
208+
209+
// ----------------------------------------------------------------------------
210+
211+
const LiteHttpDataAccessHelper = {
212+
fetchArray,
213+
fetchJSON,
214+
fetchText,
215+
fetchBinary, // Only for HTTP
216+
fetchImage,
217+
};
218+
219+
registerType('http', (options) => LiteHttpDataAccessHelper);
220+
221+
export default LiteHttpDataAccessHelper;

Diff for: Sources/IO/Core/DataAccessHelper/index.js

+7-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
import HtmlDataAccessHelper from './HtmlDataAccessHelper';
2-
import HttpDataAccessHelper from './HttpDataAccessHelper';
3-
import JSZipDataAccessHelper from './JSZipDataAccessHelper';
1+
const TYPE_MAPPING = {};
42

5-
const TYPE_MAPPING = {
6-
http: (options) => HttpDataAccessHelper,
7-
zip: (options) => JSZipDataAccessHelper.create(options),
8-
html: (options) => HtmlDataAccessHelper,
9-
};
10-
11-
function get(type = 'http', options = {}) {
3+
export function get(type = 'http', options = {}) {
124
return TYPE_MAPPING[type](options);
135
}
146

7+
export function registerType(type, fn) {
8+
TYPE_MAPPING[type] = fn;
9+
}
10+
1511
export default {
1612
get,
13+
registerType,
1714
};

Diff for: Sources/IO/Core/index.js

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
// Bundle size management - start
2+
import './DataAccessHelper/HtmlDataAccessHelper';
3+
import './DataAccessHelper/HttpDataAccessHelper';
4+
import './DataAccessHelper/JSZipDataAccessHelper';
5+
// Bundle size management - end
6+
17
import BinaryHelper from './BinaryHelper';
28
import DataAccessHelper from './DataAccessHelper';
39
import vtkHttpDataSetReader from './HttpDataSetReader';

Diff for: Sources/Rendering/Core/ColorTransferFunction/index.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import macro from 'vtk.js/Sources/macro';
22
import * as vtkMath from 'vtk.js/Sources/Common/Core/Math';
33
import vtkScalarsToColors from 'vtk.js/Sources/Common/Core/ScalarsToColors';
44
import Constants from 'vtk.js/Sources/Rendering/Core/ColorTransferFunction/Constants';
5-
import vtkColorMaps from 'vtk.js/Sources/Rendering/Core/ColorTransferFunction/ColorMaps';
65

76
const { ColorSpace, Scale } = Constants;
87
const { ScalarMappingTarget } = vtkScalarsToColors;
@@ -1272,4 +1271,4 @@ export const newInstance = macro.newInstance(
12721271

12731272
// ----------------------------------------------------------------------------
12741273

1275-
export default { newInstance, extend, vtkColorMaps, ...Constants };
1274+
export default { newInstance, extend, ...Constants };

Diff for: Sources/Rendering/Core/index.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// Bundle size management - start
2+
import vtkColorMaps from './ColorTransferFunction/ColorMaps';
3+
// Bundle size management - end
4+
15
import vtkAbstractMapper from './AbstractMapper';
26
import vtkAbstractMapper3D from './AbstractMapper3D';
37
import vtkAbstractPicker from './AbstractPicker';
@@ -48,7 +52,7 @@ export default {
4852
vtkAxesActor,
4953
vtkCamera,
5054
vtkCellPicker,
51-
vtkColorTransferFunction,
55+
vtkColorTransferFunction: { vtkColorMaps, ...vtkColorTransferFunction },
5256
vtkCoordinate,
5357
vtkCubeAxesActor,
5458
vtkFollower,

Diff for: Sources/tests.js

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
// Load default classes for tests
2+
import './IO/Core/DataAccessHelper/HtmlDataAccessHelper';
3+
import './IO/Core/DataAccessHelper/HttpDataAccessHelper';
4+
import './IO/Core/DataAccessHelper/JSZipDataAccessHelper';
5+
6+
// Test list
17
import './Common/Core/CellArray/test/testCellArray';
28
import './Common/Core/LookupTable/test/testCategoricalColors';
39
import './Common/Core/Math/test/testMath';

0 commit comments

Comments
 (0)