@@ -19,7 +19,8 @@ import { CustomErrorEvent } from './customClasses';
1919import { download , getDirectoryHandle } from '../fileAccessSystemUtils' ;
2020
2121class CodDicomWebServer {
22- private filePromises : Record < string , Promise < void > > = { } ;
22+ private filePromises : Record < string , { promise : Promise < void > ; requestCount : number } > = { } ;
23+ private files : Record < string , Uint8Array > = { } ;
2324 private options : CodDicomWebServerOptions = {
2425 maxCacheSize : 4 * 1024 * 1024 * 1024 , // 4GB
2526 domain : constants . url . DOMAIN ,
@@ -231,7 +232,11 @@ class CodDicomWebServer {
231232 const { url, position, fileArraybuffer } = evt . data ;
232233
233234 if ( url === fileUrl && fileArraybuffer ) {
234- this . fileManager . set ( url , { data : fileArraybuffer , position } ) ;
235+ if ( this . options . enableLocalCache ) {
236+ this . files [ fileUrl ] = fileArraybuffer ;
237+ } else {
238+ this . fileManager . set ( url , { data : fileArraybuffer , position } ) ;
239+ }
235240
236241 dataRetrievalManager . removeEventListener ( FILE_STREAMING_WORKER_NAME , 'message' , handleFirstChunk ) ;
237242 }
@@ -253,7 +258,6 @@ class CodDicomWebServer {
253258 } )
254259 . then ( ( ) => {
255260 dataRetrievalManager . removeEventListener ( FILE_STREAMING_WORKER_NAME , 'message' , handleFirstChunk ) ;
256- delete this . filePromises [ fileUrl ] ;
257261 } ) ;
258262 } else if ( fetchType === FetchTypeEnum . BYTES_OPTIMIZED && offsets ) {
259263 const { startByte, endByte } = offsets ;
@@ -268,7 +272,11 @@ class CodDicomWebServer {
268272 const { url, fileArraybuffer, offsets } = evt . data ;
269273
270274 if ( url === bytesRemovedUrl && offsets . startByte === startByte && offsets . endByte === endByte ) {
271- this . fileManager . set ( fileUrl , { data : fileArraybuffer , position : fileArraybuffer . length } ) ;
275+ if ( this . options . enableLocalCache ) {
276+ this . files [ fileUrl ] = fileArraybuffer ;
277+ } else {
278+ this . fileManager . set ( fileUrl , { data : fileArraybuffer , position : fileArraybuffer . length } ) ;
279+ }
272280
273281 dataRetrievalManager . removeEventListener ( FILE_PARTIAL_WORKER_NAME , 'message' , handleSlice ) ;
274282 resolveFile ( ) ;
@@ -289,20 +297,21 @@ class CodDicomWebServer {
289297 } )
290298 . then ( ( ) => {
291299 dataRetrievalManager . removeEventListener ( FILE_PARTIAL_WORKER_NAME , 'message' , handleSlice ) ;
292- delete this . filePromises [ fileUrl ] ;
293300 } ) ;
294301 } else {
295302 rejectFile ( new CustomError ( 'CodDicomWebServer.ts: Offsets is needed in bytes optimized fetching' ) ) ;
296303 }
297304 } ) ;
298305
299- this . filePromises [ fileUrl ] = tarPromise ;
306+ this . filePromises [ fileUrl ] = { promise : tarPromise , requestCount : 1 } ;
300307 } else {
301- tarPromise = this . filePromises [ fileUrl ] ;
308+ tarPromise = this . filePromises [ fileUrl ] . promise ;
309+ this . filePromises [ fileUrl ] . requestCount ++ ;
302310 }
303311
304312 return new Promise < ArrayBufferLike | undefined > ( ( resolveRequest , rejectRequest ) => {
305- let requestResolved = false ;
313+ let requestResolved = false ,
314+ fileFetchingCompleted = false ;
306315
307316 const handleChunkAppend = ( evt : CustomMessageEvent | CustomErrorEvent ) : void => {
308317 if ( evt instanceof CustomErrorEvent ) {
@@ -314,7 +323,11 @@ class CodDicomWebServer {
314323
315324 if ( isAppending ) {
316325 if ( chunk ) {
317- this . fileManager . append ( url , chunk , position ) ;
326+ if ( this . options . enableLocalCache ) {
327+ this . files [ url ] . set ( chunk , position - chunk . length ) ;
328+ } else {
329+ this . fileManager . append ( url , chunk , position ) ;
330+ }
318331 } else {
319332 this . fileManager . setPosition ( url , position ) ;
320333 }
@@ -327,38 +340,64 @@ class CodDicomWebServer {
327340 }
328341 }
329342
330- if ( ! requestResolved && url === fileUrl && offsets && position > offsets . endByte ) {
343+ if ( ! requestResolved && url === fileUrl && position > offsets . endByte ) {
331344 try {
332- const file = this . fileManager . get ( url , offsets ) ;
333- requestResolved = true ;
345+ const file = this . options . enableLocalCache
346+ ? this . files [ url ] . slice ( offsets . startByte , offsets . endByte )
347+ : this . fileManager . get ( url , offsets ) ;
348+
334349 resolveRequest ( file ?. buffer ) ;
335350 } catch ( error ) {
336351 rejectRequest ( error ) ;
352+ } finally {
353+ completeRequest ( url ) ;
337354 }
338355 }
339356 } ;
340357
358+ const completeRequest = ( url : string ) => {
359+ requestResolved = true ;
360+ this . filePromises [ url ] . requestCount -- ;
361+ dataRetrievalManager . removeEventListener ( FILE_STREAMING_WORKER_NAME , 'message' , handleChunkAppend ) ;
362+
363+ if ( fileFetchingCompleted && this . filePromises [ url ] && ! this . filePromises [ url ] ?. requestCount ) {
364+ delete this . filePromises [ url ] ;
365+ delete this . files [ url ] ;
366+ }
367+ } ;
368+
341369 if ( offsets && ! isBytesOptimized ) {
342370 dataRetrievalManager . addEventListener ( FILE_STREAMING_WORKER_NAME , 'message' , handleChunkAppend ) ;
343371 }
344372
345373 tarPromise
346374 . then ( ( ) => {
375+ fileFetchingCompleted = true ;
376+
347377 if ( ! requestResolved ) {
348- if ( this . fileManager . getPosition ( fileUrl ) ) {
349- const file = this . fileManager . get ( fileUrl , isBytesOptimized ? undefined : offsets ) ;
350- requestResolved = true ;
378+ if ( this . fileManager . getPosition ( fileUrl ) || this . files [ fileUrl ] ) {
379+ let file : Uint8Array ;
380+ if ( this . options . enableLocalCache ) {
381+ file =
382+ isBytesOptimized || ! offsets
383+ ? this . files [ fileUrl ]
384+ : this . files [ fileUrl ] . slice ( offsets . startByte , offsets . endByte ) ;
385+ } else {
386+ file = this . fileManager . get ( fileUrl , isBytesOptimized ? undefined : offsets ) ;
387+ }
388+
351389 resolveRequest ( file ?. buffer ) ;
352390 } else {
353391 rejectRequest ( new CustomError ( `File - ${ fileUrl } not found` ) ) ;
354392 }
355393 }
356394 } )
357395 . catch ( ( error ) => {
396+ fileFetchingCompleted = true ;
358397 rejectRequest ( error ) ;
359398 } )
360- . then ( ( ) => {
361- dataRetrievalManager . removeEventListener ( FILE_STREAMING_WORKER_NAME , 'message' , handleChunkAppend ) ;
399+ . finally ( ( ) => {
400+ completeRequest ( fileUrl ) ;
362401 } ) ;
363402 } ) ;
364403 }
0 commit comments