Skip to content

Commit

Permalink
refactor(lodash): simplify clamp and debounce utils
Browse files Browse the repository at this point in the history
  • Loading branch information
sadeghbarati authored and idiotWu committed Oct 30, 2022
1 parent 4156225 commit 7d4087e
Show file tree
Hide file tree
Showing 16 changed files with 158 additions and 36 deletions.
22 changes: 0 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@
},
"dependencies": {
"core-js": "^3.6.4",
"lodash.clamp": "^4.0.3",
"lodash.debounce": "^4.0.8",
"tslib": "^1.10.0"
}
}
2 changes: 1 addition & 1 deletion src/decorators/debounce.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import $debounce from 'lodash.debounce';
import { debounce as $debounce } from '../utils';

export function debounce(...options) {
return (_proto: any, key: string, descriptor: PropertyDescriptor) => {
Expand Down
2 changes: 1 addition & 1 deletion src/decorators/range.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import clamp from 'lodash.clamp';
import { clamp } from '../utils';

export function range(min = -Infinity, max = Infinity) {
return (proto: any, key: string) => {
Expand Down
2 changes: 1 addition & 1 deletion src/events/mouse.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import clamp from 'lodash.clamp';
import { clamp } from '../utils';
import * as I from '../interfaces/';

import {
Expand Down
2 changes: 1 addition & 1 deletion src/events/resize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as I from '../interfaces/';
import debounce from 'lodash.debounce';
import { debounce } from '../utils';

import {
eventScope,
Expand Down
2 changes: 1 addition & 1 deletion src/events/select.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import clamp from 'lodash.clamp';
import { clamp } from '../utils';
import * as I from '../interfaces/';

import {
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/overscroll/glow.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import clamp from 'lodash.clamp';
import { clamp } from '../../utils';
import Scrollbar from 'smooth-scrollbar';

import { setStyle } from '../../utils/set-style';
Expand Down
3 changes: 1 addition & 2 deletions src/plugins/overscroll/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import clamp from 'lodash.clamp';
import debounce from 'lodash.debounce';
import { clamp, debounce } from '../../utils';
import { ScrollbarPlugin } from 'smooth-scrollbar';
import { Bounce } from './bounce';
import { Glow } from './glow';
Expand Down
2 changes: 1 addition & 1 deletion src/scrollbar.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import clamp from 'lodash.clamp';
import { clamp } from './utils';

import { Options } from './options';

Expand Down
2 changes: 1 addition & 1 deletion src/scrolling/scroll-into-view.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import clamp from 'lodash.clamp';
import { clamp } from '../utils';

import * as I from '../interfaces/';

Expand Down
2 changes: 1 addition & 1 deletion src/scrolling/scroll-to.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import clamp from 'lodash.clamp';
import { clamp } from '../utils';

import * as I from '../interfaces/';

Expand Down
2 changes: 1 addition & 1 deletion src/scrolling/set-position.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import clamp from 'lodash.clamp';
import { clamp } from '../utils';
import * as I from '../interfaces/';

import {
Expand Down
3 changes: 3 additions & 0 deletions src/utils/clamp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function clamp(value: number, lower: number, upper: number): number {
return Math.max(lower, Math.min(upper, value));
}
142 changes: 142 additions & 0 deletions src/utils/debounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
interface DebounceOptions {
maxWait?: number;
leading?: boolean;
trailing?: boolean;
}

export interface IDebounceReturn {
cancel: () => void;
flush: () => void;
isPending: () => boolean;
}

export interface DebouncedReturn<T extends (...args: any[]) => ReturnType<T>> extends IDebounceReturn {
(...args: Parameters<T>): ReturnType<T> | undefined;
}

export function debounce<T extends (...args: any) => ReturnType<T>>(fn: T, wait?: number, options?: DebounceOptions): DebouncedReturn<T> {

let lastArgs;
let lastThis: unknown;
let timerId;
let lastCallTime;
let lastInvokeTime = 0;
let leading = false;
let maxing = false;
let trailing = true;
let result: ReturnType<T>;

const useRAF = !wait && wait !== 0 && typeof window !== 'undefined' && typeof window.requestAnimationFrame === 'function';

wait = +wait! || 0;
options = options || {};

leading = !!options.leading;
trailing = 'trailing' in options ? !!options.trailing : true;
maxing = 'maxWait' in options;
const maxWait = maxing ? Math.max(+options.maxWait! || 0, wait) : null;

function invokeFunc(time: number) {
const args = lastArgs;
const thisArg = lastThis;

lastArgs = lastThis = null;
lastInvokeTime = time;
result = fn.apply(thisArg, args);
return result;
}

function startTimer(pendingFunc: () => void, wait: number) {
if (useRAF) {
window.cancelAnimationFrame(timerId);
return window.requestAnimationFrame(pendingFunc);
}
return setTimeout(pendingFunc, wait);
}

function cancelTimer(id) {
useRAF ? window.cancelAnimationFrame(id) : clearTimeout(id);
}

function shouldInvoke(time: number) {
const timeSinceLastCall = time - lastCallTime;
const timeSinceLastInvoke = time - lastInvokeTime;

return (
lastCallTime === null ||
timeSinceLastCall >= wait! ||
timeSinceLastCall < 0 ||
(maxing && timeSinceLastInvoke >= maxWait!)
);
}

function timerExpired(): void | ReturnType<any> {
const time = Date.now();
if (shouldInvoke(time)) {
return trailingEdge(time);
}

const timeSinceLastCall = time - lastCallTime;
const timeSinceLastInvoke = time - lastInvokeTime;
const timeWaiting = wait! - timeSinceLastCall;
const remainingWait = maxing ? Math.min(timeWaiting, maxWait! - timeSinceLastInvoke) : timeWaiting;

timerId = startTimer(timerExpired, remainingWait);
}

function trailingEdge(time: number) {
timerId = null;

if (trailing && lastArgs) {
return invokeFunc(time);
}
lastArgs = lastThis = null;
return result;
}

function cancel() {
if (timerId) {
cancelTimer(timerId);
}
lastInvokeTime = 0;
lastArgs = lastCallTime = lastThis = timerId = null;
}

function flush() {
return !timerId ? result : trailingEdge(Date.now());
}

function isPending() {
return !!timerId;
}

function debounced(this: unknown, ...args) {
const time = Date.now();
const isInvoking = shouldInvoke(time);

lastArgs = args;
lastThis = this;
lastCallTime = time;

if (isInvoking) {
if (!timerId) {
lastInvokeTime = time;
timerId = startTimer(timerExpired, wait!);
return leading ? invokeFunc(time) : result;
}
if (maxing) {
timerId = startTimer(timerExpired, wait!);
return invokeFunc(lastCallTime);
}
}
if (!timerId) {
timerId = startTimer(timerExpired, wait!);
}
return result;
}
debounced.cancel = cancel;
debounced.flush = flush;
debounced.isPending = isPending;

return debounced;
}
2 changes: 2 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export * from './get-position';
export * from './is-one-of';
export * from './set-style';
export * from './touch-record';
export { clamp } from './clamp';
export { debounce } from './debounce';

0 comments on commit 7d4087e

Please sign in to comment.