@avatijs/debounce 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +135 -217
- package/dist/cjs/index.js +368 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.min.js +7 -0
- package/dist/cjs/index.min.js.map +1 -0
- package/dist/esm/index.js +353 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +7 -0
- package/dist/esm/index.min.js.map +1 -0
- package/dist/types/debouce.d.ts +1 -0
- package/dist/types/debouce.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/umd/index.js +378 -2
- package/dist/umd/index.js.map +1 -1
- package/dist/umd/index.min.js +8 -0
- package/dist/umd/index.min.js.map +1 -0
- package/package.json +12 -5
- package/dist/debouce.d.ts +0 -72
- package/dist/index.d.ts +0 -1
package/dist/cjs/index.js
CHANGED
@@ -1,7 +1,373 @@
|
|
1
1
|
/*!
|
2
|
-
* @avatijs/debounce 0.1.
|
2
|
+
* @avatijs/debounce 0.1.3
|
3
3
|
* Copyright (c) 2024 Khaled Sameer <khaled.smq@hotmail.com>
|
4
4
|
* Licensed under MIT, https://opensource.org/licenses/MIT/
|
5
5
|
* Please visit https://avati.io/ for details.
|
6
|
-
*/
|
6
|
+
*/
|
7
|
+
|
8
|
+
/* eslint-disable */
|
9
|
+
|
10
|
+
/******/ (() => { // webpackBootstrap
|
11
|
+
/******/ "use strict";
|
12
|
+
/******/ // The require scope
|
13
|
+
/******/ var __webpack_require__ = {};
|
14
|
+
/******/
|
15
|
+
/************************************************************************/
|
16
|
+
/******/ /* webpack/runtime/define property getters */
|
17
|
+
/******/ (() => {
|
18
|
+
/******/ // define getter functions for harmony exports
|
19
|
+
/******/ __webpack_require__.d = (exports, definition) => {
|
20
|
+
/******/ for(var key in definition) {
|
21
|
+
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
22
|
+
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
23
|
+
/******/ }
|
24
|
+
/******/ }
|
25
|
+
/******/ };
|
26
|
+
/******/ })();
|
27
|
+
/******/
|
28
|
+
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
29
|
+
/******/ (() => {
|
30
|
+
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
31
|
+
/******/ })();
|
32
|
+
/******/
|
33
|
+
/******/ /* webpack/runtime/make namespace object */
|
34
|
+
/******/ (() => {
|
35
|
+
/******/ // define __esModule on exports
|
36
|
+
/******/ __webpack_require__.r = (exports) => {
|
37
|
+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
38
|
+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
39
|
+
/******/ }
|
40
|
+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
41
|
+
/******/ };
|
42
|
+
/******/ })();
|
43
|
+
/******/
|
44
|
+
/************************************************************************/
|
45
|
+
var __webpack_exports__ = {};
|
46
|
+
// ESM COMPAT FLAG
|
47
|
+
__webpack_require__.r(__webpack_exports__);
|
48
|
+
|
49
|
+
// EXPORTS
|
50
|
+
__webpack_require__.d(__webpack_exports__, {
|
51
|
+
debounce: () => (/* reexport */ debounce)
|
52
|
+
});
|
53
|
+
|
54
|
+
;// ./src/debouce.ts
|
55
|
+
/**
|
56
|
+
* Advanced debounce utility with TypeScript support
|
57
|
+
* Provides a way to limit the rate at which a function can fire by delaying its execution
|
58
|
+
* until after a specified amount of time has elapsed since its last invocation.
|
59
|
+
* @module debounce
|
60
|
+
*/
|
61
|
+
/** WeakMap to store private state for each debounced function */
|
62
|
+
const privateState = new WeakMap();
|
63
|
+
/**
|
64
|
+
* Creates a logger instance based on debug flag
|
65
|
+
* @param debug - Whether debug logging is enabled
|
66
|
+
* @returns Object with logging methods
|
67
|
+
* @private
|
68
|
+
*/
|
69
|
+
const createLogger = (debug) => ({
|
70
|
+
log: (...args) => debug && console.log('[Debounce]', ...args),
|
71
|
+
warn: (...args) => debug && console.warn('[Debounce]', ...args),
|
72
|
+
error: (...args) => debug && console.error('[Debounce]', ...args),
|
73
|
+
});
|
74
|
+
/**
|
75
|
+
* Creates a debounced version of the provided function that delays invoking func until after
|
76
|
+
* wait milliseconds have elapsed since the last time the debounced function was invoked.
|
77
|
+
*
|
78
|
+
* @template T - The type of the function to debounce
|
79
|
+
* @param {T} func - The function to debounce
|
80
|
+
* @param {DebounceOptions} [options={}] - Configuration options
|
81
|
+
* @returns {DebouncedFunction<T>} The debounced function
|
82
|
+
* @throws {TypeError} If func is not a function
|
83
|
+
* @throws {RangeError} If wait or maxWait values are invalid
|
84
|
+
* @throws {Error} If neither leading nor trailing is true
|
85
|
+
*
|
86
|
+
* @example
|
87
|
+
* const debouncedFn = debounce(async (x: number) => x * 2, { wait: 1000 });
|
88
|
+
* await debouncedFn(5); // Will execute after 1000ms of inactivity
|
89
|
+
* const debouncedFn = debounce(
|
90
|
+
* async (x: number) => x * 2,
|
91
|
+
* {
|
92
|
+
* wait: 1000,
|
93
|
+
* onError: (error) => console.error('Error in debounced function:', error)
|
94
|
+
* }
|
95
|
+
* );
|
96
|
+
*/
|
97
|
+
function debounce(func, options = {}) {
|
98
|
+
// Input validation
|
99
|
+
if (typeof func !== 'function') {
|
100
|
+
throw new TypeError('Expected a function');
|
101
|
+
}
|
102
|
+
const { wait = 0, leading = false, trailing = true, maxWait, debug = false, signal, onError, } = options;
|
103
|
+
// Validate options
|
104
|
+
if (wait < 0 || (maxWait !== undefined && maxWait < wait)) {
|
105
|
+
throw new RangeError('Invalid wait/maxWait values');
|
106
|
+
}
|
107
|
+
if (!leading && !trailing) {
|
108
|
+
throw new Error('At least one of leading or trailing must be true');
|
109
|
+
}
|
110
|
+
const logger = createLogger(debug);
|
111
|
+
const state = {
|
112
|
+
lastInvokeTime: 0,
|
113
|
+
pendingPromises: [],
|
114
|
+
aborted: false,
|
115
|
+
};
|
116
|
+
// Setup abort controller handling
|
117
|
+
if (signal) {
|
118
|
+
signal.addEventListener('abort', () => {
|
119
|
+
state.aborted = true;
|
120
|
+
cancel();
|
121
|
+
});
|
122
|
+
}
|
123
|
+
/**
|
124
|
+
* Cancels all active timers
|
125
|
+
* @private
|
126
|
+
*/
|
127
|
+
function cancelTimers() {
|
128
|
+
if (state.timerId !== undefined) {
|
129
|
+
clearTimeout(state.timerId);
|
130
|
+
state.timerId = undefined;
|
131
|
+
logger.log('Cleared debounce timer');
|
132
|
+
}
|
133
|
+
if (state.maxTimerId !== undefined) {
|
134
|
+
clearTimeout(state.maxTimerId);
|
135
|
+
state.maxTimerId = undefined;
|
136
|
+
logger.log('Cleared max wait timer');
|
137
|
+
}
|
138
|
+
}
|
139
|
+
/**
|
140
|
+
* Cancels any pending function invocations
|
141
|
+
* Rejects all pending promises and resets internal state
|
142
|
+
*/
|
143
|
+
function cancel() {
|
144
|
+
logger.log('Cancelling pending invocations');
|
145
|
+
cancelTimers();
|
146
|
+
state.lastInvokeTime = 0;
|
147
|
+
state.lastArgs = undefined;
|
148
|
+
state.lastThis = undefined;
|
149
|
+
state.lastCallTime = undefined;
|
150
|
+
const error = new Error('Debounced function cancelled');
|
151
|
+
handleError(error);
|
152
|
+
state.pendingPromises.forEach(({ reject }) => reject(new Error('Debounced function cancelled')));
|
153
|
+
state.pendingPromises = [];
|
154
|
+
}
|
155
|
+
/**
|
156
|
+
* Handles errors during function execution
|
157
|
+
* @param {Error} error - The error that occurred
|
158
|
+
* @private
|
159
|
+
*/
|
160
|
+
function handleError(error) {
|
161
|
+
logger.error('Error occurred:', error);
|
162
|
+
if (onError) {
|
163
|
+
try {
|
164
|
+
onError(error);
|
165
|
+
}
|
166
|
+
catch (callbackError) {
|
167
|
+
logger.error('Error in onError callback:', callbackError);
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
/**
|
172
|
+
* Checks if there are any pending function invocations
|
173
|
+
* @returns {boolean} True if there are pending invocations
|
174
|
+
*/
|
175
|
+
function pending() {
|
176
|
+
return state.timerId !== undefined;
|
177
|
+
}
|
178
|
+
/**
|
179
|
+
* Determines if the function should be invoked based on timing conditions
|
180
|
+
* @param {number} time - Current timestamp
|
181
|
+
* @returns {boolean} True if function should be invoked
|
182
|
+
* @private
|
183
|
+
*/
|
184
|
+
function shouldInvoke(time) {
|
185
|
+
if (state.aborted)
|
186
|
+
return false;
|
187
|
+
const timeSinceLastCall = state.lastCallTime === undefined ? 0 : time - state.lastCallTime;
|
188
|
+
const timeSinceLastInvoke = time - state.lastInvokeTime;
|
189
|
+
return (state.lastCallTime === undefined ||
|
190
|
+
timeSinceLastCall >= wait ||
|
191
|
+
timeSinceLastCall < 0 ||
|
192
|
+
(maxWait !== undefined && timeSinceLastInvoke >= maxWait));
|
193
|
+
}
|
194
|
+
/**
|
195
|
+
* Executes the underlying function and manages promise resolution
|
196
|
+
* @param {number} time - Current timestamp
|
197
|
+
* @returns {Promise} Promise resolving to function result
|
198
|
+
* @private
|
199
|
+
*/
|
200
|
+
async function invokeFunc(time) {
|
201
|
+
logger.log(`Invoking function at ${time}`);
|
202
|
+
state.lastInvokeTime = time;
|
203
|
+
const args = state.lastArgs;
|
204
|
+
const thisArg = state.lastThis;
|
205
|
+
state.lastArgs = undefined;
|
206
|
+
state.lastThis = undefined;
|
207
|
+
try {
|
208
|
+
const result = await func.apply(thisArg, args);
|
209
|
+
state.result = result;
|
210
|
+
state.pendingPromises.forEach(({ resolve }) => resolve(result));
|
211
|
+
state.pendingPromises = [];
|
212
|
+
logger.log('Function invoked successfully', result);
|
213
|
+
return result;
|
214
|
+
}
|
215
|
+
catch (error) {
|
216
|
+
const wrappedError = error instanceof Error ? error : new Error(String(error));
|
217
|
+
logger.error('Error in function invocation:', wrappedError);
|
218
|
+
handleError(wrappedError);
|
219
|
+
// Clear pending promises after handling error
|
220
|
+
const currentPromises = [...state.pendingPromises];
|
221
|
+
state.pendingPromises = [];
|
222
|
+
// Reject all pending promises
|
223
|
+
currentPromises.forEach(({ reject }) => reject(wrappedError));
|
224
|
+
}
|
225
|
+
}
|
226
|
+
/**
|
227
|
+
* Starts both the debounce timer and maxWait timer if configured
|
228
|
+
* @param {number} time - Current timestamp
|
229
|
+
* @private
|
230
|
+
*/
|
231
|
+
function startTimer(time) {
|
232
|
+
const remainingTime = remainingWait(time);
|
233
|
+
state.timerId = setTimeout(timerExpired, remainingTime);
|
234
|
+
logger.log(`Started debounce timer for ${remainingTime}ms`);
|
235
|
+
if (maxWait !== undefined && !state.maxTimerId) {
|
236
|
+
const timeToMaxWait = maxWait - (time - state.lastCallTime);
|
237
|
+
state.maxTimerId = setTimeout(() => {
|
238
|
+
logger.log('Max wait timer expired');
|
239
|
+
cancelTimers();
|
240
|
+
invokeFunc(Date.now());
|
241
|
+
}, Math.max(0, timeToMaxWait));
|
242
|
+
logger.log(`Started max wait timer for ${timeToMaxWait}ms`);
|
243
|
+
}
|
244
|
+
}
|
245
|
+
/**
|
246
|
+
* Calculates remaining wait time before next execution
|
247
|
+
* @param {number} time - Current timestamp
|
248
|
+
* @returns {number} Milliseconds until next allowed execution
|
249
|
+
* @private
|
250
|
+
*/
|
251
|
+
function remainingWait(time) {
|
252
|
+
const timeSinceLastCall = state.lastCallTime ? time - state.lastCallTime : 0;
|
253
|
+
return Math.max(0, wait - timeSinceLastCall);
|
254
|
+
}
|
255
|
+
/**
|
256
|
+
* Handles timer expiration
|
257
|
+
* @private
|
258
|
+
*/
|
259
|
+
function timerExpired() {
|
260
|
+
const time = Date.now();
|
261
|
+
logger.log('Debounce timer expired');
|
262
|
+
if (shouldInvoke(time)) {
|
263
|
+
return trailingEdge(time);
|
264
|
+
}
|
265
|
+
startTimer(time);
|
266
|
+
}
|
267
|
+
/**
|
268
|
+
* Handles leading edge execution
|
269
|
+
* @param {number} time - Current timestamp
|
270
|
+
* @private
|
271
|
+
*/
|
272
|
+
function leadingEdge(time) {
|
273
|
+
logger.log('Leading edge triggered');
|
274
|
+
state.lastInvokeTime = time;
|
275
|
+
startTimer(time);
|
276
|
+
if (leading) {
|
277
|
+
invokeFunc(time);
|
278
|
+
}
|
279
|
+
}
|
280
|
+
/**
|
281
|
+
* Handles trailing edge execution
|
282
|
+
* @param {number} time - Current timestamp
|
283
|
+
* @private
|
284
|
+
*/
|
285
|
+
function trailingEdge(time) {
|
286
|
+
logger.log('Trailing edge triggered');
|
287
|
+
cancelTimers();
|
288
|
+
if (trailing && state.lastArgs) {
|
289
|
+
invokeFunc(time);
|
290
|
+
}
|
291
|
+
else {
|
292
|
+
state.pendingPromises.forEach(({ resolve }) => {
|
293
|
+
resolve(state.result);
|
294
|
+
});
|
295
|
+
state.pendingPromises = [];
|
296
|
+
}
|
297
|
+
}
|
298
|
+
/**
|
299
|
+
* Immediately executes the debounced function
|
300
|
+
* @param {...Parameters<T>} args - Function arguments
|
301
|
+
* @returns {Promise<ReturnType<T>>} Promise resolving to function result
|
302
|
+
*/
|
303
|
+
async function flush(...args) {
|
304
|
+
logger.log('Flush requested');
|
305
|
+
const argsToUse = args.length > 0 ? args : state.lastArgs;
|
306
|
+
const thisArg = state.lastThis;
|
307
|
+
cancelTimers();
|
308
|
+
if (argsToUse) {
|
309
|
+
state.lastArgs = argsToUse;
|
310
|
+
state.lastThis = thisArg;
|
311
|
+
return invokeFunc(Date.now());
|
312
|
+
}
|
313
|
+
return Promise.resolve(state.result);
|
314
|
+
}
|
315
|
+
/**
|
316
|
+
* Cleans up resources used by the debounced function
|
317
|
+
*/
|
318
|
+
function cleanup() {
|
319
|
+
logger.log('Cleanup initiated');
|
320
|
+
cancel();
|
321
|
+
privateState.delete(debounced);
|
322
|
+
}
|
323
|
+
/**
|
324
|
+
* The debounced function that wraps the original
|
325
|
+
* @param {...Parameters<T>} args - Function arguments
|
326
|
+
* @returns {Promise<ReturnType<T>>} Promise resolving to function result
|
327
|
+
*/
|
328
|
+
const debounced = function (...args) {
|
329
|
+
if (state.aborted) {
|
330
|
+
return Promise.reject(new Error('Debounced function aborted'));
|
331
|
+
}
|
332
|
+
const time = Date.now();
|
333
|
+
const isInvoking = shouldInvoke(time);
|
334
|
+
state.lastArgs = args;
|
335
|
+
state.lastThis = this;
|
336
|
+
state.lastCallTime = time;
|
337
|
+
logger.log('Function called', {
|
338
|
+
time,
|
339
|
+
isInvoking,
|
340
|
+
args,
|
341
|
+
pending: pending(),
|
342
|
+
});
|
343
|
+
return new Promise((resolve, reject) => {
|
344
|
+
state.pendingPromises.push({ resolve, reject });
|
345
|
+
if (state.timerId === undefined) {
|
346
|
+
leadingEdge(time);
|
347
|
+
}
|
348
|
+
else {
|
349
|
+
cancelTimers();
|
350
|
+
startTimer(time);
|
351
|
+
}
|
352
|
+
});
|
353
|
+
};
|
354
|
+
// Store private state
|
355
|
+
privateState.set(debounced, state);
|
356
|
+
// Add utility methods
|
357
|
+
Object.defineProperties(debounced, {
|
358
|
+
cancel: { value: cancel, writable: false, configurable: false },
|
359
|
+
flush: { value: flush, writable: false, configurable: false },
|
360
|
+
pending: { value: pending, writable: false, configurable: false },
|
361
|
+
cleanup: { value: cleanup, writable: false, configurable: false },
|
362
|
+
});
|
363
|
+
return debounced;
|
364
|
+
}
|
365
|
+
|
366
|
+
|
367
|
+
;// ./src/index.ts
|
368
|
+
|
369
|
+
|
370
|
+
module.exports = __webpack_exports__;
|
371
|
+
/******/ })()
|
372
|
+
;
|
7
373
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","mappings":"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","sources":["webpack://@avatijs/debounce/webpack/bootstrap","webpack://@avatijs/debounce/webpack/runtime/define property getters","webpack://@avatijs/debounce/webpack/runtime/hasOwnProperty shorthand","webpack://@avatijs/debounce/webpack/runtime/make namespace object","webpack://@avatijs/debounce/./src/debouce.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Advanced debounce utility with TypeScript support\n * Provides a way to limit the rate at which a function can fire by delaying its execution\n * until after a specified amount of time has elapsed since its last invocation.\n * @module debounce\n */\n\n/**\n * Timer ID type returned by setTimeout\n * Used for managing timers internally\n */\ntype TimerId = ReturnType<typeof setTimeout>;\n\n/**\n * Generic function type that can accept any arguments and return any value\n * Used as a constraint for functions that can be debounced\n */\ntype AnyFunction = (...args: any[]) => any;\n\n/**\n * Configuration options for the debounce function\n * @interface DebounceOptions\n */\ninterface DebounceOptions {\n /** Number of milliseconds to delay execution (default: 0) */\n readonly wait?: number;\n /** Whether to execute on the leading edge of the timeout (default: false) */\n readonly leading?: boolean;\n /** Whether to execute on the trailing edge of the timeout (default: true) */\n readonly trailing?: boolean;\n /** Maximum time the function can be delayed before forced execution */\n readonly maxWait?: number;\n /** Enable debug logging for troubleshooting */\n readonly debug?: boolean;\n /** AbortController signal for cancellation */\n readonly signal?: AbortSignal;\n\n onError?: (error: Error) => void;\n}\n\n/**\n * Interface for the debounced function, including utility methods\n * @interface DebouncedFunction\n * @template T - The type of the original function\n */\ninterface DebouncedFunction<T extends AnyFunction> {\n /** Cancels any pending function invocations */\n readonly cancel: () => void;\n /** Immediately executes any pending function call */\n readonly flush: (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;\n /** Checks if there are any pending invocations */\n readonly pending: () => boolean;\n /** Cleans up resources used by the debounced function */\n readonly cleanup: () => void;\n\n /** The debounced function that wraps the original */\n (...args: Parameters<T>): Promise<Awaited<ReturnType<T>>>;\n}\n\n/**\n * Internal state management for the debounced function\n * @interface PrivateState\n * @template T - The type of the original function\n * @private\n */\ninterface PrivateState<T extends AnyFunction> {\n /** Current timer ID for the debounce delay */\n timerId?: TimerId;\n /** Timer ID for the maximum wait limit */\n maxTimerId?: TimerId;\n /** Timestamp of the last function call */\n lastCallTime?: number;\n /** Timestamp of the last successful function invocation */\n lastInvokeTime: number;\n /** Arguments from the most recent function call */\n lastArgs?: Parameters<T>;\n /** Execution context (this) from the most recent call */\n lastThis?: any;\n /** Result from the last function execution */\n result?: Awaited<ReturnType<T>>;\n /** Array of pending promises waiting for resolution */\n pendingPromises: Array<{\n resolve: (value: Awaited<ReturnType<T>>) => void;\n reject: (reason?: any) => void;\n }>;\n /** Flag indicating if the function has been aborted */\n aborted: boolean;\n}\n\n/** WeakMap to store private state for each debounced function */\nconst privateState = new WeakMap<DebouncedFunction<any>, PrivateState<any>>();\n\n/**\n * Creates a logger instance based on debug flag\n * @param debug - Whether debug logging is enabled\n * @returns Object with logging methods\n * @private\n */\nconst createLogger = (debug: boolean) => ({\n log: (...args: any[]) => debug && console.log('[Debounce]', ...args),\n warn: (...args: any[]) => debug && console.warn('[Debounce]', ...args),\n error: (...args: any[]) => debug && console.error('[Debounce]', ...args),\n});\n\n/**\n * Creates a debounced version of the provided function that delays invoking func until after\n * wait milliseconds have elapsed since the last time the debounced function was invoked.\n *\n * @template T - The type of the function to debounce\n * @param {T} func - The function to debounce\n * @param {DebounceOptions} [options={}] - Configuration options\n * @returns {DebouncedFunction<T>} The debounced function\n * @throws {TypeError} If func is not a function\n * @throws {RangeError} If wait or maxWait values are invalid\n * @throws {Error} If neither leading nor trailing is true\n *\n * @example\n * const debouncedFn = debounce(async (x: number) => x * 2, { wait: 1000 });\n * await debouncedFn(5); // Will execute after 1000ms of inactivity\n * const debouncedFn = debounce(\n * async (x: number) => x * 2,\n * {\n * wait: 1000,\n * onError: (error) => console.error('Error in debounced function:', error)\n * }\n * );\n */\nfunction debounce<T extends AnyFunction>(\n func: T,\n options: DebounceOptions = {},\n): DebouncedFunction<T> {\n // Input validation\n if (typeof func !== 'function') {\n throw new TypeError('Expected a function');\n }\n\n const {\n wait = 0,\n leading = false,\n trailing = true,\n maxWait,\n debug = false,\n signal,\n onError,\n } = options;\n\n // Validate options\n if (wait < 0 || (maxWait !== undefined && maxWait < wait)) {\n throw new RangeError('Invalid wait/maxWait values');\n }\n\n if (!leading && !trailing) {\n throw new Error('At least one of leading or trailing must be true');\n }\n\n const logger = createLogger(debug);\n const state: PrivateState<T> = {\n lastInvokeTime: 0,\n pendingPromises: [],\n aborted: false,\n };\n\n // Setup abort controller handling\n if (signal) {\n signal.addEventListener('abort', () => {\n state.aborted = true;\n cancel();\n });\n }\n\n /**\n * Cancels all active timers\n * @private\n */\n function cancelTimers(): void {\n if (state.timerId !== undefined) {\n clearTimeout(state.timerId);\n state.timerId = undefined;\n logger.log('Cleared debounce timer');\n }\n if (state.maxTimerId !== undefined) {\n clearTimeout(state.maxTimerId);\n state.maxTimerId = undefined;\n logger.log('Cleared max wait timer');\n }\n }\n\n /**\n * Cancels any pending function invocations\n * Rejects all pending promises and resets internal state\n */\n function cancel(): void {\n logger.log('Cancelling pending invocations');\n cancelTimers();\n state.lastInvokeTime = 0;\n state.lastArgs = undefined;\n state.lastThis = undefined;\n state.lastCallTime = undefined;\n const error = new Error('Debounced function cancelled');\n handleError(error);\n state.pendingPromises.forEach(({ reject }) =>\n reject(new Error('Debounced function cancelled')),\n );\n state.pendingPromises = [];\n }\n\n /**\n * Handles errors during function execution\n * @param {Error} error - The error that occurred\n * @private\n */\n function handleError(error: Error): void {\n logger.error('Error occurred:', error);\n if (onError) {\n try {\n onError(error);\n } catch (callbackError) {\n logger.error('Error in onError callback:', callbackError);\n }\n }\n }\n\n /**\n * Checks if there are any pending function invocations\n * @returns {boolean} True if there are pending invocations\n */\n function pending(): boolean {\n return state.timerId !== undefined;\n }\n\n /**\n * Determines if the function should be invoked based on timing conditions\n * @param {number} time - Current timestamp\n * @returns {boolean} True if function should be invoked\n * @private\n */\n function shouldInvoke(time: number): boolean {\n if (state.aborted) return false;\n\n const timeSinceLastCall = state.lastCallTime === undefined ? 0 : time - state.lastCallTime;\n const timeSinceLastInvoke = time - state.lastInvokeTime;\n\n return (\n state.lastCallTime === undefined ||\n timeSinceLastCall >= wait ||\n timeSinceLastCall < 0 ||\n (maxWait !== undefined && timeSinceLastInvoke >= maxWait)\n );\n }\n\n /**\n * Executes the underlying function and manages promise resolution\n * @param {number} time - Current timestamp\n * @returns {Promise} Promise resolving to function result\n * @private\n */\n async function invokeFunc(time: number): Promise<Awaited<ReturnType<T>> | void> {\n logger.log(`Invoking function at ${time}`);\n state.lastInvokeTime = time;\n const args = state.lastArgs!;\n const thisArg = state.lastThis;\n\n state.lastArgs = undefined;\n state.lastThis = undefined;\n\n try {\n const result = await func.apply(thisArg, args);\n state.result = result;\n state.pendingPromises.forEach(({ resolve }) => resolve(result));\n state.pendingPromises = [];\n logger.log('Function invoked successfully', result);\n return result;\n } catch (error) {\n const wrappedError = error instanceof Error ? error : new Error(String(error));\n logger.error('Error in function invocation:', wrappedError);\n handleError(wrappedError);\n\n // Clear pending promises after handling error\n const currentPromises = [...state.pendingPromises];\n state.pendingPromises = [];\n\n // Reject all pending promises\n currentPromises.forEach(({ reject }) => reject(wrappedError));\n }\n }\n\n /**\n * Starts both the debounce timer and maxWait timer if configured\n * @param {number} time - Current timestamp\n * @private\n */\n function startTimer(time: number): void {\n const remainingTime = remainingWait(time);\n state.timerId = setTimeout(timerExpired, remainingTime);\n logger.log(`Started debounce timer for ${remainingTime}ms`);\n\n if (maxWait !== undefined && !state.maxTimerId) {\n const timeToMaxWait = maxWait - (time - state.lastCallTime!);\n state.maxTimerId = setTimeout(\n () => {\n logger.log('Max wait timer expired');\n cancelTimers();\n invokeFunc(Date.now());\n },\n Math.max(0, timeToMaxWait),\n );\n logger.log(`Started max wait timer for ${timeToMaxWait}ms`);\n }\n }\n\n /**\n * Calculates remaining wait time before next execution\n * @param {number} time - Current timestamp\n * @returns {number} Milliseconds until next allowed execution\n * @private\n */\n function remainingWait(time: number): number {\n const timeSinceLastCall = state.lastCallTime ? time - state.lastCallTime : 0;\n return Math.max(0, wait - timeSinceLastCall);\n }\n\n /**\n * Handles timer expiration\n * @private\n */\n function timerExpired(): void {\n const time = Date.now();\n logger.log('Debounce timer expired');\n\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n\n startTimer(time);\n }\n\n /**\n * Handles leading edge execution\n * @param {number} time - Current timestamp\n * @private\n */\n function leadingEdge(time: number): void {\n logger.log('Leading edge triggered');\n state.lastInvokeTime = time;\n startTimer(time);\n\n if (leading) {\n invokeFunc(time);\n }\n }\n\n /**\n * Handles trailing edge execution\n * @param {number} time - Current timestamp\n * @private\n */\n function trailingEdge(time: number): void {\n logger.log('Trailing edge triggered');\n cancelTimers();\n\n if (trailing && state.lastArgs) {\n invokeFunc(time);\n } else {\n state.pendingPromises.forEach(({ resolve }) => {\n resolve(state.result as Awaited<ReturnType<T>>);\n });\n state.pendingPromises = [];\n }\n }\n\n /**\n * Immediately executes the debounced function\n * @param {...Parameters<T>} args - Function arguments\n * @returns {Promise<ReturnType<T>>} Promise resolving to function result\n */\n async function flush(...args: Parameters<T>): Promise<Awaited<ReturnType<T>> | void> {\n logger.log('Flush requested');\n const argsToUse = args.length > 0 ? args : state.lastArgs;\n const thisArg = state.lastThis;\n\n cancelTimers();\n\n if (argsToUse) {\n state.lastArgs = argsToUse;\n state.lastThis = thisArg;\n return invokeFunc(Date.now());\n }\n\n return Promise.resolve(state.result!);\n }\n\n /**\n * Cleans up resources used by the debounced function\n */\n function cleanup(): void {\n logger.log('Cleanup initiated');\n cancel();\n privateState.delete(debounced);\n }\n\n /**\n * The debounced function that wraps the original\n * @param {...Parameters<T>} args - Function arguments\n * @returns {Promise<ReturnType<T>>} Promise resolving to function result\n */\n const debounced = function(\n this: any,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n if (state.aborted) {\n return Promise.reject(new Error('Debounced function aborted'));\n }\n\n const time = Date.now();\n const isInvoking = shouldInvoke(time);\n\n state.lastArgs = args;\n state.lastThis = this;\n state.lastCallTime = time;\n\n logger.log('Function called', {\n time,\n isInvoking,\n args,\n pending: pending(),\n });\n\n return new Promise((resolve, reject) => {\n state.pendingPromises.push({ resolve, reject });\n\n if (state.timerId === undefined) {\n leadingEdge(time);\n } else {\n cancelTimers();\n startTimer(time);\n }\n });\n } as DebouncedFunction<T>;\n\n // Store private state\n privateState.set(debounced, state);\n\n // Add utility methods\n Object.defineProperties(debounced, {\n cancel: { value: cancel, writable: false, configurable: false },\n flush: { value: flush, writable: false, configurable: false },\n pending: { value: pending, writable: false, configurable: false },\n cleanup: { value: cleanup, writable: false, configurable: false },\n });\n\n return debounced;\n}\n\nexport { debounce, type DebouncedFunction, type DebounceOptions };\n"],"names":["__webpack_require__","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","privateState","WeakMap","createLogger","debug","log","args","console","warn","error","debounce","func","options","TypeError","wait","leading","trailing","maxWait","signal","onError","undefined","RangeError","Error","logger","state","lastInvokeTime","pendingPromises","aborted","cancelTimers","timerId","clearTimeout","maxTimerId","cancel","lastArgs","lastThis","lastCallTime","handleError","forEach","reject","callbackError","pending","shouldInvoke","time","timeSinceLastCall","async","invokeFunc","thisArg","result","apply","resolve","wrappedError","String","currentPromises","startTimer","remainingTime","Math","max","remainingWait","setTimeout","timerExpired","timeToMaxWait","Date","now","trailingEdge","addEventListener","debounced","Promise","isInvoking","this","push","leadingEdge","set","defineProperties","writable","configurable","flush","argsToUse","length","cleanup","delete"],"sourceRoot":""}
|
1
|
+
{"version":3,"file":"index.js","mappings":"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","sources":["webpack://@avatijs/debounce/webpack/bootstrap","webpack://@avatijs/debounce/webpack/runtime/define property getters","webpack://@avatijs/debounce/webpack/runtime/hasOwnProperty shorthand","webpack://@avatijs/debounce/webpack/runtime/make namespace object","webpack://@avatijs/debounce/./src/debouce.ts","webpack://@avatijs/debounce/./src/index.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Advanced debounce utility with TypeScript support\n * Provides a way to limit the rate at which a function can fire by delaying its execution\n * until after a specified amount of time has elapsed since its last invocation.\n * @module debounce\n */\n\n/**\n * Timer ID type returned by setTimeout\n * Used for managing timers internally\n */\ntype TimerId = ReturnType<typeof setTimeout>;\n\n/**\n * Generic function type that can accept any arguments and return any value\n * Used as a constraint for functions that can be debounced\n */\ntype AnyFunction = (...args: any[]) => any;\n\n/**\n * Configuration options for the debounce function\n * @interface DebounceOptions\n */\ninterface DebounceOptions {\n /** Number of milliseconds to delay execution (default: 0) */\n readonly wait?: number;\n /** Whether to execute on the leading edge of the timeout (default: false) */\n readonly leading?: boolean;\n /** Whether to execute on the trailing edge of the timeout (default: true) */\n readonly trailing?: boolean;\n /** Maximum time the function can be delayed before forced execution */\n readonly maxWait?: number;\n /** Enable debug logging for troubleshooting */\n readonly debug?: boolean;\n /** AbortController signal for cancellation */\n readonly signal?: AbortSignal;\n\n onError?: (error: Error) => void;\n}\n\n/**\n * Interface for the debounced function, including utility methods\n * @interface DebouncedFunction\n * @template T - The type of the original function\n */\ninterface DebouncedFunction<T extends AnyFunction> {\n /** Cancels any pending function invocations */\n readonly cancel: () => void;\n /** Immediately executes any pending function call */\n readonly flush: (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;\n /** Checks if there are any pending invocations */\n readonly pending: () => boolean;\n /** Cleans up resources used by the debounced function */\n readonly cleanup: () => void;\n\n /** The debounced function that wraps the original */\n (...args: Parameters<T>): Promise<Awaited<ReturnType<T>>>;\n}\n\n/**\n * Internal state management for the debounced function\n * @interface PrivateState\n * @template T - The type of the original function\n * @private\n */\ninterface PrivateState<T extends AnyFunction> {\n /** Current timer ID for the debounce delay */\n timerId?: TimerId;\n /** Timer ID for the maximum wait limit */\n maxTimerId?: TimerId;\n /** Timestamp of the last function call */\n lastCallTime?: number;\n /** Timestamp of the last successful function invocation */\n lastInvokeTime: number;\n /** Arguments from the most recent function call */\n lastArgs?: Parameters<T>;\n /** Execution context (this) from the most recent call */\n lastThis?: any;\n /** Result from the last function execution */\n result?: Awaited<ReturnType<T>>;\n /** Array of pending promises waiting for resolution */\n pendingPromises: Array<{\n resolve: (value: Awaited<ReturnType<T>>) => void;\n reject: (reason?: any) => void;\n }>;\n /** Flag indicating if the function has been aborted */\n aborted: boolean;\n}\n\n/** WeakMap to store private state for each debounced function */\nconst privateState = new WeakMap<DebouncedFunction<any>, PrivateState<any>>();\n\n/**\n * Creates a logger instance based on debug flag\n * @param debug - Whether debug logging is enabled\n * @returns Object with logging methods\n * @private\n */\nconst createLogger = (debug: boolean) => ({\n log: (...args: any[]) => debug && console.log('[Debounce]', ...args),\n warn: (...args: any[]) => debug && console.warn('[Debounce]', ...args),\n error: (...args: any[]) => debug && console.error('[Debounce]', ...args),\n});\n\n/**\n * Creates a debounced version of the provided function that delays invoking func until after\n * wait milliseconds have elapsed since the last time the debounced function was invoked.\n *\n * @template T - The type of the function to debounce\n * @param {T} func - The function to debounce\n * @param {DebounceOptions} [options={}] - Configuration options\n * @returns {DebouncedFunction<T>} The debounced function\n * @throws {TypeError} If func is not a function\n * @throws {RangeError} If wait or maxWait values are invalid\n * @throws {Error} If neither leading nor trailing is true\n *\n * @example\n * const debouncedFn = debounce(async (x: number) => x * 2, { wait: 1000 });\n * await debouncedFn(5); // Will execute after 1000ms of inactivity\n * const debouncedFn = debounce(\n * async (x: number) => x * 2,\n * {\n * wait: 1000,\n * onError: (error) => console.error('Error in debounced function:', error)\n * }\n * );\n */\nfunction debounce<T extends AnyFunction>(\n func: T,\n options: DebounceOptions = {},\n): DebouncedFunction<T> {\n // Input validation\n if (typeof func !== 'function') {\n throw new TypeError('Expected a function');\n }\n\n const {\n wait = 0,\n leading = false,\n trailing = true,\n maxWait,\n debug = false,\n signal,\n onError,\n } = options;\n\n // Validate options\n if (wait < 0 || (maxWait !== undefined && maxWait < wait)) {\n throw new RangeError('Invalid wait/maxWait values');\n }\n\n if (!leading && !trailing) {\n throw new Error('At least one of leading or trailing must be true');\n }\n\n const logger = createLogger(debug);\n const state: PrivateState<T> = {\n lastInvokeTime: 0,\n pendingPromises: [],\n aborted: false,\n };\n\n // Setup abort controller handling\n if (signal) {\n signal.addEventListener('abort', () => {\n state.aborted = true;\n cancel();\n });\n }\n\n /**\n * Cancels all active timers\n * @private\n */\n function cancelTimers(): void {\n if (state.timerId !== undefined) {\n clearTimeout(state.timerId);\n state.timerId = undefined;\n logger.log('Cleared debounce timer');\n }\n if (state.maxTimerId !== undefined) {\n clearTimeout(state.maxTimerId);\n state.maxTimerId = undefined;\n logger.log('Cleared max wait timer');\n }\n }\n\n /**\n * Cancels any pending function invocations\n * Rejects all pending promises and resets internal state\n */\n function cancel(): void {\n logger.log('Cancelling pending invocations');\n cancelTimers();\n state.lastInvokeTime = 0;\n state.lastArgs = undefined;\n state.lastThis = undefined;\n state.lastCallTime = undefined;\n const error = new Error('Debounced function cancelled');\n handleError(error);\n state.pendingPromises.forEach(({ reject }) =>\n reject(new Error('Debounced function cancelled')),\n );\n state.pendingPromises = [];\n }\n\n /**\n * Handles errors during function execution\n * @param {Error} error - The error that occurred\n * @private\n */\n function handleError(error: Error): void {\n logger.error('Error occurred:', error);\n if (onError) {\n try {\n onError(error);\n } catch (callbackError) {\n logger.error('Error in onError callback:', callbackError);\n }\n }\n }\n\n /**\n * Checks if there are any pending function invocations\n * @returns {boolean} True if there are pending invocations\n */\n function pending(): boolean {\n return state.timerId !== undefined;\n }\n\n /**\n * Determines if the function should be invoked based on timing conditions\n * @param {number} time - Current timestamp\n * @returns {boolean} True if function should be invoked\n * @private\n */\n function shouldInvoke(time: number): boolean {\n if (state.aborted) return false;\n\n const timeSinceLastCall = state.lastCallTime === undefined ? 0 : time - state.lastCallTime;\n const timeSinceLastInvoke = time - state.lastInvokeTime;\n\n return (\n state.lastCallTime === undefined ||\n timeSinceLastCall >= wait ||\n timeSinceLastCall < 0 ||\n (maxWait !== undefined && timeSinceLastInvoke >= maxWait)\n );\n }\n\n /**\n * Executes the underlying function and manages promise resolution\n * @param {number} time - Current timestamp\n * @returns {Promise} Promise resolving to function result\n * @private\n */\n async function invokeFunc(time: number): Promise<Awaited<ReturnType<T>> | void> {\n logger.log(`Invoking function at ${time}`);\n state.lastInvokeTime = time;\n const args = state.lastArgs!;\n const thisArg = state.lastThis;\n\n state.lastArgs = undefined;\n state.lastThis = undefined;\n\n try {\n const result = await func.apply(thisArg, args);\n state.result = result;\n state.pendingPromises.forEach(({ resolve }) => resolve(result));\n state.pendingPromises = [];\n logger.log('Function invoked successfully', result);\n return result;\n } catch (error) {\n const wrappedError = error instanceof Error ? error : new Error(String(error));\n logger.error('Error in function invocation:', wrappedError);\n handleError(wrappedError);\n\n // Clear pending promises after handling error\n const currentPromises = [...state.pendingPromises];\n state.pendingPromises = [];\n\n // Reject all pending promises\n currentPromises.forEach(({ reject }) => reject(wrappedError));\n }\n }\n\n /**\n * Starts both the debounce timer and maxWait timer if configured\n * @param {number} time - Current timestamp\n * @private\n */\n function startTimer(time: number): void {\n const remainingTime = remainingWait(time);\n state.timerId = setTimeout(timerExpired, remainingTime);\n logger.log(`Started debounce timer for ${remainingTime}ms`);\n\n if (maxWait !== undefined && !state.maxTimerId) {\n const timeToMaxWait = maxWait - (time - state.lastCallTime!);\n state.maxTimerId = setTimeout(\n () => {\n logger.log('Max wait timer expired');\n cancelTimers();\n invokeFunc(Date.now());\n },\n Math.max(0, timeToMaxWait),\n );\n logger.log(`Started max wait timer for ${timeToMaxWait}ms`);\n }\n }\n\n /**\n * Calculates remaining wait time before next execution\n * @param {number} time - Current timestamp\n * @returns {number} Milliseconds until next allowed execution\n * @private\n */\n function remainingWait(time: number): number {\n const timeSinceLastCall = state.lastCallTime ? time - state.lastCallTime : 0;\n return Math.max(0, wait - timeSinceLastCall);\n }\n\n /**\n * Handles timer expiration\n * @private\n */\n function timerExpired(): void {\n const time = Date.now();\n logger.log('Debounce timer expired');\n\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n\n startTimer(time);\n }\n\n /**\n * Handles leading edge execution\n * @param {number} time - Current timestamp\n * @private\n */\n function leadingEdge(time: number): void {\n logger.log('Leading edge triggered');\n state.lastInvokeTime = time;\n startTimer(time);\n\n if (leading) {\n invokeFunc(time);\n }\n }\n\n /**\n * Handles trailing edge execution\n * @param {number} time - Current timestamp\n * @private\n */\n function trailingEdge(time: number): void {\n logger.log('Trailing edge triggered');\n cancelTimers();\n\n if (trailing && state.lastArgs) {\n invokeFunc(time);\n } else {\n state.pendingPromises.forEach(({ resolve }) => {\n resolve(state.result as Awaited<ReturnType<T>>);\n });\n state.pendingPromises = [];\n }\n }\n\n /**\n * Immediately executes the debounced function\n * @param {...Parameters<T>} args - Function arguments\n * @returns {Promise<ReturnType<T>>} Promise resolving to function result\n */\n async function flush(...args: Parameters<T>): Promise<Awaited<ReturnType<T>> | void> {\n logger.log('Flush requested');\n const argsToUse = args.length > 0 ? args : state.lastArgs;\n const thisArg = state.lastThis;\n\n cancelTimers();\n\n if (argsToUse) {\n state.lastArgs = argsToUse;\n state.lastThis = thisArg;\n return invokeFunc(Date.now());\n }\n\n return Promise.resolve(state.result!);\n }\n\n /**\n * Cleans up resources used by the debounced function\n */\n function cleanup(): void {\n logger.log('Cleanup initiated');\n cancel();\n privateState.delete(debounced);\n }\n\n /**\n * The debounced function that wraps the original\n * @param {...Parameters<T>} args - Function arguments\n * @returns {Promise<ReturnType<T>>} Promise resolving to function result\n */\n const debounced = function(\n this: any,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n if (state.aborted) {\n return Promise.reject(new Error('Debounced function aborted'));\n }\n\n const time = Date.now();\n const isInvoking = shouldInvoke(time);\n\n state.lastArgs = args;\n state.lastThis = this;\n state.lastCallTime = time;\n\n logger.log('Function called', {\n time,\n isInvoking,\n args,\n pending: pending(),\n });\n\n return new Promise((resolve, reject) => {\n state.pendingPromises.push({ resolve, reject });\n\n if (state.timerId === undefined) {\n leadingEdge(time);\n } else {\n cancelTimers();\n startTimer(time);\n }\n });\n } as DebouncedFunction<T>;\n\n // Store private state\n privateState.set(debounced, state);\n\n // Add utility methods\n Object.defineProperties(debounced, {\n cancel: { value: cancel, writable: false, configurable: false },\n flush: { value: flush, writable: false, configurable: false },\n pending: { value: pending, writable: false, configurable: false },\n cleanup: { value: cleanup, writable: false, configurable: false },\n });\n\n return debounced;\n}\n\nexport { debounce, type DebouncedFunction, type DebounceOptions };\n","export * from './debouce';\n"],"names":[],"sourceRoot":""}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/*!
|
2
|
+
* @avatijs/debounce 0.1.3
|
3
|
+
* Copyright (c) 2024 Khaled Sameer <khaled.smq@hotmail.com>
|
4
|
+
* Licensed under MIT, https://opensource.org/licenses/MIT/
|
5
|
+
* Please visit https://avati.io/ for details.
|
6
|
+
*/(()=>{"use strict";var e={d:(n,o)=>{for(var r in o)e.o(o,r)&&!e.o(n,r)&&Object.defineProperty(n,r,{enumerable:!0,get:o[r]})},o:(e,n)=>Object.prototype.hasOwnProperty.call(e,n),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"t",{value:!0})}},n={};e.r(n),e.d(n,{debounce:()=>t});const o=new WeakMap,r=e=>({log:(...n)=>e&&void 0,warn:(...n)=>e&&void 0,error:(...n)=>e&&void 0});function t(e,n={}){if("function"!=typeof e)throw new TypeError("Expected a function");const{wait:t=0,leading:i=!1,trailing:c=!0,maxWait:a,debug:u=!1,signal:d,onError:l}=n;if(0>t||void 0!==a&&t>a)throw new RangeError("Invalid wait/maxWait values");if(!i&&!c)throw Error("At least one of leading or trailing must be true");const s=r(u),f={lastInvokeTime:0,pendingPromises:[],aborted:!1};function v(){void 0!==f.timerId&&(clearTimeout(f.timerId),f.timerId=void 0,s.log("Cleared debounce timer")),void 0!==f.maxTimerId&&(clearTimeout(f.maxTimerId),f.maxTimerId=void 0,s.log("Cleared max wait timer"))}function b(){s.log("Cancelling pending invocations"),v(),f.lastInvokeTime=0,f.lastArgs=void 0,f.lastThis=void 0,f.lastCallTime=void 0,g(Error("Debounced function cancelled")),f.pendingPromises.forEach((({reject:e})=>e(Error("Debounced function cancelled")))),f.pendingPromises=[]}function g(e){if(s.error("Error occurred:",e),l)try{l(e)}catch(e){s.error("Error in onError callback:",e)}}function m(){return void 0!==f.timerId}function w(e){if(f.aborted)return!1;const n=void 0===f.lastCallTime?0:e-f.lastCallTime;return void 0===f.lastCallTime||n>=t||0>n||void 0!==a&&e-f.lastInvokeTime>=a}async function E(n){s.log("Invoking function at "+n),f.lastInvokeTime=n;const o=f.lastArgs,r=f.lastThis;f.lastArgs=void 0,f.lastThis=void 0;try{const n=await e.apply(r,o);return f.result=n,f.pendingPromises.forEach((({resolve:e})=>e(n))),f.pendingPromises=[],s.log("Function invoked successfully",n),n}catch(e){const n=e instanceof Error?e:Error(e+"");s.error("Error in function invocation:",n),g(n);const o=[...f.pendingPromises];f.pendingPromises=[],o.forEach((({reject:e})=>e(n)))}}function p(e){const n=function(e){return Math.max(0,t-(f.lastCallTime?e-f.lastCallTime:0))}(e);if(f.timerId=setTimeout(y,n),s.log(`Started debounce timer for ${n}ms`),void 0!==a&&!f.maxTimerId){const n=a-(e-f.lastCallTime);f.maxTimerId=setTimeout((()=>{s.log("Max wait timer expired"),v(),E(Date.now())}),Math.max(0,n)),s.log(`Started max wait timer for ${n}ms`)}}function y(){const e=Date.now();if(s.log("Debounce timer expired"),w(e))return function(e){s.log("Trailing edge triggered"),v(),c&&f.lastArgs?E(e):(f.pendingPromises.forEach((({resolve:e})=>{e(f.result)})),f.pendingPromises=[])}(e);p(e)}d&&d.addEventListener("abort",(()=>{f.aborted=!0,b()}));const h=function(...e){if(f.aborted)return Promise.reject(Error("Debounced function aborted"));const n=Date.now(),o=w(n);return f.lastArgs=e,f.lastThis=this,f.lastCallTime=n,s.log("Function called",{time:n,isInvoking:o,args:e,pending:m()}),new Promise(((e,o)=>{f.pendingPromises.push({resolve:e,reject:o}),void 0===f.timerId?function(e){s.log("Leading edge triggered"),f.lastInvokeTime=e,p(e),i&&E(e)}(n):(v(),p(n))}))};return o.set(h,f),Object.defineProperties(h,{cancel:{value:b,writable:!1,configurable:!1},flush:{value:async function(...e){s.log("Flush requested");const n=e.length>0?e:f.lastArgs,o=f.lastThis;return v(),n?(f.lastArgs=n,f.lastThis=o,E(Date.now())):Promise.resolve(f.result)},writable:!1,configurable:!1},pending:{value:m,writable:!1,configurable:!1},cleanup:{value:function(){s.log("Cleanup initiated"),b(),o.delete(h)},writable:!1,configurable:!1}}),h}module.exports=n})();
|
7
|
+
//# sourceMappingURL=index.min.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.min.js","mappings":"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","sources":["webpack://@avatijs/debounce/webpack/bootstrap","webpack://@avatijs/debounce/webpack/runtime/define property getters","webpack://@avatijs/debounce/webpack/runtime/hasOwnProperty shorthand","webpack://@avatijs/debounce/webpack/runtime/make namespace object","webpack://@avatijs/debounce/./src/debouce.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Advanced debounce utility with TypeScript support\n * Provides a way to limit the rate at which a function can fire by delaying its execution\n * until after a specified amount of time has elapsed since its last invocation.\n * @module debounce\n */\n\n/**\n * Timer ID type returned by setTimeout\n * Used for managing timers internally\n */\ntype TimerId = ReturnType<typeof setTimeout>;\n\n/**\n * Generic function type that can accept any arguments and return any value\n * Used as a constraint for functions that can be debounced\n */\ntype AnyFunction = (...args: any[]) => any;\n\n/**\n * Configuration options for the debounce function\n * @interface DebounceOptions\n */\ninterface DebounceOptions {\n /** Number of milliseconds to delay execution (default: 0) */\n readonly wait?: number;\n /** Whether to execute on the leading edge of the timeout (default: false) */\n readonly leading?: boolean;\n /** Whether to execute on the trailing edge of the timeout (default: true) */\n readonly trailing?: boolean;\n /** Maximum time the function can be delayed before forced execution */\n readonly maxWait?: number;\n /** Enable debug logging for troubleshooting */\n readonly debug?: boolean;\n /** AbortController signal for cancellation */\n readonly signal?: AbortSignal;\n\n onError?: (error: Error) => void;\n}\n\n/**\n * Interface for the debounced function, including utility methods\n * @interface DebouncedFunction\n * @template T - The type of the original function\n */\ninterface DebouncedFunction<T extends AnyFunction> {\n /** Cancels any pending function invocations */\n readonly cancel: () => void;\n /** Immediately executes any pending function call */\n readonly flush: (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;\n /** Checks if there are any pending invocations */\n readonly pending: () => boolean;\n /** Cleans up resources used by the debounced function */\n readonly cleanup: () => void;\n\n /** The debounced function that wraps the original */\n (...args: Parameters<T>): Promise<Awaited<ReturnType<T>>>;\n}\n\n/**\n * Internal state management for the debounced function\n * @interface PrivateState\n * @template T - The type of the original function\n * @private\n */\ninterface PrivateState<T extends AnyFunction> {\n /** Current timer ID for the debounce delay */\n timerId?: TimerId;\n /** Timer ID for the maximum wait limit */\n maxTimerId?: TimerId;\n /** Timestamp of the last function call */\n lastCallTime?: number;\n /** Timestamp of the last successful function invocation */\n lastInvokeTime: number;\n /** Arguments from the most recent function call */\n lastArgs?: Parameters<T>;\n /** Execution context (this) from the most recent call */\n lastThis?: any;\n /** Result from the last function execution */\n result?: Awaited<ReturnType<T>>;\n /** Array of pending promises waiting for resolution */\n pendingPromises: Array<{\n resolve: (value: Awaited<ReturnType<T>>) => void;\n reject: (reason?: any) => void;\n }>;\n /** Flag indicating if the function has been aborted */\n aborted: boolean;\n}\n\n/** WeakMap to store private state for each debounced function */\nconst privateState = new WeakMap<DebouncedFunction<any>, PrivateState<any>>();\n\n/**\n * Creates a logger instance based on debug flag\n * @param debug - Whether debug logging is enabled\n * @returns Object with logging methods\n * @private\n */\nconst createLogger = (debug: boolean) => ({\n log: (...args: any[]) => debug && console.log('[Debounce]', ...args),\n warn: (...args: any[]) => debug && console.warn('[Debounce]', ...args),\n error: (...args: any[]) => debug && console.error('[Debounce]', ...args),\n});\n\n/**\n * Creates a debounced version of the provided function that delays invoking func until after\n * wait milliseconds have elapsed since the last time the debounced function was invoked.\n *\n * @template T - The type of the function to debounce\n * @param {T} func - The function to debounce\n * @param {DebounceOptions} [options={}] - Configuration options\n * @returns {DebouncedFunction<T>} The debounced function\n * @throws {TypeError} If func is not a function\n * @throws {RangeError} If wait or maxWait values are invalid\n * @throws {Error} If neither leading nor trailing is true\n *\n * @example\n * const debouncedFn = debounce(async (x: number) => x * 2, { wait: 1000 });\n * await debouncedFn(5); // Will execute after 1000ms of inactivity\n * const debouncedFn = debounce(\n * async (x: number) => x * 2,\n * {\n * wait: 1000,\n * onError: (error) => console.error('Error in debounced function:', error)\n * }\n * );\n */\nfunction debounce<T extends AnyFunction>(\n func: T,\n options: DebounceOptions = {},\n): DebouncedFunction<T> {\n // Input validation\n if (typeof func !== 'function') {\n throw new TypeError('Expected a function');\n }\n\n const {\n wait = 0,\n leading = false,\n trailing = true,\n maxWait,\n debug = false,\n signal,\n onError,\n } = options;\n\n // Validate options\n if (wait < 0 || (maxWait !== undefined && maxWait < wait)) {\n throw new RangeError('Invalid wait/maxWait values');\n }\n\n if (!leading && !trailing) {\n throw new Error('At least one of leading or trailing must be true');\n }\n\n const logger = createLogger(debug);\n const state: PrivateState<T> = {\n lastInvokeTime: 0,\n pendingPromises: [],\n aborted: false,\n };\n\n // Setup abort controller handling\n if (signal) {\n signal.addEventListener('abort', () => {\n state.aborted = true;\n cancel();\n });\n }\n\n /**\n * Cancels all active timers\n * @private\n */\n function cancelTimers(): void {\n if (state.timerId !== undefined) {\n clearTimeout(state.timerId);\n state.timerId = undefined;\n logger.log('Cleared debounce timer');\n }\n if (state.maxTimerId !== undefined) {\n clearTimeout(state.maxTimerId);\n state.maxTimerId = undefined;\n logger.log('Cleared max wait timer');\n }\n }\n\n /**\n * Cancels any pending function invocations\n * Rejects all pending promises and resets internal state\n */\n function cancel(): void {\n logger.log('Cancelling pending invocations');\n cancelTimers();\n state.lastInvokeTime = 0;\n state.lastArgs = undefined;\n state.lastThis = undefined;\n state.lastCallTime = undefined;\n const error = new Error('Debounced function cancelled');\n handleError(error);\n state.pendingPromises.forEach(({ reject }) =>\n reject(new Error('Debounced function cancelled')),\n );\n state.pendingPromises = [];\n }\n\n /**\n * Handles errors during function execution\n * @param {Error} error - The error that occurred\n * @private\n */\n function handleError(error: Error): void {\n logger.error('Error occurred:', error);\n if (onError) {\n try {\n onError(error);\n } catch (callbackError) {\n logger.error('Error in onError callback:', callbackError);\n }\n }\n }\n\n /**\n * Checks if there are any pending function invocations\n * @returns {boolean} True if there are pending invocations\n */\n function pending(): boolean {\n return state.timerId !== undefined;\n }\n\n /**\n * Determines if the function should be invoked based on timing conditions\n * @param {number} time - Current timestamp\n * @returns {boolean} True if function should be invoked\n * @private\n */\n function shouldInvoke(time: number): boolean {\n if (state.aborted) return false;\n\n const timeSinceLastCall = state.lastCallTime === undefined ? 0 : time - state.lastCallTime;\n const timeSinceLastInvoke = time - state.lastInvokeTime;\n\n return (\n state.lastCallTime === undefined ||\n timeSinceLastCall >= wait ||\n timeSinceLastCall < 0 ||\n (maxWait !== undefined && timeSinceLastInvoke >= maxWait)\n );\n }\n\n /**\n * Executes the underlying function and manages promise resolution\n * @param {number} time - Current timestamp\n * @returns {Promise} Promise resolving to function result\n * @private\n */\n async function invokeFunc(time: number): Promise<Awaited<ReturnType<T>> | void> {\n logger.log(`Invoking function at ${time}`);\n state.lastInvokeTime = time;\n const args = state.lastArgs!;\n const thisArg = state.lastThis;\n\n state.lastArgs = undefined;\n state.lastThis = undefined;\n\n try {\n const result = await func.apply(thisArg, args);\n state.result = result;\n state.pendingPromises.forEach(({ resolve }) => resolve(result));\n state.pendingPromises = [];\n logger.log('Function invoked successfully', result);\n return result;\n } catch (error) {\n const wrappedError = error instanceof Error ? error : new Error(String(error));\n logger.error('Error in function invocation:', wrappedError);\n handleError(wrappedError);\n\n // Clear pending promises after handling error\n const currentPromises = [...state.pendingPromises];\n state.pendingPromises = [];\n\n // Reject all pending promises\n currentPromises.forEach(({ reject }) => reject(wrappedError));\n }\n }\n\n /**\n * Starts both the debounce timer and maxWait timer if configured\n * @param {number} time - Current timestamp\n * @private\n */\n function startTimer(time: number): void {\n const remainingTime = remainingWait(time);\n state.timerId = setTimeout(timerExpired, remainingTime);\n logger.log(`Started debounce timer for ${remainingTime}ms`);\n\n if (maxWait !== undefined && !state.maxTimerId) {\n const timeToMaxWait = maxWait - (time - state.lastCallTime!);\n state.maxTimerId = setTimeout(\n () => {\n logger.log('Max wait timer expired');\n cancelTimers();\n invokeFunc(Date.now());\n },\n Math.max(0, timeToMaxWait),\n );\n logger.log(`Started max wait timer for ${timeToMaxWait}ms`);\n }\n }\n\n /**\n * Calculates remaining wait time before next execution\n * @param {number} time - Current timestamp\n * @returns {number} Milliseconds until next allowed execution\n * @private\n */\n function remainingWait(time: number): number {\n const timeSinceLastCall = state.lastCallTime ? time - state.lastCallTime : 0;\n return Math.max(0, wait - timeSinceLastCall);\n }\n\n /**\n * Handles timer expiration\n * @private\n */\n function timerExpired(): void {\n const time = Date.now();\n logger.log('Debounce timer expired');\n\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n\n startTimer(time);\n }\n\n /**\n * Handles leading edge execution\n * @param {number} time - Current timestamp\n * @private\n */\n function leadingEdge(time: number): void {\n logger.log('Leading edge triggered');\n state.lastInvokeTime = time;\n startTimer(time);\n\n if (leading) {\n invokeFunc(time);\n }\n }\n\n /**\n * Handles trailing edge execution\n * @param {number} time - Current timestamp\n * @private\n */\n function trailingEdge(time: number): void {\n logger.log('Trailing edge triggered');\n cancelTimers();\n\n if (trailing && state.lastArgs) {\n invokeFunc(time);\n } else {\n state.pendingPromises.forEach(({ resolve }) => {\n resolve(state.result as Awaited<ReturnType<T>>);\n });\n state.pendingPromises = [];\n }\n }\n\n /**\n * Immediately executes the debounced function\n * @param {...Parameters<T>} args - Function arguments\n * @returns {Promise<ReturnType<T>>} Promise resolving to function result\n */\n async function flush(...args: Parameters<T>): Promise<Awaited<ReturnType<T>> | void> {\n logger.log('Flush requested');\n const argsToUse = args.length > 0 ? args : state.lastArgs;\n const thisArg = state.lastThis;\n\n cancelTimers();\n\n if (argsToUse) {\n state.lastArgs = argsToUse;\n state.lastThis = thisArg;\n return invokeFunc(Date.now());\n }\n\n return Promise.resolve(state.result!);\n }\n\n /**\n * Cleans up resources used by the debounced function\n */\n function cleanup(): void {\n logger.log('Cleanup initiated');\n cancel();\n privateState.delete(debounced);\n }\n\n /**\n * The debounced function that wraps the original\n * @param {...Parameters<T>} args - Function arguments\n * @returns {Promise<ReturnType<T>>} Promise resolving to function result\n */\n const debounced = function(\n this: any,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n if (state.aborted) {\n return Promise.reject(new Error('Debounced function aborted'));\n }\n\n const time = Date.now();\n const isInvoking = shouldInvoke(time);\n\n state.lastArgs = args;\n state.lastThis = this;\n state.lastCallTime = time;\n\n logger.log('Function called', {\n time,\n isInvoking,\n args,\n pending: pending(),\n });\n\n return new Promise((resolve, reject) => {\n state.pendingPromises.push({ resolve, reject });\n\n if (state.timerId === undefined) {\n leadingEdge(time);\n } else {\n cancelTimers();\n startTimer(time);\n }\n });\n } as DebouncedFunction<T>;\n\n // Store private state\n privateState.set(debounced, state);\n\n // Add utility methods\n Object.defineProperties(debounced, {\n cancel: { value: cancel, writable: false, configurable: false },\n flush: { value: flush, writable: false, configurable: false },\n pending: { value: pending, writable: false, configurable: false },\n cleanup: { value: cleanup, writable: false, configurable: false },\n });\n\n return debounced;\n}\n\nexport { debounce, type DebouncedFunction, type DebounceOptions };\n"],"names":["__webpack_require__","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","privateState","WeakMap","createLogger","debug","log","args","console","warn","error","debounce","func","options","TypeError","wait","leading","trailing","maxWait","signal","onError","undefined","RangeError","Error","logger","state","lastInvokeTime","pendingPromises","aborted","cancelTimers","timerId","clearTimeout","maxTimerId","cancel","lastArgs","lastThis","lastCallTime","handleError","forEach","reject","callbackError","pending","shouldInvoke","time","timeSinceLastCall","async","invokeFunc","thisArg","result","apply","resolve","wrappedError","String","currentPromises","startTimer","remainingTime","Math","max","remainingWait","setTimeout","timerExpired","timeToMaxWait","Date","now","trailingEdge","addEventListener","debounced","Promise","isInvoking","this","push","leadingEdge","set","defineProperties","writable","configurable","flush","argsToUse","length","cleanup","delete"],"sourceRoot":""}
|