cod-dicomweb-server 1.3.12 → 1.3.13
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/cjs/main.js +108 -68
- package/dist/esm/classes/CodDicomWebServer.d.ts +1 -0
- package/dist/esm/classes/CodDicomWebServer.js +54 -16
- package/dist/esm/dataRetrieval/dataRetrievalManager.d.ts +1 -1
- package/dist/esm/dataRetrieval/dataRetrievalManager.js +1 -0
- package/dist/esm/dataRetrieval/requestManager.d.ts +1 -1
- package/dist/esm/dataRetrieval/scripts/filePartial.d.ts +1 -1
- package/dist/esm/dataRetrieval/scripts/filePartial.js +7 -4
- package/dist/esm/dataRetrieval/scripts/fileStreaming.js +4 -2
- package/dist/esm/dataRetrieval/workerManager.d.ts +1 -1
- package/dist/umd/563.js +2 -2
- package/dist/umd/563.js.map +1 -1
- package/dist/umd/846.js +2 -2
- package/dist/umd/846.js.map +1 -1
- package/dist/umd/main.js +2 -2
- package/dist/umd/main.js.map +1 -1
- package/package.json +1 -1
package/dist/cjs/main.js
CHANGED
|
@@ -1980,6 +1980,7 @@ var DataRetrievalManager = /*#__PURE__*/function () {
|
|
|
1980
1980
|
}]);
|
|
1981
1981
|
}();
|
|
1982
1982
|
var dataRetrievalManager = new DataRetrievalManager();
|
|
1983
|
+
Object.freeze(dataRetrievalManager);
|
|
1983
1984
|
function getDataRetrievalManager() {
|
|
1984
1985
|
return dataRetrievalManager;
|
|
1985
1986
|
}
|
|
@@ -1993,7 +1994,7 @@ function filePartial_asyncToGenerator(n) { return function () { var t = this, e
|
|
|
1993
1994
|
var filePartial = {
|
|
1994
1995
|
partial: function partial(args, callBack) {
|
|
1995
1996
|
return filePartial_asyncToGenerator(/*#__PURE__*/filePartial_regeneratorRuntime().mark(function _callee() {
|
|
1996
|
-
var url, offsets, headers, directoryHandle, storageName, file;
|
|
1997
|
+
var url, offsets, headers, directoryHandle, storageName, file, fileBuffer;
|
|
1997
1998
|
return filePartial_regeneratorRuntime().wrap(function _callee$(_context) {
|
|
1998
1999
|
while (1) switch (_context.prev = _context.next) {
|
|
1999
2000
|
case 0:
|
|
@@ -2003,7 +2004,7 @@ var filePartial = {
|
|
|
2003
2004
|
}
|
|
2004
2005
|
storageName = createPartialFileName(url, offsets);
|
|
2005
2006
|
if (!directoryHandle) {
|
|
2006
|
-
_context.next =
|
|
2007
|
+
_context.next = 11;
|
|
2007
2008
|
break;
|
|
2008
2009
|
}
|
|
2009
2010
|
_context.next = 6;
|
|
@@ -2014,34 +2015,39 @@ var filePartial = {
|
|
|
2014
2015
|
case 6:
|
|
2015
2016
|
file = _context.sent;
|
|
2016
2017
|
if (!file) {
|
|
2017
|
-
_context.next =
|
|
2018
|
+
_context.next = 11;
|
|
2018
2019
|
break;
|
|
2019
2020
|
}
|
|
2021
|
+
fileBuffer = new Uint8Array(file);
|
|
2020
2022
|
callBack({
|
|
2021
2023
|
url: url,
|
|
2022
|
-
fileArraybuffer:
|
|
2024
|
+
fileArraybuffer: fileBuffer,
|
|
2023
2025
|
offsets: offsets
|
|
2024
2026
|
});
|
|
2025
|
-
return _context.abrupt("return");
|
|
2026
|
-
case
|
|
2027
|
-
_context.next =
|
|
2027
|
+
return _context.abrupt("return", fileBuffer);
|
|
2028
|
+
case 11:
|
|
2029
|
+
_context.next = 13;
|
|
2028
2030
|
return fetch(url, {
|
|
2029
2031
|
headers: headers
|
|
2030
2032
|
}).then(function (response) {
|
|
2031
2033
|
return response.arrayBuffer();
|
|
2032
2034
|
}).then(function (data) {
|
|
2035
|
+
var fileBuffer = new Uint8Array(data);
|
|
2033
2036
|
callBack({
|
|
2034
2037
|
url: url,
|
|
2035
|
-
fileArraybuffer:
|
|
2038
|
+
fileArraybuffer: fileBuffer,
|
|
2036
2039
|
offsets: offsets
|
|
2037
2040
|
});
|
|
2038
2041
|
if (directoryHandle) {
|
|
2039
2042
|
writeFile(directoryHandle, storageName, data);
|
|
2040
2043
|
}
|
|
2044
|
+
return fileBuffer;
|
|
2041
2045
|
})["catch"](function (error) {
|
|
2042
2046
|
throw new CustomError('filePartial.ts: Error when fetching file: ' + (error === null || error === void 0 ? void 0 : error.message));
|
|
2043
2047
|
});
|
|
2044
|
-
case
|
|
2048
|
+
case 13:
|
|
2049
|
+
return _context.abrupt("return", _context.sent);
|
|
2050
|
+
case 14:
|
|
2045
2051
|
case "end":
|
|
2046
2052
|
return _context.stop();
|
|
2047
2053
|
}
|
|
@@ -2065,7 +2071,7 @@ function fileStreaming_asyncToGenerator(n) { return function () { var t = this,
|
|
|
2065
2071
|
var fileStreaming = {
|
|
2066
2072
|
stream: function stream(args, callBack) {
|
|
2067
2073
|
return fileStreaming_asyncToGenerator(/*#__PURE__*/fileStreaming_regeneratorRuntime().mark(function _callee() {
|
|
2068
|
-
var url, headers, useSharedArrayBuffer, directoryHandle, controller, sharedArraybuffer, fileArraybuffer, _response$body, fileName, file, _totalLength, response, reader, result, completed, totalLength, firstChunk, position, chunk, streamingError;
|
|
2074
|
+
var url, headers, useSharedArrayBuffer, directoryHandle, controller, sharedArraybuffer, fileArraybuffer, _response$body, fileName, file, _totalLength, fileBuffer, response, reader, result, completed, totalLength, firstChunk, position, chunk, streamingError;
|
|
2069
2075
|
return fileStreaming_regeneratorRuntime().wrap(function _callee$(_context) {
|
|
2070
2076
|
while (1) switch (_context.prev = _context.next) {
|
|
2071
2077
|
case 0:
|
|
@@ -2076,7 +2082,7 @@ var fileStreaming = {
|
|
|
2076
2082
|
_context.prev = 4;
|
|
2077
2083
|
fileName = createStreamingFileName(url);
|
|
2078
2084
|
if (!directoryHandle) {
|
|
2079
|
-
_context.next =
|
|
2085
|
+
_context.next = 15;
|
|
2080
2086
|
break;
|
|
2081
2087
|
}
|
|
2082
2088
|
_context.next = 9;
|
|
@@ -2086,53 +2092,54 @@ var fileStreaming = {
|
|
|
2086
2092
|
case 9:
|
|
2087
2093
|
file = _context.sent;
|
|
2088
2094
|
if (!file) {
|
|
2089
|
-
_context.next =
|
|
2095
|
+
_context.next = 15;
|
|
2090
2096
|
break;
|
|
2091
2097
|
}
|
|
2092
2098
|
_totalLength = file.byteLength;
|
|
2099
|
+
fileBuffer = new Uint8Array(file);
|
|
2093
2100
|
callBack({
|
|
2094
2101
|
url: url,
|
|
2095
2102
|
position: _totalLength,
|
|
2096
|
-
fileArraybuffer:
|
|
2103
|
+
fileArraybuffer: fileBuffer,
|
|
2097
2104
|
totalLength: _totalLength
|
|
2098
2105
|
});
|
|
2099
|
-
return _context.abrupt("return");
|
|
2100
|
-
case
|
|
2101
|
-
_context.next =
|
|
2106
|
+
return _context.abrupt("return", fileBuffer);
|
|
2107
|
+
case 15:
|
|
2108
|
+
_context.next = 17;
|
|
2102
2109
|
return fetch(url, {
|
|
2103
2110
|
headers: fileStreaming_objectSpread({}, headers),
|
|
2104
2111
|
signal: controller.signal
|
|
2105
2112
|
});
|
|
2106
|
-
case
|
|
2113
|
+
case 17:
|
|
2107
2114
|
response = _context.sent;
|
|
2108
2115
|
if (response.ok) {
|
|
2109
|
-
_context.next =
|
|
2116
|
+
_context.next = 20;
|
|
2110
2117
|
break;
|
|
2111
2118
|
}
|
|
2112
2119
|
throw new CustomError("HTTP error! status: ".concat(response.status));
|
|
2113
|
-
case
|
|
2120
|
+
case 20:
|
|
2114
2121
|
reader = (_response$body = response.body) === null || _response$body === void 0 ? void 0 : _response$body.getReader();
|
|
2115
2122
|
if (reader) {
|
|
2116
|
-
_context.next =
|
|
2123
|
+
_context.next = 23;
|
|
2117
2124
|
break;
|
|
2118
2125
|
}
|
|
2119
2126
|
throw new CustomError('Failed to get reader from response body');
|
|
2120
|
-
case
|
|
2127
|
+
case 23:
|
|
2121
2128
|
completed = false;
|
|
2122
2129
|
totalLength = parseInt(response.headers.get('Content-Length') || '0', 10);
|
|
2123
|
-
_context.next =
|
|
2130
|
+
_context.next = 27;
|
|
2124
2131
|
return reader.read();
|
|
2125
|
-
case
|
|
2132
|
+
case 27:
|
|
2126
2133
|
firstChunk = _context.sent;
|
|
2127
2134
|
completed = firstChunk.done;
|
|
2128
2135
|
if (firstChunk.value) {
|
|
2129
|
-
_context.next =
|
|
2136
|
+
_context.next = 31;
|
|
2130
2137
|
break;
|
|
2131
2138
|
}
|
|
2132
2139
|
throw new CustomError('The fetched chunks does not have value');
|
|
2133
|
-
case
|
|
2140
|
+
case 31:
|
|
2134
2141
|
if (completed) {
|
|
2135
|
-
_context.next =
|
|
2142
|
+
_context.next = 50;
|
|
2136
2143
|
break;
|
|
2137
2144
|
}
|
|
2138
2145
|
position = firstChunk.value.length;
|
|
@@ -2149,22 +2156,22 @@ var fileStreaming = {
|
|
|
2149
2156
|
fileArraybuffer: fileArraybuffer,
|
|
2150
2157
|
totalLength: totalLength
|
|
2151
2158
|
});
|
|
2152
|
-
case
|
|
2159
|
+
case 36:
|
|
2153
2160
|
if (completed) {
|
|
2154
|
-
_context.next =
|
|
2161
|
+
_context.next = 49;
|
|
2155
2162
|
break;
|
|
2156
2163
|
}
|
|
2157
|
-
_context.next =
|
|
2164
|
+
_context.next = 39;
|
|
2158
2165
|
return reader.read();
|
|
2159
|
-
case
|
|
2166
|
+
case 39:
|
|
2160
2167
|
result = _context.sent;
|
|
2161
2168
|
if (!result.done) {
|
|
2162
|
-
_context.next =
|
|
2169
|
+
_context.next = 43;
|
|
2163
2170
|
break;
|
|
2164
2171
|
}
|
|
2165
2172
|
completed = true;
|
|
2166
|
-
return _context.abrupt("continue",
|
|
2167
|
-
case
|
|
2173
|
+
return _context.abrupt("continue", 36);
|
|
2174
|
+
case 43:
|
|
2168
2175
|
chunk = result.value;
|
|
2169
2176
|
fileArraybuffer.set(chunk, position);
|
|
2170
2177
|
position += chunk.length;
|
|
@@ -2175,32 +2182,31 @@ var fileStreaming = {
|
|
|
2175
2182
|
chunk: !useSharedArrayBuffer ? chunk : undefined,
|
|
2176
2183
|
totalLength: totalLength
|
|
2177
2184
|
});
|
|
2178
|
-
_context.next =
|
|
2185
|
+
_context.next = 36;
|
|
2179
2186
|
break;
|
|
2180
|
-
case
|
|
2187
|
+
case 49:
|
|
2181
2188
|
if (directoryHandle) {
|
|
2182
2189
|
writeFile(directoryHandle, fileName, fileArraybuffer.slice().buffer);
|
|
2183
2190
|
}
|
|
2184
|
-
case
|
|
2185
|
-
_context.
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
_context.prev = 51;
|
|
2191
|
+
case 50:
|
|
2192
|
+
return _context.abrupt("return", fileArraybuffer);
|
|
2193
|
+
case 53:
|
|
2194
|
+
_context.prev = 53;
|
|
2189
2195
|
_context.t0 = _context["catch"](4);
|
|
2190
2196
|
streamingError = new CustomError('fileStreaming.ts: ' + _context.t0.message || 0);
|
|
2191
2197
|
console.error(streamingError.message, _context.t0);
|
|
2192
2198
|
throw streamingError;
|
|
2193
|
-
case
|
|
2194
|
-
_context.prev =
|
|
2199
|
+
case 58:
|
|
2200
|
+
_context.prev = 58;
|
|
2195
2201
|
sharedArraybuffer = null;
|
|
2196
2202
|
fileArraybuffer = null;
|
|
2197
2203
|
controller.abort();
|
|
2198
|
-
return _context.finish(
|
|
2199
|
-
case
|
|
2204
|
+
return _context.finish(58);
|
|
2205
|
+
case 63:
|
|
2200
2206
|
case "end":
|
|
2201
2207
|
return _context.stop();
|
|
2202
2208
|
}
|
|
2203
|
-
}, _callee, null, [[4,
|
|
2209
|
+
}, _callee, null, [[4, 53, 58, 63]]);
|
|
2204
2210
|
}))();
|
|
2205
2211
|
}
|
|
2206
2212
|
};
|
|
@@ -2268,6 +2274,7 @@ var CodDicomWebServer = /*#__PURE__*/function () {
|
|
|
2268
2274
|
var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
2269
2275
|
CodDicomWebServer_classCallCheck(this, CodDicomWebServer);
|
|
2270
2276
|
CodDicomWebServer_defineProperty(this, "filePromises", {});
|
|
2277
|
+
CodDicomWebServer_defineProperty(this, "files", {});
|
|
2271
2278
|
CodDicomWebServer_defineProperty(this, "options", {
|
|
2272
2279
|
maxCacheSize: 4 * 1024 * 1024 * 1024,
|
|
2273
2280
|
// 4GB
|
|
@@ -2555,10 +2562,14 @@ var CodDicomWebServer = /*#__PURE__*/function () {
|
|
|
2555
2562
|
position = _evt$data.position,
|
|
2556
2563
|
fileArraybuffer = _evt$data.fileArraybuffer;
|
|
2557
2564
|
if (url === fileUrl && fileArraybuffer) {
|
|
2558
|
-
_this3.
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2565
|
+
if (_this3.options.enableLocalCache) {
|
|
2566
|
+
_this3.files[fileUrl] = fileArraybuffer;
|
|
2567
|
+
} else {
|
|
2568
|
+
_this3.fileManager.set(url, {
|
|
2569
|
+
data: fileArraybuffer,
|
|
2570
|
+
position: position
|
|
2571
|
+
});
|
|
2572
|
+
}
|
|
2562
2573
|
dataRetrievalManager.removeEventListener(FILE_STREAMING_WORKER_NAME, 'message', _handleFirstChunk);
|
|
2563
2574
|
}
|
|
2564
2575
|
};
|
|
@@ -2574,7 +2585,6 @@ var CodDicomWebServer = /*#__PURE__*/function () {
|
|
|
2574
2585
|
rejectFile(error);
|
|
2575
2586
|
}).then(function () {
|
|
2576
2587
|
dataRetrievalManager.removeEventListener(FILE_STREAMING_WORKER_NAME, 'message', _handleFirstChunk);
|
|
2577
|
-
delete _this3.filePromises[fileUrl];
|
|
2578
2588
|
});
|
|
2579
2589
|
} else if (fetchType === FetchTypeEnum.BYTES_OPTIMIZED && offsets) {
|
|
2580
2590
|
var startByte = offsets.startByte,
|
|
@@ -2590,10 +2600,14 @@ var CodDicomWebServer = /*#__PURE__*/function () {
|
|
|
2590
2600
|
fileArraybuffer = _evt$data2.fileArraybuffer,
|
|
2591
2601
|
offsets = _evt$data2.offsets;
|
|
2592
2602
|
if (url === bytesRemovedUrl && offsets.startByte === startByte && offsets.endByte === endByte) {
|
|
2593
|
-
_this3.
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2603
|
+
if (_this3.options.enableLocalCache) {
|
|
2604
|
+
_this3.files[fileUrl] = fileArraybuffer;
|
|
2605
|
+
} else {
|
|
2606
|
+
_this3.fileManager.set(fileUrl, {
|
|
2607
|
+
data: fileArraybuffer,
|
|
2608
|
+
position: fileArraybuffer.length
|
|
2609
|
+
});
|
|
2610
|
+
}
|
|
2597
2611
|
dataRetrievalManager.removeEventListener(FILE_PARTIAL_WORKER_NAME, 'message', _handleSlice);
|
|
2598
2612
|
resolveFile();
|
|
2599
2613
|
}
|
|
@@ -2611,18 +2625,22 @@ var CodDicomWebServer = /*#__PURE__*/function () {
|
|
|
2611
2625
|
rejectFile(error);
|
|
2612
2626
|
}).then(function () {
|
|
2613
2627
|
dataRetrievalManager.removeEventListener(FILE_PARTIAL_WORKER_NAME, 'message', _handleSlice);
|
|
2614
|
-
delete _this3.filePromises[fileUrl];
|
|
2615
2628
|
});
|
|
2616
2629
|
} else {
|
|
2617
2630
|
rejectFile(new CustomError('CodDicomWebServer.ts: Offsets is needed in bytes optimized fetching'));
|
|
2618
2631
|
}
|
|
2619
2632
|
});
|
|
2620
|
-
this.filePromises[fileUrl] =
|
|
2633
|
+
this.filePromises[fileUrl] = {
|
|
2634
|
+
promise: tarPromise,
|
|
2635
|
+
requestCount: 1
|
|
2636
|
+
};
|
|
2621
2637
|
} else {
|
|
2622
|
-
tarPromise = this.filePromises[fileUrl];
|
|
2638
|
+
tarPromise = this.filePromises[fileUrl].promise;
|
|
2639
|
+
this.filePromises[fileUrl].requestCount++;
|
|
2623
2640
|
}
|
|
2624
2641
|
return _context2.abrupt("return", new Promise(function (resolveRequest, rejectRequest) {
|
|
2625
|
-
var requestResolved = false
|
|
2642
|
+
var requestResolved = false,
|
|
2643
|
+
fileFetchingCompleted = false;
|
|
2626
2644
|
var handleChunkAppend = function handleChunkAppend(evt) {
|
|
2627
2645
|
if (evt instanceof CustomErrorEvent) {
|
|
2628
2646
|
rejectRequest(evt.message);
|
|
@@ -2636,7 +2654,11 @@ var CodDicomWebServer = /*#__PURE__*/function () {
|
|
|
2636
2654
|
isAppending = _evt$data3.isAppending;
|
|
2637
2655
|
if (isAppending) {
|
|
2638
2656
|
if (chunk) {
|
|
2639
|
-
_this3.
|
|
2657
|
+
if (_this3.options.enableLocalCache) {
|
|
2658
|
+
_this3.files[url].set(chunk, position - chunk.length);
|
|
2659
|
+
} else {
|
|
2660
|
+
_this3.fileManager.append(url, chunk, position);
|
|
2661
|
+
}
|
|
2640
2662
|
} else {
|
|
2641
2663
|
_this3.fileManager.setPosition(url, position);
|
|
2642
2664
|
}
|
|
@@ -2648,33 +2670,51 @@ var CodDicomWebServer = /*#__PURE__*/function () {
|
|
|
2648
2670
|
_this3.fileManager.decacheNecessaryBytes(url, totalLength);
|
|
2649
2671
|
}
|
|
2650
2672
|
}
|
|
2651
|
-
if (!requestResolved && url === fileUrl &&
|
|
2673
|
+
if (!requestResolved && url === fileUrl && position > offsets.endByte) {
|
|
2652
2674
|
try {
|
|
2653
|
-
var file = _this3.fileManager.get(url, offsets);
|
|
2654
|
-
requestResolved = true;
|
|
2675
|
+
var file = _this3.options.enableLocalCache ? _this3.files[url].slice(offsets.startByte, offsets.endByte) : _this3.fileManager.get(url, offsets);
|
|
2655
2676
|
resolveRequest(file === null || file === void 0 ? void 0 : file.buffer);
|
|
2656
2677
|
} catch (error) {
|
|
2657
2678
|
rejectRequest(error);
|
|
2679
|
+
} finally {
|
|
2680
|
+
completeRequest(url);
|
|
2658
2681
|
}
|
|
2659
2682
|
}
|
|
2660
2683
|
};
|
|
2684
|
+
var completeRequest = function completeRequest(url) {
|
|
2685
|
+
var _this3$filePromises$u;
|
|
2686
|
+
requestResolved = true;
|
|
2687
|
+
_this3.filePromises[url].requestCount--;
|
|
2688
|
+
dataRetrievalManager.removeEventListener(FILE_STREAMING_WORKER_NAME, 'message', handleChunkAppend);
|
|
2689
|
+
if (fileFetchingCompleted && _this3.filePromises[url] && !((_this3$filePromises$u = _this3.filePromises[url]) !== null && _this3$filePromises$u !== void 0 && _this3$filePromises$u.requestCount)) {
|
|
2690
|
+
delete _this3.filePromises[url];
|
|
2691
|
+
delete _this3.files[url];
|
|
2692
|
+
}
|
|
2693
|
+
};
|
|
2661
2694
|
if (offsets && !isBytesOptimized) {
|
|
2662
2695
|
dataRetrievalManager.addEventListener(FILE_STREAMING_WORKER_NAME, 'message', handleChunkAppend);
|
|
2663
2696
|
}
|
|
2664
2697
|
tarPromise.then(function () {
|
|
2698
|
+
fileFetchingCompleted = true;
|
|
2665
2699
|
if (!requestResolved) {
|
|
2666
|
-
if (_this3.fileManager.getPosition(fileUrl)) {
|
|
2667
|
-
var
|
|
2668
|
-
|
|
2669
|
-
|
|
2700
|
+
if (_this3.fileManager.getPosition(fileUrl) || _this3.files[fileUrl]) {
|
|
2701
|
+
var _file;
|
|
2702
|
+
var file;
|
|
2703
|
+
if (_this3.options.enableLocalCache) {
|
|
2704
|
+
file = isBytesOptimized || !offsets ? _this3.files[fileUrl] : _this3.files[fileUrl].slice(offsets.startByte, offsets.endByte);
|
|
2705
|
+
} else {
|
|
2706
|
+
file = _this3.fileManager.get(fileUrl, isBytesOptimized ? undefined : offsets);
|
|
2707
|
+
}
|
|
2708
|
+
resolveRequest((_file = file) === null || _file === void 0 ? void 0 : _file.buffer);
|
|
2670
2709
|
} else {
|
|
2671
2710
|
rejectRequest(new CustomError("File - ".concat(fileUrl, " not found")));
|
|
2672
2711
|
}
|
|
2673
2712
|
}
|
|
2674
2713
|
})["catch"](function (error) {
|
|
2714
|
+
fileFetchingCompleted = true;
|
|
2675
2715
|
rejectRequest(error);
|
|
2676
|
-
})
|
|
2677
|
-
|
|
2716
|
+
})["finally"](function () {
|
|
2717
|
+
completeRequest(fileUrl);
|
|
2678
2718
|
});
|
|
2679
2719
|
}));
|
|
2680
2720
|
case 15:
|
|
@@ -2,6 +2,7 @@ import { Enums } from '../constants';
|
|
|
2
2
|
import type { CodDicomWebServerOptions, CODRequestOptions, FileRequestOptions, InstanceMetadata, JsonMetadata, SeriesMetadata } from '../types';
|
|
3
3
|
declare class CodDicomWebServer {
|
|
4
4
|
private filePromises;
|
|
5
|
+
private files;
|
|
5
6
|
private options;
|
|
6
7
|
private fileManager;
|
|
7
8
|
private metadataManager;
|
|
@@ -10,6 +10,7 @@ import { CustomErrorEvent } from './customClasses';
|
|
|
10
10
|
import { download, getDirectoryHandle } from '../fileAccessSystemUtils';
|
|
11
11
|
class CodDicomWebServer {
|
|
12
12
|
filePromises = {};
|
|
13
|
+
files = {};
|
|
13
14
|
options = {
|
|
14
15
|
maxCacheSize: 4 * 1024 * 1024 * 1024,
|
|
15
16
|
domain: constants.url.DOMAIN,
|
|
@@ -177,7 +178,12 @@ class CodDicomWebServer {
|
|
|
177
178
|
}
|
|
178
179
|
const { url, position, fileArraybuffer } = evt.data;
|
|
179
180
|
if (url === fileUrl && fileArraybuffer) {
|
|
180
|
-
this.
|
|
181
|
+
if (this.options.enableLocalCache) {
|
|
182
|
+
this.files[fileUrl] = fileArraybuffer;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
this.fileManager.set(url, { data: fileArraybuffer, position });
|
|
186
|
+
}
|
|
181
187
|
dataRetrievalManager.removeEventListener(FILE_STREAMING_WORKER_NAME, 'message', handleFirstChunk);
|
|
182
188
|
}
|
|
183
189
|
};
|
|
@@ -197,7 +203,6 @@ class CodDicomWebServer {
|
|
|
197
203
|
})
|
|
198
204
|
.then(() => {
|
|
199
205
|
dataRetrievalManager.removeEventListener(FILE_STREAMING_WORKER_NAME, 'message', handleFirstChunk);
|
|
200
|
-
delete this.filePromises[fileUrl];
|
|
201
206
|
});
|
|
202
207
|
}
|
|
203
208
|
else if (fetchType === FetchTypeEnum.BYTES_OPTIMIZED && offsets) {
|
|
@@ -210,7 +215,12 @@ class CodDicomWebServer {
|
|
|
210
215
|
}
|
|
211
216
|
const { url, fileArraybuffer, offsets } = evt.data;
|
|
212
217
|
if (url === bytesRemovedUrl && offsets.startByte === startByte && offsets.endByte === endByte) {
|
|
213
|
-
this.
|
|
218
|
+
if (this.options.enableLocalCache) {
|
|
219
|
+
this.files[fileUrl] = fileArraybuffer;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
this.fileManager.set(fileUrl, { data: fileArraybuffer, position: fileArraybuffer.length });
|
|
223
|
+
}
|
|
214
224
|
dataRetrievalManager.removeEventListener(FILE_PARTIAL_WORKER_NAME, 'message', handleSlice);
|
|
215
225
|
resolveFile();
|
|
216
226
|
}
|
|
@@ -228,20 +238,20 @@ class CodDicomWebServer {
|
|
|
228
238
|
})
|
|
229
239
|
.then(() => {
|
|
230
240
|
dataRetrievalManager.removeEventListener(FILE_PARTIAL_WORKER_NAME, 'message', handleSlice);
|
|
231
|
-
delete this.filePromises[fileUrl];
|
|
232
241
|
});
|
|
233
242
|
}
|
|
234
243
|
else {
|
|
235
244
|
rejectFile(new CustomError('CodDicomWebServer.ts: Offsets is needed in bytes optimized fetching'));
|
|
236
245
|
}
|
|
237
246
|
});
|
|
238
|
-
this.filePromises[fileUrl] = tarPromise;
|
|
247
|
+
this.filePromises[fileUrl] = { promise: tarPromise, requestCount: 1 };
|
|
239
248
|
}
|
|
240
249
|
else {
|
|
241
|
-
tarPromise = this.filePromises[fileUrl];
|
|
250
|
+
tarPromise = this.filePromises[fileUrl].promise;
|
|
251
|
+
this.filePromises[fileUrl].requestCount++;
|
|
242
252
|
}
|
|
243
253
|
return new Promise((resolveRequest, rejectRequest) => {
|
|
244
|
-
let requestResolved = false;
|
|
254
|
+
let requestResolved = false, fileFetchingCompleted = false;
|
|
245
255
|
const handleChunkAppend = (evt) => {
|
|
246
256
|
if (evt instanceof CustomErrorEvent) {
|
|
247
257
|
rejectRequest(evt.message);
|
|
@@ -250,7 +260,12 @@ class CodDicomWebServer {
|
|
|
250
260
|
const { url, position, chunk, totalLength, isAppending } = evt.data;
|
|
251
261
|
if (isAppending) {
|
|
252
262
|
if (chunk) {
|
|
253
|
-
this.
|
|
263
|
+
if (this.options.enableLocalCache) {
|
|
264
|
+
this.files[url].set(chunk, position - chunk.length);
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
this.fileManager.append(url, chunk, position);
|
|
268
|
+
}
|
|
254
269
|
}
|
|
255
270
|
else {
|
|
256
271
|
this.fileManager.setPosition(url, position);
|
|
@@ -264,15 +279,28 @@ class CodDicomWebServer {
|
|
|
264
279
|
this.fileManager.decacheNecessaryBytes(url, totalLength);
|
|
265
280
|
}
|
|
266
281
|
}
|
|
267
|
-
if (!requestResolved && url === fileUrl &&
|
|
282
|
+
if (!requestResolved && url === fileUrl && position > offsets.endByte) {
|
|
268
283
|
try {
|
|
269
|
-
const file = this.
|
|
270
|
-
|
|
284
|
+
const file = this.options.enableLocalCache
|
|
285
|
+
? this.files[url].slice(offsets.startByte, offsets.endByte)
|
|
286
|
+
: this.fileManager.get(url, offsets);
|
|
271
287
|
resolveRequest(file?.buffer);
|
|
272
288
|
}
|
|
273
289
|
catch (error) {
|
|
274
290
|
rejectRequest(error);
|
|
275
291
|
}
|
|
292
|
+
finally {
|
|
293
|
+
completeRequest(url);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
const completeRequest = (url) => {
|
|
298
|
+
requestResolved = true;
|
|
299
|
+
this.filePromises[url].requestCount--;
|
|
300
|
+
dataRetrievalManager.removeEventListener(FILE_STREAMING_WORKER_NAME, 'message', handleChunkAppend);
|
|
301
|
+
if (fileFetchingCompleted && this.filePromises[url] && !this.filePromises[url]?.requestCount) {
|
|
302
|
+
delete this.filePromises[url];
|
|
303
|
+
delete this.files[url];
|
|
276
304
|
}
|
|
277
305
|
};
|
|
278
306
|
if (offsets && !isBytesOptimized) {
|
|
@@ -280,10 +308,19 @@ class CodDicomWebServer {
|
|
|
280
308
|
}
|
|
281
309
|
tarPromise
|
|
282
310
|
.then(() => {
|
|
311
|
+
fileFetchingCompleted = true;
|
|
283
312
|
if (!requestResolved) {
|
|
284
|
-
if (this.fileManager.getPosition(fileUrl)) {
|
|
285
|
-
|
|
286
|
-
|
|
313
|
+
if (this.fileManager.getPosition(fileUrl) || this.files[fileUrl]) {
|
|
314
|
+
let file;
|
|
315
|
+
if (this.options.enableLocalCache) {
|
|
316
|
+
file =
|
|
317
|
+
isBytesOptimized || !offsets
|
|
318
|
+
? this.files[fileUrl]
|
|
319
|
+
: this.files[fileUrl].slice(offsets.startByte, offsets.endByte);
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
file = this.fileManager.get(fileUrl, isBytesOptimized ? undefined : offsets);
|
|
323
|
+
}
|
|
287
324
|
resolveRequest(file?.buffer);
|
|
288
325
|
}
|
|
289
326
|
else {
|
|
@@ -292,10 +329,11 @@ class CodDicomWebServer {
|
|
|
292
329
|
}
|
|
293
330
|
})
|
|
294
331
|
.catch((error) => {
|
|
332
|
+
fileFetchingCompleted = true;
|
|
295
333
|
rejectRequest(error);
|
|
296
334
|
})
|
|
297
|
-
.
|
|
298
|
-
|
|
335
|
+
.finally(() => {
|
|
336
|
+
completeRequest(fileUrl);
|
|
299
337
|
});
|
|
300
338
|
});
|
|
301
339
|
}
|
|
@@ -8,7 +8,7 @@ declare class DataRetrievalManager {
|
|
|
8
8
|
getDataRetrieverMode(): Enums.DataRetrieveMode;
|
|
9
9
|
setDataRetrieverMode(mode: Enums.DataRetrieveMode): void;
|
|
10
10
|
register(name: string, arg: (() => Worker) | ScriptObject): void;
|
|
11
|
-
executeTask(loaderName: string, taskName: string, options: Record<string, unknown> | unknown): Promise<
|
|
11
|
+
executeTask(loaderName: string, taskName: string, options: Record<string, unknown> | unknown): Promise<any>;
|
|
12
12
|
addEventListener(workerName: string, eventType: keyof WorkerEventMap, listener: (evt: CustomMessageEvent | CustomErrorEvent) => unknown): void;
|
|
13
13
|
removeEventListener(workerName: string, eventType: keyof WorkerEventMap, listener: (evt: CustomMessageEvent | CustomErrorEvent) => unknown): void;
|
|
14
14
|
reset(): void;
|
|
@@ -4,7 +4,7 @@ declare class RequestManager {
|
|
|
4
4
|
private loaderRegistry;
|
|
5
5
|
register(loaderName: string, loaderObject: ScriptObject): void;
|
|
6
6
|
private listenerCallback;
|
|
7
|
-
executeTask(loaderName: string, taskName: string, options: Record<string, unknown> | unknown): Promise<
|
|
7
|
+
executeTask(loaderName: string, taskName: string, options: Record<string, unknown> | unknown): Promise<any>;
|
|
8
8
|
addEventListener(workerName: string, eventType: keyof WorkerEventMap, listener: (evt: CustomMessageEvent | CustomErrorEvent) => unknown): void;
|
|
9
9
|
removeEventListener(workerName: string, eventType: keyof WorkerEventMap, listener: (evt: CustomMessageEvent | CustomErrorEvent) => unknown): void;
|
|
10
10
|
reset(): void;
|
|
@@ -10,17 +10,20 @@ const filePartial = {
|
|
|
10
10
|
if (directoryHandle) {
|
|
11
11
|
const file = (await readFile(directoryHandle, storageName, { offsets, isJson: false }));
|
|
12
12
|
if (file) {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const fileBuffer = new Uint8Array(file);
|
|
14
|
+
callBack({ url, fileArraybuffer: fileBuffer, offsets });
|
|
15
|
+
return fileBuffer;
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
|
-
await fetch(url, { headers })
|
|
18
|
+
return await fetch(url, { headers })
|
|
18
19
|
.then((response) => response.arrayBuffer())
|
|
19
20
|
.then((data) => {
|
|
20
|
-
|
|
21
|
+
const fileBuffer = new Uint8Array(data);
|
|
22
|
+
callBack({ url, fileArraybuffer: fileBuffer, offsets });
|
|
21
23
|
if (directoryHandle) {
|
|
22
24
|
writeFile(directoryHandle, storageName, data);
|
|
23
25
|
}
|
|
26
|
+
return fileBuffer;
|
|
24
27
|
})
|
|
25
28
|
.catch((error) => {
|
|
26
29
|
throw new CustomError('filePartial.ts: Error when fetching file: ' + error?.message);
|
|
@@ -12,8 +12,9 @@ const fileStreaming = {
|
|
|
12
12
|
const file = (await readFile(directoryHandle, fileName, { isJson: false }));
|
|
13
13
|
if (file) {
|
|
14
14
|
const totalLength = file.byteLength;
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const fileBuffer = new Uint8Array(file);
|
|
16
|
+
callBack({ url, position: totalLength, fileArraybuffer: fileBuffer, totalLength });
|
|
17
|
+
return fileBuffer;
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
const response = await fetch(url, {
|
|
@@ -67,6 +68,7 @@ const fileStreaming = {
|
|
|
67
68
|
writeFile(directoryHandle, fileName, fileArraybuffer.slice().buffer);
|
|
68
69
|
}
|
|
69
70
|
}
|
|
71
|
+
return fileArraybuffer;
|
|
70
72
|
}
|
|
71
73
|
catch (error) {
|
|
72
74
|
const streamingError = new CustomError('fileStreaming.ts: ' + error.message || 'An error occured when streaming');
|
|
@@ -2,7 +2,7 @@ import { CustomErrorEvent, CustomMessageEvent } from '../classes/customClasses';
|
|
|
2
2
|
declare class WebWorkerManager {
|
|
3
3
|
private workerRegistry;
|
|
4
4
|
register(name: string, workerFn: () => Worker): void;
|
|
5
|
-
executeTask(workerName: string, taskName: string, options: Record<string, unknown> | unknown): Promise<
|
|
5
|
+
executeTask(workerName: string, taskName: string, options: Record<string, unknown> | unknown): Promise<any>;
|
|
6
6
|
addEventListener(workerName: string, eventType: keyof WorkerEventMap, listener: (evt: CustomMessageEvent | CustomErrorEvent) => unknown): void;
|
|
7
7
|
removeEventListener(workerName: string, eventType: keyof WorkerEventMap, listener: (evt: CustomMessageEvent | CustomErrorEvent) => unknown): void;
|
|
8
8
|
reset(): void;
|