Cooperative scheduler for the browser environment that provides time-slicing capabilities for JavaScript applications.
—
Functions for executing code with specific priority contexts and managing priority levels in the scheduler.
Executes a function with a specific priority level, temporarily changing the current priority context.
/**
* Execute a function with a specific priority level
* @param priorityLevel - Priority level to use during execution
* @param eventHandler - Function to execute with the given priority
* @returns The return value of the eventHandler function
*/
function unstable_runWithPriority<T>(
priorityLevel: PriorityLevel,
eventHandler: () => T
): T;Usage Examples:
import {
unstable_runWithPriority,
unstable_UserBlockingPriority,
unstable_LowPriority,
unstable_getCurrentPriorityLevel
} from "scheduler";
// Execute function with high priority
const result = unstable_runWithPriority(unstable_UserBlockingPriority, () => {
console.log("Current priority:", unstable_getCurrentPriorityLevel()); // 2
return "high priority result";
});
// Execute background work with low priority
unstable_runWithPriority(unstable_LowPriority, () => {
// Process non-urgent data
processAnalytics();
updateCache();
});
// Nested priority contexts
unstable_runWithPriority(unstable_UserBlockingPriority, () => {
console.log("Outer priority:", unstable_getCurrentPriorityLevel()); // 2
unstable_runWithPriority(unstable_LowPriority, () => {
console.log("Inner priority:", unstable_getCurrentPriorityLevel()); // 4
});
console.log("Restored priority:", unstable_getCurrentPriorityLevel()); // 2
});Executes a function with lowered priority, shifting high-priority contexts down to Normal priority.
/**
* Execute a function with lowered priority
* Immediate, UserBlocking, and Normal priorities shift down to Normal
* Low and Idle priorities remain unchanged
* @param eventHandler - Function to execute with lowered priority
* @returns The return value of the eventHandler function
*/
function unstable_next<T>(eventHandler: () => T): T;Usage Examples:
import {
unstable_next,
unstable_runWithPriority,
unstable_UserBlockingPriority,
unstable_getCurrentPriorityLevel
} from "scheduler";
// Lowering priority from UserBlocking to Normal
unstable_runWithPriority(unstable_UserBlockingPriority, () => {
console.log("Current priority:", unstable_getCurrentPriorityLevel()); // 2 (UserBlocking)
unstable_next(() => {
console.log("Lowered priority:", unstable_getCurrentPriorityLevel()); // 3 (Normal)
// Perform less urgent work
updateSecondaryUI();
});
console.log("Restored priority:", unstable_getCurrentPriorityLevel()); // 2 (UserBlocking)
});
// Useful for deferring work within high-priority contexts
function handleUserClick() {
unstable_runWithPriority(unstable_UserBlockingPriority, () => {
// Critical UI updates
updateButtonState();
// Defer non-critical work
unstable_next(() => {
// This runs at Normal priority
logAnalytics();
updateRecommendations();
});
});
}Wraps a callback function to preserve the current priority context when the callback is executed later.
/**
* Wrap a callback to preserve current priority context
* @param callback - Function to wrap with current priority context
* @returns Wrapped function that will execute with preserved priority
*/
function unstable_wrapCallback<T>(callback: T): T;Usage Examples:
import {
unstable_wrapCallback,
unstable_runWithPriority,
unstable_UserBlockingPriority,
unstable_getCurrentPriorityLevel
} from "scheduler";
// Preserve priority across async boundaries
function setupEventListener() {
unstable_runWithPriority(unstable_UserBlockingPriority, () => {
const wrappedHandler = unstable_wrapCallback(() => {
console.log("Handler priority:", unstable_getCurrentPriorityLevel()); // 2 (UserBlocking)
handleImportantEvent();
});
// Event will execute with UserBlocking priority even though
// the current context when it fires might be different
element.addEventListener("click", wrappedHandler);
});
}
// Preserve priority in setTimeout
unstable_runWithPriority(unstable_UserBlockingPriority, () => {
const wrappedCallback = unstable_wrapCallback(() => {
console.log("setTimeout priority:", unstable_getCurrentPriorityLevel()); // 2 (UserBlocking)
handleDelayedWork();
});
setTimeout(wrappedCallback, 1000);
});
// Preserve priority in Promise callbacks
function fetchUserData() {
return unstable_runWithPriority(unstable_UserBlockingPriority, () => {
return fetch("/api/user")
.then(unstable_wrapCallback((response) => {
console.log("Promise priority:", unstable_getCurrentPriorityLevel()); // 2 (UserBlocking)
return response.json();
}))
.then(unstable_wrapCallback((userData) => {
console.log("Second promise priority:", unstable_getCurrentPriorityLevel()); // 2 (UserBlocking)
updateUI(userData);
}));
});
}The scheduler maintains a priority context that affects how tasks are scheduled and executed:
unstable_wrapCallback preserves context across async boundaries// High-priority immediate updates
function handleUserInteraction() {
unstable_runWithPriority(unstable_UserBlockingPriority, () => {
updateButtonState();
updateFormValidation();
});
}
// Low-priority background updates
function performBackgroundWork() {
unstable_runWithPriority(unstable_LowPriority, () => {
updateAnalytics();
preloadNextPage();
optimizeCache();
});
}function processUserInput(input) {
unstable_runWithPriority(unstable_UserBlockingPriority, () => {
// Critical: Update UI immediately
updateInputField(input);
validateInput(input);
// Non-critical: Defer to normal priority
unstable_next(() => {
updateSuggestions(input);
logUserBehavior(input);
});
});
}Install with Tessl CLI
npx tessl i tessl/npm-scheduler