@kitware/vtk.js
Version:
Visualization Toolkit for the Web
219 lines (201 loc) • 6.73 kB
JavaScript
import { m as macro } from '../../../macros2.js';
import Endian from '../../../Common/Core/Endian.js';
import { DataTypeByteSize } from '../../../Common/Core/DataArray/Constants.js';
import { has, registerType } from '../DataAccessHelper.js';
const {
vtkErrorMacro,
vtkDebugMacro
} = macro;
const REJECT_COMPRESSION = () => {
vtkErrorMacro('LiteHttpDataAccessHelper does not support compression. Need to register HttpDataAccessHelper instead.');
return Promise.reject(new Error('LiteHttpDataAccessHelper does not support compression. Need to register HttpDataAccessHelper instead.'));
};
/* eslint-disable prefer-promise-reject-errors */
let requestCount = 0;
function openAsyncXHR(method, url) {
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
const xhr = new XMLHttpRequest();
xhr.open(method, url, true);
if (options.headers) {
Object.entries(options.headers).forEach(_ref => {
let [key, value] = _ref;
return xhr.setRequestHeader(key, value);
});
}
if (options.progressCallback) {
xhr.addEventListener('progress', options.progressCallback);
}
return xhr;
}
function fetchBinary(url) {
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return new Promise((resolve, reject) => {
const xhr = openAsyncXHR('GET', url, options);
xhr.onreadystatechange = e => {
if (xhr.readyState === 4) {
if (xhr.status === 200 || xhr.status === 0) {
resolve(xhr.response);
} else {
reject({
xhr,
e
});
}
}
};
// Make request
xhr.responseType = 'arraybuffer';
xhr.send();
});
}
function fetchArray(instance, baseURL, array) {
let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
if (options && options.compression) {
return REJECT_COMPRESSION();
}
if (array.ref && !array.ref.pending) {
return new Promise((resolve, reject) => {
const url = [baseURL, array.ref.basepath, array.ref.id].join('/');
const xhr = openAsyncXHR('GET', url, options);
xhr.onreadystatechange = e => {
if (xhr.readyState === 1) {
array.ref.pending = true;
if (++requestCount === 1 && instance?.invokeBusy) {
instance.invokeBusy(true);
}
}
if (xhr.readyState === 4) {
array.ref.pending = false;
if (xhr.status === 200 || xhr.status === 0) {
array.buffer = xhr.response;
if (array.ref.encode === 'JSON') {
array.values = JSON.parse(array.buffer);
} else {
if (Endian.ENDIANNESS !== array.ref.encode && Endian.ENDIANNESS) {
// Need to swap bytes
vtkDebugMacro(`Swap bytes of ${array.name}`);
Endian.swapBytes(array.buffer, DataTypeByteSize[array.dataType]);
}
array.values = macro.newTypedArray(array.dataType, array.buffer);
}
if (array.values.length !== array.size) {
vtkErrorMacro(`Error in FetchArray: ${array.name}, does not have the proper array size. Got ${array.values.length}, instead of ${array.size}`);
}
// Done with the ref and work
delete array.ref;
if (--requestCount === 0 && instance?.invokeBusy) {
instance.invokeBusy(false);
}
if (instance?.modified) {
instance.modified();
}
resolve(array);
} else {
reject({
xhr,
e
});
}
}
};
// Make request
xhr.responseType = array.dataType !== 'string' ? 'arraybuffer' : 'text';
xhr.send();
});
}
return Promise.resolve(array);
}
// ----------------------------------------------------------------------------
function fetchJSON(instance, url) {
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
if (options && options.compression) {
return REJECT_COMPRESSION();
}
return new Promise((resolve, reject) => {
const xhr = openAsyncXHR('GET', url, options);
xhr.onreadystatechange = e => {
if (xhr.readyState === 1) {
if (++requestCount === 1 && instance?.invokeBusy) {
instance.invokeBusy(true);
}
}
if (xhr.readyState === 4) {
if (--requestCount === 0 && instance?.invokeBusy) {
instance.invokeBusy(false);
}
if (xhr.status === 200 || xhr.status === 0) {
resolve(JSON.parse(xhr.responseText));
} else {
reject({
xhr,
e
});
}
}
};
// Make request
xhr.responseType = 'text';
xhr.send();
});
}
// ----------------------------------------------------------------------------
function fetchText(instance, url) {
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
if (options && options.compression) {
return REJECT_COMPRESSION();
}
return new Promise((resolve, reject) => {
const xhr = openAsyncXHR('GET', url, options);
xhr.onreadystatechange = e => {
if (xhr.readyState === 1) {
if (++requestCount === 1 && instance?.invokeBusy) {
instance.invokeBusy(true);
}
}
if (xhr.readyState === 4) {
if (--requestCount === 0 && instance?.invokeBusy) {
instance.invokeBusy(false);
}
if (xhr.status === 200 || xhr.status === 0) {
resolve(xhr.responseText);
} else {
reject({
xhr,
e
});
}
}
};
// Make request
xhr.responseType = 'text';
xhr.send();
});
}
// ----------------------------------------------------------------------------
function fetchImage(instance, url) {
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
return new Promise((resolve, reject) => {
const img = new Image();
if (options.crossOrigin) {
img.crossOrigin = options.crossOrigin;
}
img.onload = () => resolve(img);
img.onerror = reject;
img.src = url;
});
}
/* eslint-enable prefer-promise-reject-errors */
// ----------------------------------------------------------------------------
const LiteHttpDataAccessHelper = {
fetchArray,
fetchJSON,
fetchText,
fetchBinary,
// Only for HTTP
fetchImage
};
// The lite version should never override a full feature one...
if (!has('http')) {
registerType('http', options => LiteHttpDataAccessHelper);
}
export { LiteHttpDataAccessHelper as default };