@jupyterlab/git
Version:
A JupyterLab extension for version control using git
119 lines (118 loc) • 3.46 kB
JavaScript
import { LinkedList } from '@lumino/collections';
import { UUID } from '@lumino/coreutils';
import { Signal } from '@lumino/signaling';
/**
* A generic task handler
*/
export class TaskHandler {
constructor(model) {
this._isDisposed = false;
this._taskList = new LinkedList();
this._taskChanged = new Signal(model);
}
/**
* Boolean indicating whether the handler has been disposed.
*/
get isDisposed() {
return this._isDisposed;
}
/**
* Signal emitted when a task starts
*
* 'empty' is emitted each time the task list have processed all tasks
*/
get taskChanged() {
return this._taskChanged;
}
/**
* Adds a task to the list of pending model tasks.
*
* #Note:
* This will add a task name in the queue but the task
* execution remains in the hand of the caller.
* In particular it is the responsibility of the caller
* to call `remove(taskID)` when the task is executed.
*
* @param task - task name
* @returns task identifier
*/
add(task) {
// Generate a unique task identifier:
const id = this._generateTaskID();
// Add the task to our list of pending tasks:
this._taskList.addLast({
id: id,
task: task
});
// If this task is the only task, broadcast the task...
if (this._taskList.length === 1) {
this._taskChanged.emit(task);
}
// Return the task identifier to allow consumers to remove the task once completed:
return id;
}
/**
* Dispose of task handler.
*/
dispose() {
if (this.isDisposed) {
return;
}
this._isDisposed = true;
Signal.clearData(this);
}
/**
* Add a asynchronous task to the stack and execute it
*
* @param name Name of the task
* @param callable Asynchronous task to be executed
*
* @returns The result of the task
*/
async execute(name, callable) {
const taskID = this.add(name);
try {
return await callable();
}
finally {
this.remove(taskID);
}
}
/**
* Removes a task from the list of pending model tasks.
*
* @param id - task identifier
*/
remove(taskID) {
let node = this._taskList.firstNode;
// Check the first node...
if ((node === null || node === void 0 ? void 0 : node.value.id) === taskID) {
this._taskList.removeNode(node);
}
else {
// Walk the task list looking for a task with the provided identifier...
while (node === null || node === void 0 ? void 0 : node.next) {
node = node === null || node === void 0 ? void 0 : node.next;
if (node.value && node.value.id === taskID) {
this._taskList.removeNode(node);
break;
}
}
}
// Check for pending tasks and broadcast the oldest pending task...
if (this._taskList.length === 0) {
this._taskChanged.emit('empty');
}
else {
this._taskChanged.emit(this._taskList.first.task);
}
}
/**
* Generates a unique task identifier.
*
* @returns task identifier
*/
_generateTaskID() {
return UUID.uuid4();
}
}