Files
dewedev/node_modules/webpack/lib/util/processAsyncTree.js
dwindown 7f2dd5260f Initial commit: Developer Tools MVP with visual editor
- Complete React app with 7 developer tools
- JSON Tool with visual structured editor
- Serialize Tool with visual structured editor
- URL, Base64, CSV/JSON, Beautifier, Diff tools
- Responsive navigation with dropdown menu
- Dark/light mode toggle
- Mobile-responsive design with sticky header
- All tools working with copy/paste functionality
2025-08-02 09:31:26 +07:00

69 lines
1.6 KiB
JavaScript

/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/**
* @template T
* @template {Error} E
* @param {Iterable<T>} items initial items
* @param {number} concurrency number of items running in parallel
* @param {(item: T, push: (item: T) => void, callback: (err?: E) => void) => void} processor worker which pushes more items
* @param {(err?: E) => void} callback all items processed
* @returns {void}
*/
const processAsyncTree = (items, concurrency, processor, callback) => {
const queue = [...items];
if (queue.length === 0) return callback();
let processing = 0;
let finished = false;
let processScheduled = true;
/**
* @param {T} item item
*/
const push = (item) => {
queue.push(item);
if (!processScheduled && processing < concurrency) {
processScheduled = true;
process.nextTick(processQueue);
}
};
/**
* @param {E | null | undefined} err error
*/
const processorCallback = (err) => {
processing--;
if (err && !finished) {
finished = true;
callback(err);
return;
}
if (!processScheduled) {
processScheduled = true;
process.nextTick(processQueue);
}
};
const processQueue = () => {
if (finished) return;
while (processing < concurrency && queue.length > 0) {
processing++;
const item = /** @type {T} */ (queue.pop());
processor(item, push, processorCallback);
}
processScheduled = false;
if (queue.length === 0 && processing === 0 && !finished) {
finished = true;
callback();
}
};
processQueue();
};
module.exports = processAsyncTree;