pangu
Version:
Paranoid text spacing for good readability, to automatically insert whitespace between CJK (Chinese, Japanese, Korean) and half-width characters (alphabetical letters, numerical digits and symbols).
65 lines (54 loc) • 1.6 kB
text/typescript
export interface TaskSchedulerConfig {
enabled: boolean;
timeout: number;
}
export class TaskQueue {
private queue: (() => void)[] = [];
private isProcessing = false;
add(task: () => void) {
this.queue.push(task);
this.scheduleProcessing();
}
clear() {
this.queue.length = 0;
}
get length() {
return this.queue.length;
}
private scheduleProcessing() {
if (!this.isProcessing && this.queue.length > 0) {
this.isProcessing = true;
requestIdleCallback((deadline) => this.process(deadline), { timeout: 5000 });
}
}
private process(deadline: IdleDeadline) {
try {
while (deadline.timeRemaining() > 0 && this.queue.length > 0) {
const task = this.queue.shift();
task?.();
}
} finally {
// A throwing task must not leave isProcessing stuck at true, or every
// future add() would silently never schedule processing again
this.isProcessing = false;
if (this.queue.length > 0) {
this.scheduleProcessing();
}
}
}
}
/**
* Runs queued text spacing work during browser idle time to avoid blocking the UI.
* Tasks execute via requestIdleCallback when the browser has spare time,
* ensuring smooth user experience even when processing large amounts of text.
*/
export class TaskScheduler {
public readonly config: TaskSchedulerConfig = {
enabled: true,
timeout: 2000, // Not consulted by scheduleProcessing(), which uses a hardcoded 5000ms idle deadline
};
private taskQueue = new TaskQueue();
get queue() {
return this.taskQueue;
}
}