frontend/app/DeletedItems/DeletedItemsStreamConsumer.jsx (58 lines of code) (raw):

import ndjsonStream from "can-ndjson-stream"; /** * consumes the NDJSON stream of deleted objects * @param collection collection name to scan * @param prefix optional path-prefix to search within * @param searchDoc an AdvancedSearchDocument * @param callback callback to receive data. This is called once for every row with the arguments (ArchiveEntry, isDone boolean). * To continue the loading operation, it should return true; to cancel an in-progress operation it should return false. * @param delay optional time to wait between loads, in milliseconds. Can help prevent the page jamming/stuttering because javascript * renders are taking up all the runtime * @returns {Promise<void>} */ async function loadDeletedItemStream(collection, prefix, searchDoc, callback, delay) { let args = "?limit=200"; if(prefix) { args = `?prefix=${encodeURIComponent(prefix)}&limit=200` } const response = await fetch(`/api/deleted/${collection}/search${args}`,{ method: "PUT", body: JSON.stringify(searchDoc), headers: { "Content-Type": "application/json" } }); const asyncDelay = (ms) => { return new Promise((resolve, reject)=>window.setTimeout(resolve, ms)) } switch(response.status) { case 200: const streamReader = ndjsonStream(response.body).getReader(); let result; while(!result || !result.done) { result = await streamReader.read(); const shouldContinue = callback(result.value, result.done); if(!shouldContinue) { console.log("DeletedItemsStreamConsumer requested early cancellation"); await streamReader.cancel("User cancelled loading"); console.log("DeletedItemsStreamConsumer cancelletion completed"); return; } if(delay) await asyncDelay(delay); } break; case 502|503|504: console.warn("Server is not responding, retrying shortly..."); return new Promise((resolve, reject)=>{ window.setTimeout(()=>{ loadDeletedItemStream(collection, prefix, searchDoc, callback) .then(resolve) .catch(reject) }, 2000); }); default: console.error("Server returned an unexpected code: ", response.status); return; } } export {loadDeletedItemStream};