diff --git a/package.json b/package.json index bd318b6..52fb3d1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cod-dicomweb-server", "title": "COD Dicomweb server", - "version": "1.3.11", + "version": "1.3.12", "private": false, "description": "A wadors server proxy that get data from a Cloud Optimized Dicom format.", "main": "dist/umd/main.js", diff --git a/src/classes/CodDicomWebServer.ts b/src/classes/CodDicomWebServer.ts index 1e346b0..2144a98 100644 --- a/src/classes/CodDicomWebServer.ts +++ b/src/classes/CodDicomWebServer.ts @@ -21,7 +21,7 @@ import { download, getDirectoryHandle } from '../fileAccessSystemUtils'; class CodDicomWebServer { private filePromises: Record> = {}; private options: CodDicomWebServerOptions = { - maxWorkerFetchSize: Infinity, + maxCacheSize: 4 * 1024 * 1024 * 1024, // 4GB domain: constants.url.DOMAIN, enableLocalCache: false }; @@ -29,15 +29,15 @@ class CodDicomWebServer { private metadataManager; private seriesUidFileUrls: Record> = {}; - constructor(args: { maxWorkerFetchSize?: number; domain?: string; disableWorker?: boolean; enableLocalCache?: boolean } = {}) { - const { maxWorkerFetchSize, domain, disableWorker, enableLocalCache } = args; + constructor(args: { maxCacheSize?: number; domain?: string; disableWorker?: boolean; enableLocalCache?: boolean } = {}) { + const { maxCacheSize, domain, disableWorker, enableLocalCache } = args; - this.options.maxWorkerFetchSize = maxWorkerFetchSize || this.options.maxWorkerFetchSize; + this.options.maxCacheSize = maxCacheSize || this.options.maxCacheSize; this.options.domain = domain || this.options.domain; this.options.enableLocalCache = !!enableLocalCache; const fileStreamingScriptName = constants.dataRetrieval.FILE_STREAMING_WORKER_NAME; const filePartialScriptName = constants.dataRetrieval.FILE_PARTIAL_WORKER_NAME; - this.fileManager = new FileManager({ fileStreamingScriptName }); + this.fileManager = new FileManager(); this.metadataManager = new MetadataManager(); if (disableWorker) { @@ -45,7 +45,7 @@ class CodDicomWebServer { dataRetrievalManager.setDataRetrieverMode(Enums.DataRetrieveMode.REQUEST); } - register({ fileStreamingScriptName, filePartialScriptName }, this.options.maxWorkerFetchSize); + register({ fileStreamingScriptName, filePartialScriptName }); } public setOptions = (newOptions: Partial): void => { @@ -213,17 +213,12 @@ class CodDicomWebServer { } const directoryHandle = this.options.enableLocalCache && (await getDirectoryHandle()); - const { maxWorkerFetchSize } = this.getOptions(); const dataRetrievalManager = getDataRetrievalManager(); - const { FILE_STREAMING_WORKER_NAME, FILE_PARTIAL_WORKER_NAME, THRESHOLD } = constants.dataRetrieval; + const { FILE_STREAMING_WORKER_NAME, FILE_PARTIAL_WORKER_NAME } = constants.dataRetrieval; let tarPromise: Promise; if (!this.filePromises[fileUrl]) { tarPromise = new Promise((resolveFile, rejectFile) => { - if (this.fileManager.getTotalSize() + THRESHOLD > maxWorkerFetchSize) { - throw new CustomError(`CodDicomWebServer.ts: Maximum size(${maxWorkerFetchSize}) for fetching files reached`); - } - const FetchTypeEnum = constants.Enums.FetchType; if (fetchType === FetchTypeEnum.API_OPTIMIZED) { @@ -315,7 +310,7 @@ class CodDicomWebServer { throw evt.error; } - const { url, position, chunk, isAppending } = evt.data; + const { url, position, chunk, totalLength, isAppending } = evt.data; if (isAppending) { if (chunk) { @@ -323,6 +318,13 @@ class CodDicomWebServer { } else { this.fileManager.setPosition(url, position); } + } else { + // The full empty file including with first chunk have been stored to fileManager + // by the worker listener in the file promise. + // So, we check whether the cache exceeded the limit here. + if (this.fileManager.getTotalSize() > this.options.maxCacheSize) { + this.fileManager.decacheNecessaryBytes(url, totalLength); + } } if (!requestResolved && url === fileUrl && offsets && position > offsets.endByte) { diff --git a/src/classes/customClasses.ts b/src/classes/customClasses.ts index 27c3b58..427a00b 100644 --- a/src/classes/customClasses.ts +++ b/src/classes/customClasses.ts @@ -17,5 +17,6 @@ export class CustomMessageEvent extends MessageEvent<{ chunk?: Uint8Array; isAppending?: boolean; fileArraybuffer?: Uint8Array; + totalLength: number; offsets?: { startByte: number; endByte: number }; }> {} diff --git a/src/dataRetrieval/register.ts b/src/dataRetrieval/register.ts index fd9f3ba..483de2a 100644 --- a/src/dataRetrieval/register.ts +++ b/src/dataRetrieval/register.ts @@ -3,13 +3,7 @@ import { getDataRetrievalManager } from './dataRetrievalManager'; import filePartial from './scripts/filePartial'; import fileStreaming from './scripts/fileStreaming'; -export function register( - workerNames: { - fileStreamingScriptName: string; - filePartialScriptName: string; - }, - maxFetchSize: number -): void { +export function register(workerNames: { fileStreamingScriptName: string; filePartialScriptName: string }): void { const { fileStreamingScriptName, filePartialScriptName } = workerNames; const dataRetrievalManager = getDataRetrievalManager(); @@ -33,6 +27,4 @@ export function register( dataRetrievalManager.register(filePartialScriptName, partialWorkerFn); } - - dataRetrievalManager.executeTask(fileStreamingScriptName, 'setMaxFetchSize', maxFetchSize); } diff --git a/src/dataRetrieval/scripts/fileStreaming.ts b/src/dataRetrieval/scripts/fileStreaming.ts index 22b1b0c..1253907 100644 --- a/src/dataRetrieval/scripts/fileStreaming.ts +++ b/src/dataRetrieval/scripts/fileStreaming.ts @@ -2,21 +2,6 @@ import { CustomError } from '../../classes/customClasses'; import { createStreamingFileName, readFile, writeFile } from '../../fileAccessSystemUtils'; const fileStreaming = { - maxFetchSize: 4 * 1024 * 1024 * 1024, // 4GB - fetchedSize: 0, - - setMaxFetchSize(size: number): void { - if (size > 0) { - this.maxFetchSize = size; - } - }, - - decreaseFetchedSize(size: number): void { - if (size > 0 && size <= this.fetchedSize) { - this.fetchedSize -= size; - } - }, - async stream( args: { url: string; @@ -30,6 +15,7 @@ const fileStreaming = { isAppending?: boolean; fileArraybuffer?: Uint8Array; chunk?: Uint8Array; + totalLength: number; }) => void ): Promise { const { url, headers, useSharedArrayBuffer, directoryHandle } = args; @@ -42,7 +28,8 @@ const fileStreaming = { if (directoryHandle) { const file = (await readFile(directoryHandle, fileName, { isJson: false })) as ArrayBuffer; if (file) { - callBack({ url, position: file.byteLength, fileArraybuffer: new Uint8Array(file) }); + const totalLength = file.byteLength; + callBack({ url, position: totalLength, fileArraybuffer: new Uint8Array(file), totalLength }); return; } } @@ -74,13 +61,6 @@ const fileStreaming = { if (!completed) { let position = firstChunk.value.length; - if (this.fetchedSize + position > this.maxFetchSize) { - controller.abort(); - throw new CustomError(`Maximum size(${this.maxFetchSize}) for fetching files reached`); - } - - this.fetchedSize += position; - if (useSharedArrayBuffer) { sharedArraybuffer = new SharedArrayBuffer(totalLength); fileArraybuffer = new Uint8Array(sharedArraybuffer); @@ -88,7 +68,7 @@ const fileStreaming = { fileArraybuffer = new Uint8Array(totalLength); } fileArraybuffer.set(firstChunk.value); - callBack({ url, position, fileArraybuffer }); + callBack({ url, position, fileArraybuffer, totalLength }); while (!completed) { result = await reader.read(); @@ -100,14 +80,6 @@ const fileStreaming = { const chunk = result.value; - if (this.fetchedSize + chunk.length > this.maxFetchSize) { - sharedArraybuffer = null; - fileArraybuffer = null; - controller.abort(); - throw new CustomError(`Maximum size(${this.maxFetchSize}) for fetching files reached`); - } - - this.fetchedSize += chunk.length; fileArraybuffer.set(chunk, position); position += chunk.length; @@ -115,7 +87,8 @@ const fileStreaming = { isAppending: true, url, position: position, - chunk: !useSharedArrayBuffer ? chunk : undefined + chunk: !useSharedArrayBuffer ? chunk : undefined, + totalLength }); } diff --git a/src/fileManager.ts b/src/fileManager.ts index e07309b..d472c83 100644 --- a/src/fileManager.ts +++ b/src/fileManager.ts @@ -1,16 +1,10 @@ -import type { FileManagerOptions } from './types'; -import { getDataRetrievalManager } from './dataRetrieval/dataRetrievalManager'; +import type { FileManagerFile } from './types'; class FileManager { - private files: Record = {}; - private fileStreamingScriptName: string; + private files: Record = {}; - constructor({ fileStreamingScriptName }: FileManagerOptions) { - this.fileStreamingScriptName = fileStreamingScriptName; - } - - set(url: string, file: { data: Uint8Array; position: number }): void { - this.files[url] = file; + set(url: string, file: Omit): void { + this.files[url] = { ...file, lastModified: Date.now() }; } get(url: string, offsets?: { startByte: number; endByte: number }): Uint8Array | null { @@ -24,6 +18,7 @@ class FileManager { setPosition(url: string, position: number): void { if (this.files[url]) { this.files[url].position = position; + this.files[url].lastModified = Date.now(); } } @@ -39,29 +34,46 @@ class FileManager { } getTotalSize(): number { - return Object.entries(this.files).reduce((total, [url, { position }]) => { - return url.includes('?bytes=') ? total : total + position; + return Object.values(this.files).reduce((total, { data }) => { + return total + data.byteLength; }, 0); } remove(url: string): void { - const removedSize = this.getPosition(url); - delete this.files[url]; - - if (url.includes('?bytes=')) { - return; + try { + delete this.files[url]; + console.log(`Removed ${url} from CodDicomwebServer cache`); + } catch (error) { + console.warn(`Error removing ${url} from CodDicomwebServer cache:`, error); } - - const retrievalManager = getDataRetrievalManager(); - retrievalManager.executeTask(this.fileStreamingScriptName, 'decreaseFetchedSize', removedSize); } purge(): void { + const fileURLs = Object.keys(this.files); + const totalSize = this.getTotalSize(); + fileURLs.forEach((url) => this.remove(url)); + + console.log(`Purged ${totalSize - this.getTotalSize()} bytes from CodDicomwebServer cache`); + } + + decacheNecessaryBytes(url: string, bytesNeeded: number): number { const totalSize = this.getTotalSize(); - this.files = {}; + const filesToDelete: string[] = []; + let collectiveSize = 0; + + Object.entries(this.files) + .sort(([, a], [, b]) => a.lastModified - b.lastModified) + .forEach(([key, file]) => { + if (collectiveSize < bytesNeeded && key !== url) { + filesToDelete.push(key); + collectiveSize += file.data.byteLength; + } + }); + + filesToDelete.forEach((key) => this.remove(key)); - const retrievalManager = getDataRetrievalManager(); - retrievalManager.executeTask(this.fileStreamingScriptName, 'decreaseFetchedSize', totalSize); + console.log(`Decached ${totalSize - this.getTotalSize()} bytes`); + return collectiveSize; } } diff --git a/src/tests/classes/CodDicomWebServer.test.ts b/src/tests/classes/CodDicomWebServer.test.ts index b301f52..5cad960 100644 --- a/src/tests/classes/CodDicomWebServer.test.ts +++ b/src/tests/classes/CodDicomWebServer.test.ts @@ -7,7 +7,6 @@ describe('CodDicomWebServer', () => { const getDataRetrievalManagerMock = jest.spyOn(require('../../dataRetrieval/dataRetrievalManager'), 'getDataRetrievalManager'); const fileManagerMock = jest.spyOn(require('../../fileManager'), 'default'); const metadataManagerMock = jest.spyOn(require('../../metadataManager'), 'default'); - const getDirectoryHandleMock = jest.spyOn(require('../../fileAccessSystemUtils'), 'getDirectoryHandle').mockReturnThis(); const workerAddEventListener = jest.fn(); const fileManagerSet = jest.fn(); @@ -68,7 +67,7 @@ describe('CodDicomWebServer', () => { }); it('should create a new instance with custom options', () => { - const options = { maxWorkerFetchSize: 10000, domain: 'example.com' }; + const options = { maxCacheSize: 10000, domain: 'example.com' }; const serverWithCustomOptions = new CodDicomWebServer(options); expect(serverWithCustomOptions).toBeInstanceOf(CodDicomWebServer); }); @@ -77,23 +76,23 @@ describe('CodDicomWebServer', () => { describe('getOptions', () => { it('should return the default options if not set', () => { const options = server.getOptions(); - expect(options).toEqual({ maxWorkerFetchSize: Infinity, domain: url.DOMAIN, enableLocalCache: false }); + expect(options).toEqual({ maxCacheSize: Infinity, domain: url.DOMAIN, enableLocalCache: false }); }); }); describe('setOptions', () => { it('should set new options', () => { - const newOptions = { maxWorkerFetchSize: 2000 }; + const newOptions = { maxCacheSize: 2000 }; server.setOptions(newOptions); expect(server.getOptions()).toEqual({ domain: url.DOMAIN, enableLocalCache: false, ...newOptions }); }); it('should not set new options if the value is undefined', () => { - const newOptions = { maxWorkerFetchSize: 2000, domain: undefined }; + const newOptions = { maxCacheSize: 2000, domain: undefined }; server.setOptions(newOptions); expect(server.getOptions()).toEqual({ domain: url.DOMAIN, - maxWorkerFetchSize: newOptions.maxWorkerFetchSize, + maxCacheSize: newOptions.maxCacheSize, enableLocalCache: false }); }); @@ -202,7 +201,7 @@ describe('CodDicomWebServer', () => { ); }); - it('should throw an error if the maxFetchSize has been exceeded', async () => { + it('should handle even if there is a cache limit', async () => { const fileUrl = 'fileUrl'; const headers = { 'Content-Type': 'application/octet-stream' }; const options = { @@ -210,13 +209,11 @@ describe('CodDicomWebServer', () => { useSharedArrayBuffer: true, fetchType: Enums.FetchType.BYTES_OPTIMIZED }; - server.setOptions({ maxWorkerFetchSize: 20 }); + server.setOptions({ maxCacheSize: 20 }); fileManagerGetTotalSize.mockReturnValueOnce(23); // @ts-ignore - await expect(server.fetchFile(fileUrl, headers, options)).rejects.toThrow( - 'CodDicomWebServer.ts: Maximum size(20) for fetching files reached' - ); + await expect(server.fetchFile(fileUrl, headers, options)).resolves; }); it('should return the file if cached in the fileManager', async () => { @@ -242,7 +239,7 @@ describe('CodDicomWebServer', () => { it('should delete a series instance', () => { const seriesInstanceUID = '1.2.3.4'; - server.addFileUrl(seriesInstanceUID, 'fileUrl'); + server.addFileUrl(seriesInstanceUID, Enums.URLType.FILE, 'fileUrl'); server.delete(seriesInstanceUID); expect(fileManagerRemove).toHaveBeenCalledTimes(1); @@ -258,10 +255,10 @@ describe('CodDicomWebServer', () => { describe('deleteAll', () => { it('should delete all series instances', () => { - server.addFileUrl('1.2.3.4', 'fileUrl1'); - server.addFileUrl('1.2.4', 'fileUrl2'); - server.addFileUrl('1.2.4', 'fileUrl3'); - server.addFileUrl('1.2.3.4', 'fileUrl3'); + server.addFileUrl('1.2.3.4', Enums.URLType.FILE, 'fileUrl1'); + server.addFileUrl('1.2.4', Enums.URLType.FILE, 'fileUrl2'); + server.addFileUrl('1.2.4', Enums.URLType.FILE, 'fileUrl3'); + server.addFileUrl('1.2.3.4', Enums.URLType.FILE, 'fileUrl3'); server.deleteAll(); expect(fileManagerRemove).toHaveBeenCalledTimes(4); diff --git a/src/tests/dataRetrieval/scripts/fileStreaming.test.ts b/src/tests/dataRetrieval/scripts/fileStreaming.test.ts index a8cebf1..59b910e 100644 --- a/src/tests/dataRetrieval/scripts/fileStreaming.test.ts +++ b/src/tests/dataRetrieval/scripts/fileStreaming.test.ts @@ -38,61 +38,10 @@ const URL_RESPONSES = { }; describe('fileStreaming', () => { - let initialFetchedSize: number, initialMaxFetchSize: number; - - beforeAll(() => { - ({ fetchedSize: initialFetchedSize, maxFetchSize: initialMaxFetchSize } = fileStreaming); - }); - beforeEach(() => { jest.clearAllMocks(); }); - describe('setMaxFetchSize', () => { - afterEach(() => { - fileStreaming.setMaxFetchSize(initialMaxFetchSize); - }); - - it('should not set the maxFetchSize if is less than or equal to 0', async () => { - const newSize = -10; - fileStreaming.setMaxFetchSize(newSize); - expect(fileStreaming.maxFetchSize).toBe(initialMaxFetchSize); - }); - - it('should set the maxFetchSize if is greater than 0', async () => { - const newSize = 100; - fileStreaming.setMaxFetchSize(newSize); - expect(fileStreaming.maxFetchSize).toBe(newSize); - }); - }); - - describe('decreaseFetchedSize', () => { - afterEach(() => { - fileStreaming.fetchedSize = initialFetchedSize; - }); - - it('should decrease the fetchedSize if the decreaseSize is greater than 0', async () => { - fileStreaming.fetchedSize = 80; - const decreaseSize = 50; - fileStreaming.decreaseFetchedSize(decreaseSize); - expect(fileStreaming.fetchedSize).toBe(30); - }); - - it('should not decrease the fetchedSize if the decreaseSize is less than or equal to 0', async () => { - fileStreaming.fetchedSize = 80; - const decreaseSize = -5; - fileStreaming.decreaseFetchedSize(decreaseSize); - expect(fileStreaming.fetchedSize).toBe(80); - }); - - it('should not decrease the fetchedSize if the decreaseSize greater than the fetchedSize', async () => { - fileStreaming.fetchedSize = 30; - const decreaseSize = 50; - fileStreaming.decreaseFetchedSize(decreaseSize); - expect(fileStreaming.fetchedSize).toBe(30); - }); - }); - describe('stream', () => { global.fetch = jest.fn(async (url: string) => { return URL_RESPONSES[url] || Promise.reject(new CustomError('Error Fetching')); @@ -102,8 +51,6 @@ describe('fileStreaming', () => { afterEach(() => { jest.clearAllMocks(); - fileStreaming.fetchedSize = initialFetchedSize; - fileStreaming.setMaxFetchSize(initialMaxFetchSize); }); it('stream with invalid headers', async () => { @@ -145,33 +92,6 @@ describe('fileStreaming', () => { ); }); - it('should throw an error if maxFetchSize is exceeded - case1', async () => { - const url = 'exceed_max_size_1'; - const headers = { 'Content-Type': 'application/octet-stream' }; - fileStreaming.setMaxFetchSize(3); - const callback = jest.fn(); - await expect(fileStreaming.stream({ url, headers }, callback)).rejects.toThrow( - 'fileStreaming.ts: Maximum size(3) for fetching files reached' - ); - }); - - it('should throw an error if maxFetchSize is exceeded - case2', async () => { - const url = 'exceed_max_size_2'; - const headers = { 'Content-Type': 'application/octet-stream' }; - fileStreaming.setMaxFetchSize(5); - const callback = jest.fn(); - await expect(fileStreaming.stream({ url, headers }, callback)).rejects.toThrow( - 'fileStreaming.ts: Maximum size(5) for fetching files reached' - ); - - expect(global.fetch).toHaveBeenCalledWith(url, { headers, signal: expect.any(AbortSignal) }); - expect(callback).toHaveBeenCalledWith({ - url, - position: 4, - fileArraybuffer: Uint8Array.from([1, 2, 3, 4, 0, 0, 0, 0, 0, 0]) - }); - }); - it('should callback the file', async () => { const url = 'working_case_1'; const headers = { 'Content-Type': 'application/octet-stream' }; @@ -185,22 +105,23 @@ describe('fileStreaming', () => { position: 4, // To the listener of the postMessage, the first four of fileArraybuffer will have value, // the rest will be 0 because listener params are cloned from the postmessage inputs. - fileArraybuffer: Uint8Array.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + fileArraybuffer: Uint8Array.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), + totalLength: 10 }); expect(callback).toHaveBeenCalledWith({ isAppending: true, url, position: 7, - chunk: Uint8Array.from([5, 6, 7]) + chunk: Uint8Array.from([5, 6, 7]), + totalLength: 10 }); expect(callback).toHaveBeenCalledWith({ isAppending: true, url, position: 10, - chunk: Uint8Array.from([8, 9, 10]) + chunk: Uint8Array.from([8, 9, 10]), + totalLength: 10 }); - - expect(fileStreaming.fetchedSize).toBe(10); }); it('should stream with useSharedArrayBuffer', async () => { @@ -214,21 +135,23 @@ describe('fileStreaming', () => { expect(callback).toHaveBeenCalledWith({ url, position: 4, - fileArraybuffer: Uint8Array.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + fileArraybuffer: Uint8Array.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), + totalLength: 10 }); expect(callback).toHaveBeenCalledWith({ isAppending: true, url, position: 7, - chunk: undefined + chunk: undefined, + totalLength: 10 }); expect(callback).toHaveBeenCalledWith({ isAppending: true, url, position: 10, - chunk: undefined + chunk: undefined, + totalLength: 10 }); - expect(fileStreaming.fetchedSize).toBe(10); }); }); }); diff --git a/src/tests/fileManager.test.ts b/src/tests/fileManager.test.ts index d0c05b8..08fb850 100644 --- a/src/tests/fileManager.test.ts +++ b/src/tests/fileManager.test.ts @@ -3,11 +3,8 @@ import FileManager from '../fileManager'; describe('FileManager', () => { let fileManager: FileManager; - const getDataRetrievalManagerMock = jest.spyOn(require('../dataRetrieval/dataRetrievalManager'), 'getDataRetrievalManager'); - getDataRetrievalManagerMock.mockImplementation(() => ({ executeTask: jest.fn() })); - beforeEach(() => { - fileManager = new FileManager({ fileStreamingScriptName: 'test-worker' }); + fileManager = new FileManager(); jest.clearAllMocks(); }); @@ -117,7 +114,7 @@ describe('FileManager', () => { const file3 = { data: new Uint8Array([4, 5, 6]), position: 3 }; fileManager.set(url3, file3); - expect(fileManager.getTotalSize()).toBe(6); + expect(fileManager.getTotalSize()).toBe(9); }); it('should remove file', () => { @@ -127,7 +124,6 @@ describe('FileManager', () => { fileManager.remove(url); expect(fileManager.get(url)).toBeNull(); - expect(getDataRetrievalManagerMock).toHaveBeenCalledTimes(1); }); it('should remove file but wont call getWebWorkerManager', () => { @@ -137,7 +133,6 @@ describe('FileManager', () => { fileManager.remove(url); expect(fileManager.get(url)).toBeNull(); - expect(getDataRetrievalManagerMock).not.toHaveBeenCalled(); }); it('should purge all files', () => { @@ -151,6 +146,6 @@ describe('FileManager', () => { expect(fileManager.get(url1)).toBeNull(); expect(fileManager.get(url2)).toBeNull(); - expect(getDataRetrievalManagerMock).toHaveBeenCalledTimes(1); + expect(fileManager.getTotalSize()).toEqual(0); }); }); diff --git a/src/types/codDicomWebServerOptions.ts b/src/types/codDicomWebServerOptions.ts index a51df8b..30f06b6 100644 --- a/src/types/codDicomWebServerOptions.ts +++ b/src/types/codDicomWebServerOptions.ts @@ -1,6 +1,6 @@ type CodDicomWebServerOptions = { [key: string]: number | string | boolean; - maxWorkerFetchSize: number; + maxCacheSize: number; domain: string; enableLocalCache: boolean; }; diff --git a/src/types/fileManagerFile.ts b/src/types/fileManagerFile.ts new file mode 100644 index 0000000..96afbec --- /dev/null +++ b/src/types/fileManagerFile.ts @@ -0,0 +1,3 @@ +type FileManagerFile = { data: Uint8Array; position: number; lastModified: number }; + +export type { FileManagerFile }; diff --git a/src/types/fileManagerOptions.ts b/src/types/fileManagerOptions.ts deleted file mode 100644 index 78d1cce..0000000 --- a/src/types/fileManagerOptions.ts +++ /dev/null @@ -1,3 +0,0 @@ -type FileManagerOptions = { fileStreamingScriptName: string }; - -export type { FileManagerOptions }; diff --git a/src/types/index.ts b/src/types/index.ts index ae103c2..47a97ea 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,5 +1,5 @@ export * from './codDicomWebServerOptions'; -export * from './fileManagerOptions'; +export * from './fileManagerFile'; export * from './metadata'; export * from './metadataUrlCreationParams'; export * from './parsedWadoRsUrlDetails';