@uppy/provider-views
Version:
View library for Uppy remote provider plugins.
64 lines (63 loc) • 2.64 kB
JavaScript
// p-queue does not have a `"main"` field in its `package.json`, and that makes `import/no-unresolved` freak out.
// We can safely ignore it because bundlers will happily use the `"exports"` field instead.
import PQueue from 'p-queue';
import shallowClone from './shallowClone.js';
const recursivelyFetch = async (queue, poorTree, poorFolder, apiList, validateSingleFile) => {
let items = [];
let currentPath = poorFolder.cached
? poorFolder.nextPagePath
: poorFolder.id;
while (currentPath) {
const response = await apiList(currentPath);
items = items.concat(response.items);
currentPath = response.nextPagePath;
}
const newFolders = items.filter((i) => i.isFolder === true);
const newFiles = items.filter((i) => i.isFolder === false);
const folders = newFolders.map((folder) => ({
type: 'folder',
id: folder.requestPath,
cached: false,
nextPagePath: null,
status: 'checked',
parentId: poorFolder.id,
data: folder,
}));
const files = newFiles.map((file) => {
const restrictionError = validateSingleFile(file);
return {
type: 'file',
id: file.requestPath,
restrictionError,
status: restrictionError ? 'unchecked' : 'checked',
parentId: poorFolder.id,
data: file,
};
});
poorFolder.cached = true;
poorFolder.nextPagePath = null;
poorTree.push(...files, ...folders);
folders.forEach(async (folder) => {
queue.add(() => recursivelyFetch(queue, poorTree, folder, apiList, validateSingleFile));
});
};
const afterFill = async (partialTree, apiList, validateSingleFile, reportProgress) => {
const queue = new PQueue({ concurrency: 6 });
// fill up the missing parts of a partialTree!
const poorTree = shallowClone(partialTree);
const poorFolders = poorTree.filter((item) => item.type === 'folder' &&
item.status === 'checked' &&
// either "not yet cached at all" or "some pages are left to fetch"
(item.cached === false || item.nextPagePath));
// per each poor folder, recursively fetch all files and make them .checked!
poorFolders.forEach((poorFolder) => {
queue.add(() => recursivelyFetch(queue, poorTree, poorFolder, apiList, validateSingleFile));
});
queue.on('completed', () => {
const nOfFilesChecked = poorTree.filter((i) => i.type === 'file' && i.status === 'checked').length;
reportProgress(nOfFilesChecked);
});
await queue.onIdle();
return poorTree;
};
export default afterFill;