import type {PriorityLevel} from '../SchedulerPriorities';
declare class TaskController {
constructor(options?: {priority?: string}): TaskController;
signal: mixed;
abort(): void;
}
type PostTaskPriorityLevel = 'user-blocking' | 'user-visible' | 'background';
type CallbackNode = {
_controller: TaskController,
};
import {
ImmediatePriority,
UserBlockingPriority,
NormalPriority,
LowPriority,
IdlePriority,
} from '../SchedulerPriorities';
export {
ImmediatePriority as unstable_ImmediatePriority,
UserBlockingPriority as unstable_UserBlockingPriority,
NormalPriority as unstable_NormalPriority,
IdlePriority as unstable_IdlePriority,
LowPriority as unstable_LowPriority,
};
const perf = window.performance;
const setTimeout = window.setTimeout;
const scheduler = global.scheduler;
const getCurrentTime: () => DOMHighResTimeStamp = perf.now.bind(perf);
export const unstable_now = getCurrentTime;
const yieldInterval = 5;
let deadline = 0;
let currentPriorityLevel_DEPRECATED = NormalPriority;
export function unstable_shouldYield(): boolean {
return getCurrentTime() >= deadline;
}
export function unstable_requestPaint() {
}
type SchedulerCallback<T> = (didTimeout_DEPRECATED: boolean) =>
| T
| SchedulerCallback<T>;
export function unstable_scheduleCallback<T>(
priorityLevel: PriorityLevel,
callback: SchedulerCallback<T>,
options?: {delay?: number},
): CallbackNode {
let postTaskPriority;
switch (priorityLevel) {
case ImmediatePriority:
case UserBlockingPriority:
postTaskPriority = 'user-blocking';
break;
case LowPriority:
case NormalPriority:
postTaskPriority = 'user-visible';
break;
case IdlePriority:
postTaskPriority = 'background';
break;
default:
postTaskPriority = 'user-visible';
break;
}
const controller = new TaskController({priority: postTaskPriority});
const postTaskOptions = {
delay: typeof options === 'object' && options !== null ? options.delay : 0,
signal: controller.signal,
};
const node = {
_controller: controller,
};
scheduler
.postTask(
runTask.bind(null, priorityLevel, postTaskPriority, node, callback),
postTaskOptions,
)
.catch(handleAbortError);
return node;
}
function runTask<T>(
priorityLevel: PriorityLevel,
postTaskPriority: PostTaskPriorityLevel,
node: CallbackNode,
callback: SchedulerCallback<T>,
) {
deadline = getCurrentTime() + yieldInterval;
try {
currentPriorityLevel_DEPRECATED = priorityLevel;
const didTimeout_DEPRECATED = false;
const result = callback(didTimeout_DEPRECATED);
if (typeof result === 'function') {
const continuation: SchedulerCallback<T> = (result: any);
const continuationOptions = {
signal: node._controller.signal,
};
const nextTask = runTask.bind(
null,
priorityLevel,
postTaskPriority,
node,
continuation,
);
if (scheduler.yield !== undefined) {
scheduler
.yield(continuationOptions)
.then(nextTask)
.catch(handleAbortError);
} else {
scheduler
.postTask(nextTask, continuationOptions)
.catch(handleAbortError);
}
}
} catch (error) {
setTimeout(() => {
throw error;
});
} finally {
currentPriorityLevel_DEPRECATED = NormalPriority;
}
}
function handleAbortError(error: any) {
}
export function unstable_cancelCallback(node: CallbackNode) {
const controller = node._controller;
controller.abort();
}
export function unstable_runWithPriority<T>(
priorityLevel: PriorityLevel,
callback: () => T,
): T {
const previousPriorityLevel = currentPriorityLevel_DEPRECATED;
currentPriorityLevel_DEPRECATED = priorityLevel;
try {
return callback();
} finally {
currentPriorityLevel_DEPRECATED = previousPriorityLevel;
}
}
export function unstable_getCurrentPriorityLevel(): PriorityLevel {
return currentPriorityLevel_DEPRECATED;
}
export function unstable_next<T>(callback: () => T): T {
let priorityLevel;
switch (currentPriorityLevel_DEPRECATED) {
case ImmediatePriority:
case UserBlockingPriority:
case NormalPriority:
priorityLevel = NormalPriority;
break;
default:
priorityLevel = currentPriorityLevel_DEPRECATED;
break;
}
const previousPriorityLevel = currentPriorityLevel_DEPRECATED;
currentPriorityLevel_DEPRECATED = priorityLevel;
try {
return callback();
} finally {
currentPriorityLevel_DEPRECATED = previousPriorityLevel;
}
}
export function unstable_wrapCallback<T>(callback: () => T): () => T {
const parentPriorityLevel = currentPriorityLevel_DEPRECATED;
return () => {
const previousPriorityLevel = currentPriorityLevel_DEPRECATED;
currentPriorityLevel_DEPRECATED = parentPriorityLevel;
try {
return callback();
} finally {
currentPriorityLevel_DEPRECATED = previousPriorityLevel;
}
};
}
export function unstable_forceFrameRate() {}
export function unstable_pauseExecution() {}
export function unstable_continueExecution() {}
export function unstable_getFirstCallbackNode(): null {
return null;
}
export const unstable_Profiling = null;