zincjs 1.20.1-beta.3 → 2.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zincjs",
3
- "version": "1.20.1-beta.3",
3
+ "version": "2.0.0",
4
4
  "description": "ZincJS (Web-based-Zinc-Visualisation)",
5
5
  "main": "build/zinc.js",
6
6
  "directories": {
@@ -17,11 +17,14 @@
17
17
  ],
18
18
  "scripts": {
19
19
  "build-bundle": "vite build",
20
- "test": "npm --prefix ./test install && npm --prefix ./test run test-ci",
20
+ "test-watch": "vitest",
21
+ "test": "vitest run --reporter=junit --outputFile=test-results.xml",
22
+ "test-standard": "vitest run",
21
23
  "changelog": "auto-changelog -p --output CHANGELOG.md --template keepachangelog",
22
24
  "jsdoc": "jsdoc -c jsdoc_conf.json",
23
25
  "version": "npm run build-bundle;npm run jsdoc;npm run changelog; git add CHANGELOG.md docs",
24
26
  "release:beta": "npm version prerelease --preid=beta; npm publish --tag beta",
27
+ "release:major": "npm version major; npm publish",
25
28
  "release:minor": "npm version minor; npm publish",
26
29
  "release:patch": "npm version patch; npm publish"
27
30
  },
@@ -42,25 +45,23 @@
42
45
  },
43
46
  "homepage": "http://alan-wu.github.io/ZincJS/",
44
47
  "devDependencies": {
45
- "@babel/core": "^7.23.9",
46
- "@babel/preset-env": "^7.23.9",
48
+ "@vitest/coverage-v8": "^1.6.1",
47
49
  "auto-changelog": "^2.4.0",
48
- "babel-preset-minify": "^0.5.1",
49
- "file-loader": "^6.2.0",
50
+ "chai": "^4.1.0",
51
+ "gl": "^6.0.2",
52
+ "happy-dom": "^20.10.6",
50
53
  "jsdoc": "^4.0.2",
51
- "raw-loader": "^4.0.2",
54
+ "msw": "^2.14.6",
52
55
  "vite": "^5.0.10",
56
+ "vite-plugin-node-polyfills": "^0.28.0",
57
+ "vitest": "^1.6.1",
53
58
  "webpack-node-externals": "^3.0.0"
54
59
  },
55
60
  "dependencies": {
56
61
  "css-element-queries": "^1.2.2",
57
62
  "lodash": "^4.17.19",
58
63
  "nifti-reader-js": "0.8.0",
59
- "promise-polyfill": "^8.1.3",
60
64
  "three": "^0.130.1",
61
- "three-spritetext": "1.6.2",
62
- "url-loader": "^4.1.1",
63
- "url-polyfill": "^1.1.7",
64
- "webworkify-webpack": "^2.1.5"
65
+ "three-spritetext": "1.6.2"
65
66
  }
66
67
  }
package/src/controls.js CHANGED
@@ -851,18 +851,24 @@ const CameraControls = function ( object, domElement, renderer, scene ) {
851
851
  * @param {requestCallback} finishCallback - The callback once the path is load.
852
852
  */
853
853
  this.loadPathURL = (path_url, finishCallback) => {
854
- const xmlhttp = new XMLHttpRequest();
855
- xmlhttp.onreadystatechange = () => {
856
- if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
857
- const pathData = JSON.parse(xmlhttp.responseText);
858
- this.loadPath(pathData);
859
- if (finishCallback != undefined && (typeof finishCallback == 'function'))
860
- finishCallback();
861
- }
862
- }
863
- const requestURL = resolveURL(path_url);
864
- xmlhttp.open("GET", requestURL, true);
865
- xmlhttp.send();
854
+ const requestURL = resolveURL(path_url);
855
+ fetch(requestURL)
856
+ .then((response) => {
857
+ if (!response.ok) {
858
+ throw new Error(`HTTP error! status: ${response.status}`);
859
+ }
860
+ return response.json();
861
+ })
862
+ .then((pathData) => {
863
+ this.loadPath(pathData);
864
+ if (finishCallback !== undefined && typeof finishCallback === 'function') {
865
+ finishCallback();
866
+ }
867
+ })
868
+ .catch((error) => {
869
+ console.error(`Failed to load path asset from: ${requestURL}`, error);
870
+ });
871
+
866
872
  }
867
873
 
868
874
  /**
@@ -1593,7 +1599,7 @@ const RayCaster = function (sceneIn, hostSceneIn, callbackFunctionIn, hoverCallb
1593
1599
  const renderer = rendererIn;
1594
1600
  const callbackFunction = callbackFunctionIn;
1595
1601
  const hoverCallbackFunction = hoverCallbackFunctionIn;
1596
- const enabled = true;
1602
+ let enabled = true;
1597
1603
  const raycaster = new THREE.Raycaster();
1598
1604
  raycaster.params.Line.threshold = 0.1;
1599
1605
  raycaster.params.Points.threshold = 1;
@@ -1607,11 +1613,11 @@ const RayCaster = function (sceneIn, hostSceneIn, callbackFunctionIn, hoverCallb
1607
1613
  let pickableObjects = undefined;
1608
1614
 
1609
1615
  this.enable = () => {
1610
- enable = true;
1616
+ enabled = true;
1611
1617
  }
1612
1618
 
1613
1619
  this.disable = () => {
1614
- enable = false;
1620
+ enabled = false;
1615
1621
  }
1616
1622
 
1617
1623
  this.getIntersectsObject = (zincCamera) => {
@@ -420,8 +420,9 @@ const TextureSlides = function (textureIn) {
420
420
 
421
421
  this.setMask = (maskTextureIn) => {
422
422
  maskTexture = maskTextureIn;
423
+ maskEnabled = maskTexture ? true : false;
423
424
  this.setUniformsValue("mask", maskTexture);
424
- this.setUniformsValue("maskEnabled", maskTexture ? true : false);
425
+ this.setUniformsValue("maskEnabled", maskEnabled);
425
426
  }
426
427
 
427
428
  this.hideEdges = () => {
@@ -84,7 +84,7 @@ const SceneLoader = function (sceneIn) {
84
84
  const promises = [];
85
85
  for (const [key, value] of Object.entries(views.Entries)) {
86
86
  if (referenceURL) {
87
- newURL = createNewURL(value, referenceURL);
87
+ const newURL = createNewURL(value, referenceURL);
88
88
  promises.push(new Promise((resolve, reject) => {
89
89
  // Add parameters if we are sent them
90
90
  fetch(newURL)
@@ -115,26 +115,28 @@ const SceneLoader = function (sceneIn) {
115
115
  */
116
116
  this.loadViewURL = (url, finishCallback) => {
117
117
  this.toBeDownloaded += 1;
118
- const xmlhttp = new XMLHttpRequest();
119
- xmlhttp.onreadystatechange = () => {
120
- if (xmlhttp.readyState == 4) {
121
- if(xmlhttp.status == 200) {
122
- const viewData = JSON.parse(xmlhttp.responseText);
123
- scene.setupMultipleViews("default", { "default" : viewData });
124
- scene.resetView();
125
- viewLoaded = true;
126
- --this.toBeDownloaded;
127
- if (finishCallback != undefined && (typeof finishCallback == 'function'))
128
- finishCallback();
129
- } else {
130
- (this.onError(finishCallback))({responseURL: url});
118
+ const requestURL = resolveURL(url);
119
+ fetch(requestURL)
120
+ .then((response) => {
121
+ if (!response.ok) {
122
+ throw new Error(`HTTP error! status: ${response.status}`);
131
123
  }
132
- }
124
+ return response.json();
125
+ })
126
+ .then((viewData) => {
127
+ scene.setupMultipleViews("default", { "default" : viewData });
128
+ scene.resetView();
129
+ viewLoaded = true;
130
+ --this.toBeDownloaded;
131
+ if (finishCallback !== undefined && typeof finishCallback === 'function') {
132
+ finishCallback();
133
+ }
134
+ })
135
+ .catch((error) => {
136
+ console.error(`Fetch failed for URL: ${requestURL}`, error);
137
+ (this.onError(finishCallback))({ responseURL: requestURL });
138
+ });
133
139
  }
134
- const requestURL = resolveURL(url);
135
- xmlhttp.open("GET", requestURL, true);
136
- xmlhttp.send();
137
- }
138
140
 
139
141
  /**
140
142
  * Load a legacy model(s) format with the provided URLs and parameters. This only loads the geometry
@@ -173,23 +175,35 @@ const SceneLoader = function (sceneIn) {
173
175
  * @deprecated
174
176
  */
175
177
  this.loadFromViewURL = (targetRegion, jsonFilePrefix, finishCallback) => {
176
- const xmlhttp = new XMLHttpRequest();
177
- xmlhttp.onreadystatechange = () => {
178
- if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
179
- const viewData = JSON.parse(xmlhttp.responseText);
180
- scene.loadView(viewData);
181
- const urls = [];
182
- const filename_prefix = jsonFilePrefix + "_";
183
- for (let i = 0; i < viewData.numberOfResources; i++) {
184
- const filename = filename_prefix + (i + 1) + ".json";
185
- urls.push(filename);
186
- }
187
- this.loadModelsURL(targetRegion, urls, viewData.colour, viewData.opacity, viewData.timeEnabled, viewData.morphColour, finishCallback);
188
- }
189
- }
190
178
  const requestURL = resolveURL(jsonFilePrefix + "_view.json");
191
- xmlhttp.open("GET", requestURL, true);
192
- xmlhttp.send();
179
+ fetch(requestURL)
180
+ .then((response) => {
181
+ if (!response.ok) {
182
+ throw new Error(`HTTP error! status: ${response.status}`);
183
+ }
184
+ return response.json();
185
+ })
186
+ .then((viewData) => {
187
+ scene.loadView(viewData);
188
+ const urls = [];
189
+ const filename_prefix = jsonFilePrefix + "_";
190
+ for (let i = 0; i < viewData.numberOfResources; i++) {
191
+ const filename = filename_prefix + (i + 1) + ".json";
192
+ urls.push(filename);
193
+ }
194
+ this.loadModelsURL(
195
+ targetRegion,
196
+ urls,
197
+ viewData.colour,
198
+ viewData.opacity,
199
+ viewData.timeEnabled,
200
+ viewData.morphColour,
201
+ finishCallback
202
+ );
203
+ })
204
+ .catch((error) => {
205
+ console.error(`Failed to load view data from: ${requestURL}`, error);
206
+ });
193
207
  }
194
208
 
195
209
  //Internal loader for a regular zinc geometry.
@@ -549,17 +563,6 @@ const SceneLoader = function (sceneIn) {
549
563
  }
550
564
  };
551
565
 
552
-
553
- //Load a glyphset into this scene.
554
- const onLoadTextureReady = (region, xmlhttp, groupName, finishCallback, options) => {
555
- return () => {
556
- if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
557
- const textureData = JSON.parse(xmlhttp.responseText);
558
- loadTexture(region, xmlhttp.responseURL, textureData, groupName, finishCallback, options);
559
- }
560
- };
561
- };
562
-
563
566
  /**
564
567
  * Load a texture into this scene object.
565
568
  *
@@ -572,11 +575,21 @@ const SceneLoader = function (sceneIn) {
572
575
  if (isInline) {
573
576
  loadTexture(region, undefined, url, groupName, finishCallback, options);
574
577
  } else {
575
- const xmlhttp = new XMLHttpRequest();
576
- xmlhttp.onreadystatechange = onLoadTextureReady(region, xmlhttp,
577
- groupName, finishCallback, options);
578
- xmlhttp.open("GET", resolveURL(url), true);
579
- xmlhttp.send();
578
+ const requestURL = resolveURL(url);
579
+ fetch(requestURL)
580
+ .then((response) => {
581
+ if (!response.ok) {
582
+ throw new Error(`HTTP error! status: ${response.status}`);
583
+ }
584
+ const referenceURL = response.url || (new URL(requestURL)).href;
585
+ return response.json().then((textureData) => ({ textureData, referenceURL }));
586
+ })
587
+ .then(({textureData, referenceURL}) => {
588
+ loadTexture(region, referenceURL, textureData, groupName, finishCallback, options);
589
+ })
590
+ .catch((error) => {
591
+ console.error(`Fetch failed for texture URL: ${requestURL}`, error);
592
+ });
580
593
  }
581
594
  }
582
595
 
@@ -971,29 +984,30 @@ const SceneLoader = function (sceneIn) {
971
984
  * for each glyphset and geometry that has been written in.
972
985
  */
973
986
  this.loadMetadataURL = (targetRegion, url, finishCallback, allCompletedCallback, options) => {
974
- const xmlhttp = new XMLHttpRequest();
975
987
  const requestURL = resolveURL(url);
976
- xmlhttp.onreadystatechange = () => {
977
- if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
988
+ fetch(requestURL)
989
+ .then((response) => {
990
+ if (!response.ok) {
991
+ throw new Error(`HTTP error! status: ${response.status}`);
992
+ }
993
+ const referenceURL = response.url || (new URL(requestURL)).href;
994
+ return response.json().then((metadata) => ({ metadata, referenceURL }));
995
+ })
996
+ .then(({metadata, referenceURL}) => {
978
997
  scene.resetMetadata();
979
998
  scene.resetDuration();
980
999
  viewLoaded = false;
981
- let referenceURL = xmlhttp.responseURL;
982
- if (referenceURL === undefined)
983
- referenceURL = (new URL(requestURL)).href;
984
- const metadata = JSON.parse(xmlhttp.responseText);
985
1000
  if (Array.isArray(metadata)) {
986
1001
  loadVersionOne(targetRegion, metadata, referenceURL, finishCallback, allCompletedCallback, options);
987
1002
  } else if (typeof metadata === "object" && metadata !== null) {
988
- if (metadata.Version == "2.0") {
1003
+ if (metadata.Version === "2.0") {
989
1004
  loadVersionTwo(targetRegion, metadata, referenceURL, finishCallback, allCompletedCallback);
990
1005
  }
991
1006
  }
992
- }
993
- }
994
-
995
- xmlhttp.open("GET", requestURL, true);
996
- xmlhttp.send();
1007
+ })
1008
+ .catch((error) => {
1009
+ console.error(`Fetch failed for URL: ${requestURL}`, error);
1010
+ });
997
1011
  }
998
1012
  }
999
1013
 
package/src/utilities.js CHANGED
@@ -87,23 +87,20 @@ function getBoundingBox(mesh, cachedBox, b1, v1, v2) {
87
87
  //Convenient function
88
88
  function loadExternalFile(url, data, callback, errorCallback) {
89
89
  // Set up an asynchronous request
90
- const request = new XMLHttpRequest();
91
- request.open('GET', resolveURL(url), true);
92
-
93
- // Hook the event that gets called as the request progresses
94
- request.onreadystatechange = () => {
95
- // If the request is "DONE" (completed or failed)
96
- if (request.readyState == 4) {
97
- // If we got HTTP status 200 (OK)
98
- if (request.status == 200) {
99
- callback(request.responseText, data)
100
- } else { // Failed
101
- errorCallback(url);
102
- }
103
- }
104
- };
105
-
106
- request.send(null);
90
+ fetch(resolveURL(url))
91
+ .then((response) => {
92
+ if (!response.ok) {
93
+ throw new Error(`HTTP error! status: ${response.status}`);
94
+ }
95
+ return response.text();
96
+ })
97
+ .then((responseText) => {
98
+ callback(responseText, data);
99
+ })
100
+ .catch((error) => {
101
+ console.error(`Fetch string payload retrieval failed for: ${requestURL}`, error);
102
+ errorCallback(url);
103
+ });
107
104
  }
108
105
 
109
106
  function loadExternalFiles(urls, callback, errorCallback) {