UNPKG

cod-dicomweb-server

Version:

A wadors server proxy that get data from a Cloud Optimized Dicom format.

84 lines (83 loc) 3.51 kB
import { CustomError } from '../../classes/customClasses'; import { createStreamingFileName, readFile, writeFile } from '../../fileAccessSystemUtils'; const fileStreaming = { async stream(args, callBack) { const { url, headers, useSharedArrayBuffer, directoryHandle } = args; const controller = new AbortController(); let sharedArraybuffer = null; let fileArraybuffer = null; try { const fileName = createStreamingFileName(url); if (directoryHandle) { const file = (await readFile(directoryHandle, fileName, { isJson: false })); if (file) { const totalLength = file.byteLength; callBack({ url, position: totalLength, fileArraybuffer: new Uint8Array(file), totalLength }); return; } } const response = await fetch(url, { headers: { ...headers }, signal: controller.signal }); if (!response.ok) { throw new CustomError(`HTTP error! status: ${response.status}`); } const reader = response.body?.getReader(); if (!reader) { throw new CustomError('Failed to get reader from response body'); } let result; let completed = false; const totalLength = parseInt(response.headers.get('Content-Length') || '0', 10); const firstChunk = await reader.read(); completed = firstChunk.done; if (!firstChunk.value) { throw new CustomError('The fetched chunks does not have value'); } if (!completed) { let position = firstChunk.value.length; if (useSharedArrayBuffer) { sharedArraybuffer = new SharedArrayBuffer(totalLength); fileArraybuffer = new Uint8Array(sharedArraybuffer); } else { fileArraybuffer = new Uint8Array(totalLength); } fileArraybuffer.set(firstChunk.value); callBack({ url, position, fileArraybuffer, totalLength }); while (!completed) { result = await reader.read(); if (result.done) { completed = true; continue; } const chunk = result.value; fileArraybuffer.set(chunk, position); position += chunk.length; callBack({ isAppending: true, url, position: position, chunk: !useSharedArrayBuffer ? chunk : undefined, totalLength }); } if (directoryHandle) { writeFile(directoryHandle, fileName, fileArraybuffer.slice().buffer); } } } catch (error) { const streamingError = new CustomError('fileStreaming.ts: ' + error.message || 'An error occured when streaming'); console.error(streamingError.message, error); throw streamingError; } finally { sharedArraybuffer = null; fileArraybuffer = null; controller.abort(); } } }; export default fileStreaming;