Primitives for creating scheduled — throttled or debounced — callbacks.
npx @tessl/cli install tessl/npm-solid-primitives--scheduled@1.5.0Solid Primitives Scheduled provides comprehensive SolidJS primitives for creating scheduled callbacks including debounce, throttle, leading edge schedulers, and idle-time scheduling capabilities. All functions integrate seamlessly with SolidJS's reactive system and lifecycle management, automatically clearing timeouts on root disposal.
npm install @solid-primitives/scheduledimport {
debounce,
throttle,
scheduleIdle,
leading,
leadingAndTrailing,
createScheduled,
type ScheduleCallback,
type Scheduled
} from "@solid-primitives/scheduled";For individual imports:
import { debounce } from "@solid-primitives/scheduled";
import { throttle } from "@solid-primitives/scheduled";
import { type Scheduled } from "@solid-primitives/scheduled";import { debounce, throttle, createScheduled } from "@solid-primitives/scheduled";
import { createEffect, createSignal } from "solid-js";
// Basic debouncing
const debouncedFn = debounce((message: string) => console.log(message), 250);
debouncedFn("Hello!");
debouncedFn.clear(); // Cancel pending execution
// Basic throttling
const throttledFn = throttle((value: number) => console.log(value), 100);
throttledFn(42);
throttledFn.clear(); // Cancel pending execution
// Reactive scheduling with createScheduled
const scheduled = createScheduled(fn => debounce(fn, 1000));
const [count, setCount] = createSignal(0);
createEffect(() => {
const value = count();
if (scheduled()) {
console.log("Debounced count:", value);
}
});The package is built around several key concepts:
onCleanup() when reactive roots are disposed.clear() methods for manual cancellationCreates a debounced callback that executes on the trailing edge after the specified delay.
/**
* Creates a callback that is debounced and cancellable. The debounced callback is called on trailing edge.
* The timeout will be automatically cleared on root dispose.
*/
function debounce<Args extends unknown[]>(
callback: (...args: Args) => void,
wait?: number
): Scheduled<Args>;Usage Examples:
import { debounce } from "@solid-primitives/scheduled";
// Basic debouncing
const handleSearch = debounce((query: string) => {
console.log("Searching for:", query);
}, 300);
handleSearch("react");
handleSearch("solid"); // Only this will execute after 300ms
// Manual cancellation
handleSearch("typescript");
handleSearch.clear(); // Cancels the pending searchCreates a throttled callback that executes on the trailing edge at most once per interval.
/**
* Creates a callback that is throttled and cancellable. The throttled callback is called on trailing edge.
* The timeout will be automatically cleared on root dispose.
*/
function throttle<Args extends unknown[]>(
callback: (...args: Args) => void,
wait?: number
): Scheduled<Args>;Usage Examples:
import { throttle } from "@solid-primitives/scheduled";
// Throttle scroll events
const handleScroll = throttle((event: Event) => {
console.log("Scroll position:", window.scrollY);
}, 100);
window.addEventListener("scroll", handleScroll);
// Manual cancellation
handleScroll.clear();Creates a callback throttled using requestIdleCallback() for browser idle-time execution. Falls back to throttle when requestIdleCallback is unavailable (Safari).
/**
* Creates a callback throttled using `window.requestIdleCallback()`.
* The throttled callback is called on trailing edge.
* The timeout will be automatically cleared on root dispose.
*/
function scheduleIdle<Args extends unknown[]>(
callback: (...args: Args) => void,
maxWait?: number
): Scheduled<Args>;Usage Examples:
import { scheduleIdle } from "@solid-primitives/scheduled";
// Schedule non-critical work during idle time
const processAnalytics = scheduleIdle((data: AnalyticsData) => {
console.log("Processing analytics:", data);
}, 250); // Maximum 250ms wait
processAnalytics(userData);
processAnalytics.clear(); // Cancel pending workCreates a scheduled callback that executes on the leading edge (immediately on first call).
/**
* Creates a scheduled and cancellable callback that will be called on leading edge.
* The timeout will be automatically cleared on root dispose.
*/
function leading<Args extends unknown[]>(
schedule: ScheduleCallback,
callback: (...args: Args) => void,
wait?: number
): Scheduled<Args>;Usage Examples:
import { leading, debounce, throttle } from "@solid-primitives/scheduled";
// Leading debounce - executes immediately, then waits
const leadingDebounce = leading(debounce, (message: string) => {
console.log("Immediate:", message);
}, 1000);
leadingDebounce("First"); // Executes immediately
leadingDebounce("Second"); // Ignored during wait period
// Leading throttle - executes immediately, then at intervals
const leadingThrottle = leading(throttle, (count: number) => {
console.log("Count:", count);
}, 500);Creates a scheduled callback that executes on the leading edge for the first call and trailing edge for subsequent calls.
/**
* Creates a scheduled and cancellable callback that will be called on the leading edge
* for the first call, and trailing edge thereafter.
* The timeout will be automatically cleared on root dispose.
*/
function leadingAndTrailing<Args extends unknown[]>(
schedule: ScheduleCallback,
callback: (...args: Args) => void,
wait?: number
): Scheduled<Args>;Usage Examples:
import { leadingAndTrailing, debounce } from "@solid-primitives/scheduled";
// Executes immediately on first call, then debounced
const smartSave = leadingAndTrailing(debounce, (data: FormData) => {
console.log("Saving:", data);
}, 2000);
smartSave(formData1); // Executes immediately (leading)
smartSave(formData2); // Waits for trailing edge
smartSave(formData3); // Waits for trailing edge (only final call executes)Creates a signal for scheduling execution of solid computations by tracking.
/**
* Creates a signal used for scheduling execution of solid computations by tracking.
*/
function createScheduled(
schedule: (callback: VoidFunction) => VoidFunction
): Accessor<boolean>;Usage Examples:
import { createScheduled, debounce } from "@solid-primitives/scheduled";
import { createEffect, createSignal, createMemo } from "solid-js";
// With createEffect
const debouncedSignal = createScheduled(fn => debounce(fn, 500));
const [value, setValue] = createSignal(0);
createEffect(() => {
const currentValue = value();
if (debouncedSignal()) {
console.log("Debounced value:", currentValue);
}
});
// With createMemo for transformed values
const debouncedValue = createMemo((prev: number = 0) => {
const currentValue = value();
return debouncedSignal() ? currentValue : prev;
});
// With different schedulers
const throttledSignal = createScheduled(fn => throttle(fn, 100));
const leadingSignal = createScheduled(fn => leading(debounce, fn, 1000));/**
* Generic type for schedule callback functions
*/
type ScheduleCallback = <Args extends unknown[]>(
callback: (...args: Args) => void,
wait?: number
) => Scheduled<Args>;
/**
* Interface for scheduled callback functions with clear method
*/
interface Scheduled<Args extends unknown[]> {
/** The scheduled callback function */
(...args: Args): void;
/** Method to cancel pending timeout */
clear: VoidFunction;
}All functions provide safe server-side rendering support:
isServer is truerequestIdleCallback: scheduleIdle gracefully falls back to throttle in browsers without support (Safari)setTimeout/clearTimeout: Full support across all modern browsers