Socket
Socket
Sign inDemoInstall

@restart/hooks

Package Overview
Dependencies
Maintainers
3
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@restart/hooks - npm Package Compare versions

Comparing version 0.4.11 to 0.4.12

12

cjs/useDebouncedCallback.d.ts

@@ -0,8 +1,14 @@

export interface UseDebouncedCallbackOptions {
wait: number;
leading?: boolean;
trailing?: boolean;
maxWait?: number;
}
/**
* Creates a debounced function that will invoke the input function after the
* specified delay.
* specified wait.
*
* @param fn a function that will be debounced
* @param delay The milliseconds delay before invoking the function
* @param waitOrOptions a wait in milliseconds or a debounce configuration
*/
export default function useDebouncedCallback<TCallback extends (...args: any[]) => any>(fn: TCallback, delay: number): (...args: Parameters<TCallback>) => void;
export default function useDebouncedCallback<TCallback extends (...args: any[]) => any>(fn: TCallback, waitOrOptions: number | UseDebouncedCallbackOptions): (...args: Parameters<TCallback>) => void;

@@ -10,14 +10,98 @@ "use strict";

* Creates a debounced function that will invoke the input function after the
* specified delay.
* specified wait.
*
* @param fn a function that will be debounced
* @param delay The milliseconds delay before invoking the function
* @param waitOrOptions a wait in milliseconds or a debounce configuration
*/
function useDebouncedCallback(fn, delay) {
function useDebouncedCallback(fn, waitOrOptions) {
const lastCallTimeRef = (0, _react.useRef)(null);
const lastInvokeTimeRef = (0, _react.useRef)(0);
const isTimerSetRef = (0, _react.useRef)(false);
const lastArgsRef = (0, _react.useRef)(null);
const {
wait,
maxWait,
leading = false,
trailing = true
} = typeof waitOrOptions === 'number' ? {
wait: waitOrOptions
} : waitOrOptions;
const timeout = (0, _useTimeout.default)();
return (0, _react.useCallback)((...args) => {
timeout.set(() => {
fn(...args);
}, delay);
}, [fn, delay]);
return (0, _react.useMemo)(() => {
const hasMaxWait = !!maxWait;
function leadingEdge(time) {
// Reset any `maxWait` timer.
lastInvokeTimeRef.current = time;
// Start the timer for the trailing edge.
isTimerSetRef.current = true;
timeout.set(timerExpired, wait);
// Invoke the leading edge.
if (leading) {
invokeFunc(time);
}
}
function trailingEdge(time) {
isTimerSetRef.current = false;
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
if (trailing && lastArgsRef.current) {
return invokeFunc(time);
}
lastArgsRef.current = null;
}
function timerExpired() {
var _lastCallTimeRef$curr;
var time = Date.now();
if (shouldInvoke(time)) {
return trailingEdge(time);
}
const timeSinceLastCall = time - ((_lastCallTimeRef$curr = lastCallTimeRef.current) != null ? _lastCallTimeRef$curr : 0);
const timeSinceLastInvoke = time - lastInvokeTimeRef.current;
const timeWaiting = wait - timeSinceLastCall;
// Restart the timer.
timeout.set(timerExpired, hasMaxWait ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting);
}
function invokeFunc(time) {
var _lastArgsRef$current;
const args = (_lastArgsRef$current = lastArgsRef.current) != null ? _lastArgsRef$current : [];
lastArgsRef.current = null;
lastInvokeTimeRef.current = time;
return fn(...args);
}
function shouldInvoke(time) {
var _lastCallTimeRef$curr2;
const timeSinceLastCall = time - ((_lastCallTimeRef$curr2 = lastCallTimeRef.current) != null ? _lastCallTimeRef$curr2 : 0);
const timeSinceLastInvoke = time - lastInvokeTimeRef.current;
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
return lastCallTimeRef.current === null || timeSinceLastCall >= wait || timeSinceLastCall < 0 || hasMaxWait && timeSinceLastInvoke >= maxWait;
}
return (...args) => {
const time = Date.now();
const isInvoking = shouldInvoke(time);
lastArgsRef.current = args;
lastCallTimeRef.current = time;
if (isInvoking) {
if (!isTimerSetRef.current) {
return leadingEdge(lastCallTimeRef.current);
}
if (hasMaxWait) {
// Handle invocations in a tight loop.
isTimerSetRef.current = true;
setTimeout(timerExpired, wait);
return invokeFunc(lastCallTimeRef.current);
}
}
if (!isTimerSetRef.current) {
isTimerSetRef.current = true;
setTimeout(timerExpired, wait);
}
};
}, [fn, wait, maxWait, leading, trailing]);
}
import { Dispatch, SetStateAction } from 'react';
import { UseDebouncedCallbackOptions } from './useDebouncedCallback';
/**

@@ -13,4 +14,4 @@ * Similar to `useState`, except the setter function is debounced by

* @param initialState initial state value
* @param delay The milliseconds delay before a new value is set
* @param delayOrOptions The milliseconds delay before a new value is set, or options object
*/
export default function useDebouncedState<T>(initialState: T, delay: number): [T, Dispatch<SetStateAction<T>>];
export default function useDebouncedState<T>(initialState: T, delayOrOptions: number | UseDebouncedCallbackOptions): [T, Dispatch<SetStateAction<T>>];

@@ -19,8 +19,8 @@ "use strict";

* @param initialState initial state value
* @param delay The milliseconds delay before a new value is set
* @param delayOrOptions The milliseconds delay before a new value is set, or options object
*/
function useDebouncedState(initialState, delay) {
function useDebouncedState(initialState, delayOrOptions) {
const [state, setState] = (0, _react.useState)(initialState);
const debouncedSetState = (0, _useDebouncedCallback.default)(setState, delay);
const debouncedSetState = (0, _useDebouncedCallback.default)(setState, delayOrOptions);
return [state, debouncedSetState];
}

@@ -0,1 +1,5 @@

import { UseDebouncedCallbackOptions } from './useDebouncedCallback';
export type UseDebouncedValueOptions = UseDebouncedCallbackOptions & {
isEqual?: (a: any, b: any) => boolean;
};
/**

@@ -7,6 +11,6 @@ * Debounce a value change by a specified number of milliseconds. Useful

* @param value
* @param delayMs
* @param waitOrOptions
* @returns
*/
declare function useDebouncedValue<TValue>(value: TValue, delayMs?: number): TValue;
declare function useDebouncedValue<TValue>(value: TValue, waitOrOptions?: number | UseDebouncedValueOptions): TValue;
export default useDebouncedValue;

@@ -8,2 +8,3 @@ "use strict";

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const defaultIsEqual = (a, b) => a === b;
/**

@@ -15,11 +16,16 @@ * Debounce a value change by a specified number of milliseconds. Useful

* @param value
* @param delayMs
* @param waitOrOptions
* @returns
*/
function useDebouncedValue(value, delayMs = 500) {
const [debouncedValue, setDebouncedValue] = (0, _useDebouncedState.default)(value, delayMs);
function useDebouncedValue(value, waitOrOptions = 500) {
const previousValueRef = (0, _react.useRef)(value);
const isEqual = typeof waitOrOptions === 'object' ? waitOrOptions.isEqual || defaultIsEqual : defaultIsEqual;
const [debouncedValue, setDebouncedValue] = (0, _useDebouncedState.default)(value, waitOrOptions);
(0, _react.useDebugValue)(debouncedValue);
(0, _react.useEffect)(() => {
setDebouncedValue(value);
}, [value, delayMs]);
if (!isEqual || !isEqual(previousValueRef.current, value)) {
previousValueRef.current = value;
setDebouncedValue(value);
}
});
return debouncedValue;

@@ -26,0 +32,0 @@ }

@@ -0,1 +1,2 @@

import { MutableRefObject } from 'react';
/**

@@ -22,2 +23,3 @@ * Returns a controller object for setting a timeout that is properly cleaned up

clear: () => void;
handleRef: MutableRefObject<any>;
};

@@ -61,5 +61,6 @@ "use strict";

set,
clear
clear,
handleRef
};
}, []);
}

@@ -0,8 +1,14 @@

export interface UseDebouncedCallbackOptions {
wait: number;
leading?: boolean;
trailing?: boolean;
maxWait?: number;
}
/**
* Creates a debounced function that will invoke the input function after the
* specified delay.
* specified wait.
*
* @param fn a function that will be debounced
* @param delay The milliseconds delay before invoking the function
* @param waitOrOptions a wait in milliseconds or a debounce configuration
*/
export default function useDebouncedCallback<TCallback extends (...args: any[]) => any>(fn: TCallback, delay: number): (...args: Parameters<TCallback>) => void;
export default function useDebouncedCallback<TCallback extends (...args: any[]) => any>(fn: TCallback, waitOrOptions: number | UseDebouncedCallbackOptions): (...args: Parameters<TCallback>) => void;

@@ -1,18 +0,101 @@

import { useCallback } from 'react';
import { useMemo, useRef } from 'react';
import useTimeout from './useTimeout';
/**
* Creates a debounced function that will invoke the input function after the
* specified delay.
* specified wait.
*
* @param fn a function that will be debounced
* @param delay The milliseconds delay before invoking the function
* @param waitOrOptions a wait in milliseconds or a debounce configuration
*/
export default function useDebouncedCallback(fn, delay) {
export default function useDebouncedCallback(fn, waitOrOptions) {
const lastCallTimeRef = useRef(null);
const lastInvokeTimeRef = useRef(0);
const isTimerSetRef = useRef(false);
const lastArgsRef = useRef(null);
const {
wait,
maxWait,
leading = false,
trailing = true
} = typeof waitOrOptions === 'number' ? {
wait: waitOrOptions
} : waitOrOptions;
const timeout = useTimeout();
return useCallback((...args) => {
timeout.set(() => {
fn(...args);
}, delay);
}, [fn, delay]);
return useMemo(() => {
const hasMaxWait = !!maxWait;
function leadingEdge(time) {
// Reset any `maxWait` timer.
lastInvokeTimeRef.current = time;
// Start the timer for the trailing edge.
isTimerSetRef.current = true;
timeout.set(timerExpired, wait);
// Invoke the leading edge.
if (leading) {
invokeFunc(time);
}
}
function trailingEdge(time) {
isTimerSetRef.current = false;
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
if (trailing && lastArgsRef.current) {
return invokeFunc(time);
}
lastArgsRef.current = null;
}
function timerExpired() {
var _lastCallTimeRef$curr;
var time = Date.now();
if (shouldInvoke(time)) {
return trailingEdge(time);
}
const timeSinceLastCall = time - ((_lastCallTimeRef$curr = lastCallTimeRef.current) != null ? _lastCallTimeRef$curr : 0);
const timeSinceLastInvoke = time - lastInvokeTimeRef.current;
const timeWaiting = wait - timeSinceLastCall;
// Restart the timer.
timeout.set(timerExpired, hasMaxWait ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting);
}
function invokeFunc(time) {
var _lastArgsRef$current;
const args = (_lastArgsRef$current = lastArgsRef.current) != null ? _lastArgsRef$current : [];
lastArgsRef.current = null;
lastInvokeTimeRef.current = time;
return fn(...args);
}
function shouldInvoke(time) {
var _lastCallTimeRef$curr2;
const timeSinceLastCall = time - ((_lastCallTimeRef$curr2 = lastCallTimeRef.current) != null ? _lastCallTimeRef$curr2 : 0);
const timeSinceLastInvoke = time - lastInvokeTimeRef.current;
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
return lastCallTimeRef.current === null || timeSinceLastCall >= wait || timeSinceLastCall < 0 || hasMaxWait && timeSinceLastInvoke >= maxWait;
}
return (...args) => {
const time = Date.now();
const isInvoking = shouldInvoke(time);
lastArgsRef.current = args;
lastCallTimeRef.current = time;
if (isInvoking) {
if (!isTimerSetRef.current) {
return leadingEdge(lastCallTimeRef.current);
}
if (hasMaxWait) {
// Handle invocations in a tight loop.
isTimerSetRef.current = true;
setTimeout(timerExpired, wait);
return invokeFunc(lastCallTimeRef.current);
}
}
if (!isTimerSetRef.current) {
isTimerSetRef.current = true;
setTimeout(timerExpired, wait);
}
};
}, [fn, wait, maxWait, leading, trailing]);
}
import { Dispatch, SetStateAction } from 'react';
import { UseDebouncedCallbackOptions } from './useDebouncedCallback';
/**

@@ -13,4 +14,4 @@ * Similar to `useState`, except the setter function is debounced by

* @param initialState initial state value
* @param delay The milliseconds delay before a new value is set
* @param delayOrOptions The milliseconds delay before a new value is set, or options object
*/
export default function useDebouncedState<T>(initialState: T, delay: number): [T, Dispatch<SetStateAction<T>>];
export default function useDebouncedState<T>(initialState: T, delayOrOptions: number | UseDebouncedCallbackOptions): [T, Dispatch<SetStateAction<T>>];

@@ -15,8 +15,8 @@ import { useState } from 'react';

* @param initialState initial state value
* @param delay The milliseconds delay before a new value is set
* @param delayOrOptions The milliseconds delay before a new value is set, or options object
*/
export default function useDebouncedState(initialState, delay) {
export default function useDebouncedState(initialState, delayOrOptions) {
const [state, setState] = useState(initialState);
const debouncedSetState = useDebouncedCallback(setState, delay);
const debouncedSetState = useDebouncedCallback(setState, delayOrOptions);
return [state, debouncedSetState];
}

@@ -0,1 +1,5 @@

import { UseDebouncedCallbackOptions } from './useDebouncedCallback';
export type UseDebouncedValueOptions = UseDebouncedCallbackOptions & {
isEqual?: (a: any, b: any) => boolean;
};
/**

@@ -7,6 +11,6 @@ * Debounce a value change by a specified number of milliseconds. Useful

* @param value
* @param delayMs
* @param waitOrOptions
* @returns
*/
declare function useDebouncedValue<TValue>(value: TValue, delayMs?: number): TValue;
declare function useDebouncedValue<TValue>(value: TValue, waitOrOptions?: number | UseDebouncedValueOptions): TValue;
export default useDebouncedValue;

@@ -1,4 +0,4 @@

import { useEffect, useDebugValue } from 'react';
import { useEffect, useDebugValue, useRef } from 'react';
import useDebouncedState from './useDebouncedState';
const defaultIsEqual = (a, b) => a === b;
/**

@@ -10,13 +10,18 @@ * Debounce a value change by a specified number of milliseconds. Useful

* @param value
* @param delayMs
* @param waitOrOptions
* @returns
*/
function useDebouncedValue(value, delayMs = 500) {
const [debouncedValue, setDebouncedValue] = useDebouncedState(value, delayMs);
function useDebouncedValue(value, waitOrOptions = 500) {
const previousValueRef = useRef(value);
const isEqual = typeof waitOrOptions === 'object' ? waitOrOptions.isEqual || defaultIsEqual : defaultIsEqual;
const [debouncedValue, setDebouncedValue] = useDebouncedState(value, waitOrOptions);
useDebugValue(debouncedValue);
useEffect(() => {
setDebouncedValue(value);
}, [value, delayMs]);
if (!isEqual || !isEqual(previousValueRef.current, value)) {
previousValueRef.current = value;
setDebouncedValue(value);
}
});
return debouncedValue;
}
export default useDebouncedValue;

@@ -0,1 +1,2 @@

import { MutableRefObject } from 'react';
/**

@@ -22,2 +23,3 @@ * Returns a controller object for setting a timeout that is properly cleaned up

clear: () => void;
handleRef: MutableRefObject<any>;
};

@@ -57,5 +57,6 @@ import { useMemo, useRef } from 'react';

set,
clear
clear,
handleRef
};
}, []);
}
{
"name": "@restart/hooks",
"version": "0.4.11",
"version": "0.4.12",
"main": "cjs/index.js",

@@ -5,0 +5,0 @@ "types": "cjs/index.d.ts",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc