From d7ac13792c3d262a6b3291a4bf5dc1e917920495 Mon Sep 17 00:00:00 2001
From: vkovtun <viktor.kovtun@id.ethz.ch>
Date: Wed, 17 Apr 2024 21:31:01 +0200
Subject: [PATCH] BIS-753: Working on efficient download.

---
 ui-admin/index.html                           |  1 +
 .../database/data-browser/DataBrowser.jsx     |  2 +-
 .../data-browser/DataBrowserController.js     | 24 +++++++++++++++++++
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/ui-admin/index.html b/ui-admin/index.html
index 54ad52df32a..55c8686f7de 100644
--- a/ui-admin/index.html
+++ b/ui-admin/index.html
@@ -40,6 +40,7 @@
       onerror="loadError()"
     ></script>
     <script src="/openbis/resources/api/data-store-server/api/jszip.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/streamsaver@2"></script>
     <script src="/openbis/resources/api/v3/require.js"></script>
     <script src="/openbis/resources/api/data-store-server/api/server-data-store-facade.js"></script>
   </head>
diff --git a/ui-admin/src/js/components/database/data-browser/DataBrowser.jsx b/ui-admin/src/js/components/database/data-browser/DataBrowser.jsx
index 23f04aea6a8..da902e41887 100644
--- a/ui-admin/src/js/components/database/data-browser/DataBrowser.jsx
+++ b/ui-admin/src/js/components/database/data-browser/DataBrowser.jsx
@@ -359,7 +359,7 @@ class DataBrowser extends React.Component {
   }
 
   async fileToBlob(file) {
-    const dataArray = await this.controller.download(file)
+    const dataArray = await this.controller.downloadFile(file)
     return new Blob(dataArray, { type: this.inferMimeType(file.path) })
   }
 
diff --git a/ui-admin/src/js/components/database/data-browser/DataBrowserController.js b/ui-admin/src/js/components/database/data-browser/DataBrowserController.js
index 80e578edad3..ef317d2f9b7 100644
--- a/ui-admin/src/js/components/database/data-browser/DataBrowserController.js
+++ b/ui-admin/src/js/components/database/data-browser/DataBrowserController.js
@@ -251,6 +251,30 @@ export default class DataBrowserController extends ComponentController {
     return dataArray
   }
 
+  async downloadFile(file) {
+    // Check if StreamSaver's service worker is correctly set up
+    if (!navigator.serviceWorker.controller) {
+      const registration = await navigator.serviceWorker.register('/sw.js'); // Path to your service worker file
+      await navigator.serviceWorker.ready; // Wait for the service worker to be ready
+    }
+
+    const streamSaver = window.streamSaver
+    streamSaver.mitm = 'https://cdn.jsdelivr.net/npm/streamsaver@2/mitm.html'
+    const fileStream = streamSaver.createWriteStream(file.name);
+    const writer = fileStream.getWriter();
+
+    let offset = 0;
+
+    while (offset < file.size) {
+      const chunk = await this._download(file, offset)
+      const buffer = await chunk.arrayBuffer()
+      await writer.write(new Uint8Array(buffer))
+      offset += CHUNK_SIZE
+    }
+
+    writer.close()
+  }
+
   async _download(file, offset) {
     const limit = Math.min(CHUNK_SIZE, file.size - offset)
     return await this.component.datastoreServer.read(this.owner, file.path, offset, limit)
-- 
GitLab