resig.js
Version:
Universal reactive signal library with complete platform features: signals, animations, CRDTs, scheduling, DOM integration. Works identically across React, SolidJS, Svelte, Vue, and Qwik.
343 lines • 24 kB
JavaScript
/**
* Scheduler - Stream coalgebra for managing async operations and animations
* Following coalgebraic principles for time-evolving systems
*/
import { signal } from '../core/signal';
// Task priority levels
export var Priority;
(function (Priority) {
Priority[Priority["IMMEDIATE"] = 0] = "IMMEDIATE";
Priority[Priority["HIGH"] = 1] = "HIGH";
Priority[Priority["NORMAL"] = 2] = "NORMAL";
Priority[Priority["LOW"] = 3] = "LOW";
Priority[Priority["IDLE"] = 4] = "IDLE";
})(Priority || (Priority = {}));
// Task queue implementation with priority
class TaskQueue {
constructor() {
this.queues = new Map();
this.taskMap = new Map();
// Initialize priority queues
Object.values(Priority).forEach((priority) => {
if (typeof priority === 'number') {
this.queues.set(priority, []);
}
});
}
enqueue(task) {
const queue = this.queues.get(task.priority);
if (queue) {
queue.push(task);
this.taskMap.set(task.id, task);
}
}
dequeue() {
// Process tasks by priority (lower number = higher priority)
for (const priority of [
Priority.IMMEDIATE,
Priority.HIGH,
Priority.NORMAL,
Priority.LOW,
Priority.IDLE,
]) {
const queue = this.queues.get(priority);
if (queue && queue.length > 0) {
const task = queue.shift();
this.taskMap.delete(task.id);
return task;
}
}
return null;
}
remove(taskId) {
const task = this.taskMap.get(taskId);
if (!task)
return false;
const queue = this.queues.get(task.priority);
if (queue) {
const index = queue.findIndex((t) => t.id === taskId);
if (index !== -1) {
queue.splice(index, 1);
this.taskMap.delete(taskId);
return true;
}
}
return false;
}
clear() {
this.queues.forEach((queue) => (queue.length = 0));
this.taskMap.clear();
}
get size() {
return this.taskMap.size;
}
}
// Main scheduler implementation
export const scheduler = () => {
const taskQueue = new TaskQueue();
const delayedTasks = new Map(); // taskId -> timeoutId
const repeatingTasks = new Map(); // taskId -> repeat info
let isRunning = false;
let animationFrameId = null;
let completedCount = 0;
let failedCount = 0;
const stateSignal = signal({
running: false,
taskCount: 0,
completedTasks: 0,
failedTasks: 0,
});
const updateState = () => {
stateSignal._set({
running: isRunning,
taskCount: taskQueue.size + delayedTasks.size,
completedTasks: completedCount,
failedTasks: failedCount,
});
};
const processTask = async (task) => {
try {
await task.execute();
completedCount++;
// Handle repeating tasks
if (task.repeat) {
const repeatInfo = repeatingTasks.get(task.id);
if (repeatInfo) {
if (typeof task.repeat === 'number') {
repeatInfo.remaining--;
if (repeatInfo.remaining <= 0) {
repeatingTasks.delete(task.id);
return;
}
}
// Reschedule the task
if (task.delay) {
const timeoutId = window.setTimeout(() => {
delayedTasks.delete(task.id);
taskQueue.enqueue(task);
updateState();
}, task.delay);
delayedTasks.set(task.id, timeoutId);
}
else {
taskQueue.enqueue(task);
}
}
}
}
catch (error) {
console.error(`Task ${task.id} failed:`, error);
failedCount++;
// Cancel task if it has a cancel handler
if (task.cancel) {
try {
task.cancel();
}
catch (cancelError) {
console.error(`Task ${task.id} cancel failed:`, cancelError);
}
}
}
updateState();
};
const tick = () => {
if (!isRunning)
return;
const task = taskQueue.dequeue();
if (task) {
processTask(task);
}
updateState();
if (isRunning) {
animationFrameId = requestAnimationFrame(tick);
}
};
const instance = {
state: stateSignal,
schedule: (task) => {
const taskId = task.id ||
`task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
const taskWithId = { ...task, id: taskId };
// Handle repeating tasks
if (task.repeat) {
const remaining = typeof task.repeat === 'number' ? task.repeat : Infinity;
repeatingTasks.set(taskId, { task: taskWithId, remaining });
}
// Handle delayed tasks
if (task.delay && task.delay > 0) {
const timeoutId = window.setTimeout(() => {
delayedTasks.delete(taskId);
taskQueue.enqueue(taskWithId);
updateState();
}, task.delay);
delayedTasks.set(taskId, timeoutId);
}
else {
taskQueue.enqueue(taskWithId);
}
updateState();
return taskId;
},
cancel: (taskId) => {
// Cancel delayed task
const timeoutId = delayedTasks.get(taskId);
if (timeoutId) {
clearTimeout(timeoutId);
delayedTasks.delete(taskId);
repeatingTasks.delete(taskId);
updateState();
return true;
}
// Cancel queued task
const removed = taskQueue.remove(taskId);
if (removed) {
repeatingTasks.delete(taskId);
updateState();
return true;
}
return false;
},
start: () => {
if (isRunning)
return;
isRunning = true;
updateState();
tick();
},
stop: () => {
if (!isRunning)
return;
isRunning = false;
if (animationFrameId) {
cancelAnimationFrame(animationFrameId);
animationFrameId = null;
}
updateState();
},
clear: () => {
// Cancel all delayed tasks
delayedTasks.forEach((timeoutId) => clearTimeout(timeoutId));
delayedTasks.clear();
// Clear all queues
taskQueue.clear();
repeatingTasks.clear();
// Reset counters
completedCount = 0;
failedCount = 0;
updateState();
},
};
return instance;
};
// Global scheduler instance
let globalScheduler = null;
export const getGlobalScheduler = () => {
if (!globalScheduler) {
globalScheduler = scheduler();
globalScheduler.start(); // Auto-start global scheduler
}
return globalScheduler;
};
// Convenience functions using global scheduler
export const schedule = (task) => {
const taskId = task.id || `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
return getGlobalScheduler().schedule({ ...task, id: taskId });
};
export const cancel = (taskId) => {
return getGlobalScheduler().cancel(taskId);
};
export const delay = (ms) => {
return new Promise((resolve) => {
schedule({
priority: Priority.NORMAL,
execute: resolve,
delay: ms,
});
});
};
export const nextFrame = () => {
return new Promise((resolve) => {
schedule({
priority: Priority.HIGH,
execute: resolve,
});
});
};
export const idle = (callback) => {
return schedule({
priority: Priority.IDLE,
execute: callback,
});
};
// Animation utilities
export const animate = (duration, callback, easing = (t) => t) => {
const startTime = performance.now();
const taskId = schedule({
priority: Priority.HIGH,
repeat: true,
execute: () => {
const elapsed = performance.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easing(progress);
callback(easedProgress);
if (progress >= 1) {
cancel(taskId);
}
},
});
return taskId;
};
// Debounce utility using scheduler
export const debounce = (fn, delay) => {
let taskId = null;
const debouncedFn = ((...args) => {
if (taskId) {
cancel(taskId);
}
taskId = schedule({
priority: Priority.NORMAL,
delay,
execute: () => fn(...args),
});
});
debouncedFn.cancel = () => {
if (taskId) {
cancel(taskId);
taskId = null;
}
};
return debouncedFn;
};
// Throttle utility using scheduler
export const throttle = (fn, delay) => {
let lastExecution = 0;
let taskId = null;
const throttledFn = ((...args) => {
const now = performance.now();
const timeSinceLastExecution = now - lastExecution;
if (timeSinceLastExecution >= delay) {
lastExecution = now;
fn(...args);
}
else if (!taskId) {
const remainingDelay = delay - timeSinceLastExecution;
taskId = schedule({
priority: Priority.NORMAL,
delay: remainingDelay,
execute: () => {
lastExecution = performance.now();
fn(...args);
taskId = null;
},
});
}
});
throttledFn.cancel = () => {
if (taskId) {
cancel(taskId);
taskId = null;
}
};
return throttledFn;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2NoZWR1bGVyL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQVUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVoRCx1QkFBdUI7QUFDdkIsTUFBTSxDQUFOLElBQVksUUFNWDtBQU5ELFdBQVksUUFBUTtJQUNsQixpREFBYSxDQUFBO0lBQ2IsdUNBQVEsQ0FBQTtJQUNSLDJDQUFVLENBQUE7SUFDVixxQ0FBTyxDQUFBO0lBQ1AsdUNBQVEsQ0FBQTtBQUNWLENBQUMsRUFOVyxRQUFRLEtBQVIsUUFBUSxRQU1uQjtBQThCRCwwQ0FBMEM7QUFDMUMsTUFBTSxTQUFTO0lBSWI7UUFIUSxXQUFNLEdBQTBCLElBQUksR0FBRyxFQUFFLENBQUM7UUFDMUMsWUFBTyxHQUFzQixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBRzdDLDZCQUE2QjtRQUM3QixNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQzNDLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNoQyxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsT0FBTyxDQUFDLElBQVU7UUFDaEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzdDLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2pCLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxD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