summaryrefslogtreecommitdiff
path: root/ext/js/general/task-accumulator.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/js/general/task-accumulator.js')
-rw-r--r--ext/js/general/task-accumulator.js46
1 files changed, 40 insertions, 6 deletions
diff --git a/ext/js/general/task-accumulator.js b/ext/js/general/task-accumulator.js
index cae58b94..cb136908 100644
--- a/ext/js/general/task-accumulator.js
+++ b/ext/js/general/task-accumulator.js
@@ -18,25 +18,46 @@
import {log} from '../core.js';
+/**
+ * @template K,V
+ */
export class TaskAccumulator {
+ /**
+ * @param {(tasks: [key: ?K, task: import('task-accumulator').Task<V>][]) => Promise<void>} runTasks
+ */
constructor(runTasks) {
+ /** @type {?Promise<void>} */
this._deferPromise = null;
+ /** @type {?Promise<void>} */
this._activePromise = null;
+ /** @type {import('task-accumulator').Task<V>[]} */
this._tasks = [];
+ /** @type {import('task-accumulator').Task<V>[]} */
this._tasksActive = [];
+ /** @type {Map<K, import('task-accumulator').Task<V>>} */
this._uniqueTasks = new Map();
+ /** @type {Map<K, import('task-accumulator').Task<V>>} */
this._uniqueTasksActive = new Map();
+ /** @type {() => Promise<void>} */
this._runTasksBind = this._runTasks.bind(this);
+ /** @type {() => void} */
this._tasksCompleteBind = this._tasksComplete.bind(this);
- this._runTasks = runTasks;
+ /** @type {(tasks: [key: ?K, task: import('task-accumulator').Task<V>][]) => Promise<void>} */
+ this._runTasksCallback = runTasks;
}
+ /**
+ * @param {?K} key
+ * @param {V} data
+ * @returns {Promise<void>}
+ */
enqueue(key, data) {
if (this._deferPromise === null) {
const promise = this._activePromise !== null ? this._activePromise : Promise.resolve();
this._deferPromise = promise.then(this._runTasksBind);
}
+ /** @type {import('task-accumulator').Task<V>} */
const task = {data, stale: false};
if (key !== null) {
const activeTaskInfo = this._uniqueTasksActive.get(key);
@@ -52,6 +73,9 @@ export class TaskAccumulator {
return this._deferPromise;
}
+ /**
+ * @returns {Promise<void>}
+ */
_runTasks() {
this._deferPromise = null;
@@ -64,18 +88,28 @@ export class TaskAccumulator {
return this._activePromise;
}
+ /**
+ * @returns {Promise<void>}
+ */
async _runTasksAsync() {
try {
- const allTasks = [
- ...this._tasksActive.map((taskInfo) => [null, taskInfo]),
- ...this._uniqueTasksActive.entries()
- ];
- await this._runTasks(allTasks);
+ /** @type {[key: ?K, task: import('task-accumulator').Task<V>][]} */
+ const allTasks = [];
+ for (const taskInfo of this._tasksActive) {
+ allTasks.push([null, taskInfo]);
+ }
+ for (const [key, taskInfo] of this._uniqueTasksActive) {
+ allTasks.push([key, taskInfo]);
+ }
+ await this._runTasksCallback(allTasks);
} catch (e) {
log.error(e);
}
}
+ /**
+ * @returns {void}
+ */
_tasksComplete() {
this._tasksActive.length = 0;
this._uniqueTasksActive.clear();