typedash
Version:
modern, type-safe collection of utility functions
1 lines • 4.07 kB
Source Map (JSON)
{"version":3,"file":"throttle-KF7yjFgX.cjs","names":[],"sources":["../src/functions/throttle/throttle.ts"],"sourcesContent":["import type { AnyFunction } from '../../types/_internal';\n\ninterface ThrottleOptions {\n /**\n * Specify invoking on the leading edge of the timeout.\n * @default true\n */\n leading?: boolean;\n /**\n * Specify invoking on the trailing edge of the timeout.\n * @default true\n */\n trailing?: boolean;\n}\n\n/**\n * Creates a throttled function that limits the rate at which it can be called.\n * @param func The function to be throttled.\n * @param wait The number of milliseconds to wait between each invocation of the function.\n * @param options The options for the throttling behavior.\n * @param options.leading Whether to call the function on the leading edge of the timeout.\n * @param options.trailing Whether to call the function on the trailing edge of the timeout.\n * @returns The throttled function with `cancel` and `flush` methods.\n */\nexport function throttle<TFunction extends AnyFunction>(\n func: TFunction,\n wait = 0,\n options: ThrottleOptions = {}\n): ThrottledFunction<TFunction> {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n let lastArguments: Parameters<TFunction> | null = null;\n let lastContext: ThisParameterType<TFunction> | null = null;\n let lastInvokeTime = 0;\n\n const { leading = true, trailing = true } = options;\n\n function invokeFunc(time: number) {\n lastInvokeTime = time;\n func.apply(lastContext, lastArguments ?? []);\n lastContext = null;\n lastArguments = null;\n }\n\n function trailingEdge() {\n if (trailing && lastArguments) {\n invokeFunc(Date.now());\n }\n timeoutId = null;\n }\n\n function timerExpired() {\n const time = Date.now();\n if (time - lastInvokeTime >= wait) {\n trailingEdge();\n } else {\n timeoutId = setTimeout(timerExpired, wait - (time - lastInvokeTime));\n }\n }\n\n function throttledFunction(\n this: ThisParameterType<TFunction>,\n ...args: Parameters<TFunction>\n ) {\n const time = Date.now();\n if (!lastInvokeTime && !leading) {\n lastInvokeTime = time;\n }\n\n const remaining = wait - (time - lastInvokeTime);\n lastArguments = args;\n lastContext = this;\n\n if (remaining <= 0 || remaining > wait) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n invokeFunc(time);\n } else if (!timeoutId && trailing) {\n timeoutId = setTimeout(timerExpired, remaining);\n }\n }\n\n throttledFunction.cancel = () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n lastInvokeTime = 0;\n lastArguments = null;\n lastContext = null;\n timeoutId = null;\n };\n\n throttledFunction.flush = () => {\n if (timeoutId) {\n invokeFunc(Date.now());\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n\n return throttledFunction;\n}\n\ninterface ThrottledFunction<TFunction extends AnyFunction> {\n (...args: Parameters<TFunction>): void;\n cancel: () => void;\n flush: () => void;\n}\n"],"mappings":";;;;;;;;;;;AAwBA,SAAgB,SACd,MACA,OAAO,GACP,UAA2B,EAAE,EACC;CAC9B,IAAI,YAAkD;CACtD,IAAI,gBAA8C;CAClD,IAAI,cAAmD;CACvD,IAAI,iBAAiB;CAErB,MAAM,EAAE,UAAU,MAAM,WAAW,SAAS;CAE5C,SAAS,WAAW,MAAc;AAChC,mBAAiB;AACjB,OAAK,MAAM,aAAa,iBAAiB,EAAE,CAAC;AAC5C,gBAAc;AACd,kBAAgB;;CAGlB,SAAS,eAAe;AACtB,MAAI,YAAY,cACd,YAAW,KAAK,KAAK,CAAC;AAExB,cAAY;;CAGd,SAAS,eAAe;EACtB,MAAM,OAAO,KAAK,KAAK;AACvB,MAAI,OAAO,kBAAkB,KAC3B,eAAc;MAEd,aAAY,WAAW,cAAc,QAAQ,OAAO,gBAAgB;;CAIxE,SAAS,kBAEP,GAAG,MACH;EACA,MAAM,OAAO,KAAK,KAAK;AACvB,MAAI,CAAC,kBAAkB,CAAC,QACtB,kBAAiB;EAGnB,MAAM,YAAY,QAAQ,OAAO;AACjC,kBAAgB;AAChB,gBAAc;AAEd,MAAI,aAAa,KAAK,YAAY,MAAM;AACtC,OAAI,WAAW;AACb,iBAAa,UAAU;AACvB,gBAAY;;AAEd,cAAW,KAAK;aACP,CAAC,aAAa,SACvB,aAAY,WAAW,cAAc,UAAU;;AAInD,mBAAkB,eAAe;AAC/B,MAAI,UACF,cAAa,UAAU;AAEzB,mBAAiB;AACjB,kBAAgB;AAChB,gBAAc;AACd,cAAY;;AAGd,mBAAkB,cAAc;AAC9B,MAAI,WAAW;AACb,cAAW,KAAK,KAAK,CAAC;AACtB,gBAAa,UAAU;AACvB,eAAY;;;AAIhB,QAAO"}