@alwatr/debounce 1.1.7 โ 1.1.9
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/CHANGELOG.md +10 -0
- package/dist/main.cjs +2 -2
- package/dist/main.mjs +2 -2
- package/package.json +8 -7
- package/src/debounce.test.js +0 -388
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.1.9](https://github.com/Alwatr/nanolib/compare/@alwatr/debounce@1.1.8...@alwatr/debounce@1.1.9) (2025-09-27)
|
|
7
|
+
|
|
8
|
+
### ๐งน Miscellaneous Chores
|
|
9
|
+
|
|
10
|
+
* exclude test files from package distribution ([86f4f2f](https://github.com/Alwatr/nanolib/commit/86f4f2f5985845c5cf3a3a9398de7b2f98ce53e7))
|
|
11
|
+
|
|
12
|
+
## [1.1.8](https://github.com/Alwatr/nanolib/compare/@alwatr/debounce@1.1.7...@alwatr/debounce@1.1.8) (2025-09-22)
|
|
13
|
+
|
|
14
|
+
**Note:** Version bump only for package @alwatr/debounce
|
|
15
|
+
|
|
6
16
|
## [1.1.7](https://github.com/Alwatr/nanolib/compare/@alwatr/debounce@1.1.6...@alwatr/debounce@1.1.7) (2025-09-22)
|
|
7
17
|
|
|
8
18
|
**Note:** Version bump only for package @alwatr/debounce
|
package/dist/main.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** ๐ฆ @alwatr/debounce v1.1.
|
|
2
|
-
__dev_mode__: console.debug("๐ฆ @alwatr/debounce v1.1.
|
|
1
|
+
/** ๐ฆ @alwatr/debounce v1.1.9 */
|
|
2
|
+
__dev_mode__: console.debug("๐ฆ @alwatr/debounce v1.1.9");
|
|
3
3
|
"use strict";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:true}),mod);var main_exports={};__export(main_exports,{Debouncer:()=>Debouncer,createDebouncer:()=>createDebouncer});module.exports=__toCommonJS(main_exports);var Debouncer=class{constructor(config__){this.config__=config__;this.config__.trailing??=true;this.flush=this.flush.bind(this)}get isPending(){return this.timerId__!==void 0}trigger(...args){this.lastArgs__=args;const firstTrigger=!this.isPending;if(firstTrigger){if(this.config__.maxWait){this.maxWaitTimerId__=setTimeout(this.flush,this.config__.maxWait)}if(this.config__.leading===true){this.invoke__()}}else{clearTimeout(this.timerId__)}this.timerId__=setTimeout(()=>{if(this.config__.trailing===true){this.invoke__()}this.cleanup__()},this.config__.delay)}cancel(){if(this.timerId__){clearTimeout(this.timerId__)}if(this.maxWaitTimerId__){clearTimeout(this.maxWaitTimerId__)}this.cleanup__()}cleanup__(){delete this.timerId__;delete this.maxWaitTimerId__;delete this.lastArgs__}flush(){if(this.isPending){this.invoke__()}this.cancel()}invoke__(){if(this.lastArgs__){this.config__.func.apply(this.config__.thisContext,this.lastArgs__);this.lastArgs__=void 0}}};function createDebouncer(config){return new Debouncer(config)}0&&(module.exports={Debouncer,createDebouncer});
|
|
4
4
|
//# sourceMappingURL=main.cjs.map
|
package/dist/main.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** ๐ฆ @alwatr/debounce v1.1.
|
|
2
|
-
__dev_mode__: console.debug("๐ฆ @alwatr/debounce v1.1.
|
|
1
|
+
/** ๐ฆ @alwatr/debounce v1.1.9 */
|
|
2
|
+
__dev_mode__: console.debug("๐ฆ @alwatr/debounce v1.1.9");
|
|
3
3
|
var Debouncer=class{constructor(config__){this.config__=config__;this.config__.trailing??=true;this.flush=this.flush.bind(this)}get isPending(){return this.timerId__!==void 0}trigger(...args){this.lastArgs__=args;const firstTrigger=!this.isPending;if(firstTrigger){if(this.config__.maxWait){this.maxWaitTimerId__=setTimeout(this.flush,this.config__.maxWait)}if(this.config__.leading===true){this.invoke__()}}else{clearTimeout(this.timerId__)}this.timerId__=setTimeout(()=>{if(this.config__.trailing===true){this.invoke__()}this.cleanup__()},this.config__.delay)}cancel(){if(this.timerId__){clearTimeout(this.timerId__)}if(this.maxWaitTimerId__){clearTimeout(this.maxWaitTimerId__)}this.cleanup__()}cleanup__(){delete this.timerId__;delete this.maxWaitTimerId__;delete this.lastArgs__}flush(){if(this.isPending){this.invoke__()}this.cancel()}invoke__(){if(this.lastArgs__){this.config__.func.apply(this.config__.thisContext,this.lastArgs__);this.lastArgs__=void 0}}};function createDebouncer(config){return new Debouncer(config)}export{Debouncer,createDebouncer};
|
|
4
4
|
//# sourceMappingURL=main.mjs.map
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alwatr/debounce",
|
|
3
3
|
"description": "A powerful, modern, and type-safe debouncer utility designed for high-performance applications. It's framework-agnostic, works seamlessly in both Node.js and browsers, and provides a rich API for fine-grained control over function execution.",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.9",
|
|
5
5
|
"author": "S. Ali Mihandoost <ali.mihandoost@gmail.com>",
|
|
6
6
|
"bugs": "https://github.com/Alwatr/nanolib/issues",
|
|
7
7
|
"devDependencies": {
|
|
8
|
-
"@alwatr/nano-build": "6.3.
|
|
9
|
-
"@alwatr/prettier-config": "5.0.
|
|
10
|
-
"@alwatr/tsconfig-base": "6.0.
|
|
11
|
-
"@alwatr/type-helper": "6.1.
|
|
8
|
+
"@alwatr/nano-build": "6.3.4",
|
|
9
|
+
"@alwatr/prettier-config": "5.0.5",
|
|
10
|
+
"@alwatr/tsconfig-base": "6.0.3",
|
|
11
|
+
"@alwatr/type-helper": "6.1.4",
|
|
12
12
|
"@jest/globals": "^30.1.2",
|
|
13
13
|
"@types/node": "^22.18.6",
|
|
14
14
|
"typescript": "^5.9.2"
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"files": [
|
|
24
24
|
"**/*.{js,mjs,cjs,map,d.ts,html,md,LEGAL.txt}",
|
|
25
25
|
"LICENSE",
|
|
26
|
-
"!demo/**/*"
|
|
26
|
+
"!demo/**/*",
|
|
27
|
+
"!**/*.test.js"
|
|
27
28
|
],
|
|
28
29
|
"homepage": "https://github.com/Alwatr/nanolib/tree/next/packages/debounce#readme",
|
|
29
30
|
"keywords": [
|
|
@@ -79,5 +80,5 @@
|
|
|
79
80
|
"sideEffects": false,
|
|
80
81
|
"type": "module",
|
|
81
82
|
"types": "./dist/main.d.ts",
|
|
82
|
-
"gitHead": "
|
|
83
|
+
"gitHead": "c013ded43aff3937cf347de4e99125ab807d99e1"
|
|
83
84
|
}
|
package/src/debounce.test.js
DELETED
|
@@ -1,388 +0,0 @@
|
|
|
1
|
-
import {describe, beforeEach, afterEach, it, expect, jest} from '@jest/globals';
|
|
2
|
-
import {createDebouncer} from '@alwatr/debounce';
|
|
3
|
-
|
|
4
|
-
describe('Debouncer', () => {
|
|
5
|
-
/**
|
|
6
|
-
* @type {import("jest-mock").Mock<import("jest-mock").UnknownFunction>}
|
|
7
|
-
*/
|
|
8
|
-
let mockFunc;
|
|
9
|
-
/**
|
|
10
|
-
* @type {import("@alwatr/debounce").Debouncer<typeof mockFunc>}
|
|
11
|
-
*/
|
|
12
|
-
let debouncer;
|
|
13
|
-
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
mockFunc = jest.fn();
|
|
16
|
-
jest.useFakeTimers();
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
afterEach(() => {
|
|
20
|
-
jest.clearAllTimers();
|
|
21
|
-
jest.useRealTimers();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
describe('Basic Trailing Debounce (default)', () => {
|
|
25
|
-
beforeEach(() => {
|
|
26
|
-
debouncer = createDebouncer({
|
|
27
|
-
func: mockFunc,
|
|
28
|
-
delay: 300,
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('should execute after delay on single trigger', () => {
|
|
33
|
-
debouncer.trigger('test');
|
|
34
|
-
expect(mockFunc).not.toHaveBeenCalled();
|
|
35
|
-
jest.advanceTimersByTime(300);
|
|
36
|
-
expect(mockFunc).toHaveBeenCalledWith('test');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('should reset delay on multiple triggers', () => {
|
|
40
|
-
debouncer.trigger('first');
|
|
41
|
-
jest.advanceTimersByTime(200);
|
|
42
|
-
debouncer.trigger('second');
|
|
43
|
-
jest.advanceTimersByTime(200);
|
|
44
|
-
expect(mockFunc).not.toHaveBeenCalled();
|
|
45
|
-
jest.advanceTimersByTime(100);
|
|
46
|
-
expect(mockFunc).toHaveBeenCalledWith('second');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('should not execute if cancelled before delay', () => {
|
|
50
|
-
debouncer.trigger('test');
|
|
51
|
-
debouncer.cancel();
|
|
52
|
-
jest.advanceTimersByTime(300);
|
|
53
|
-
expect(mockFunc).not.toHaveBeenCalled();
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
describe('Leading Debounce', () => {
|
|
58
|
-
beforeEach(() => {
|
|
59
|
-
debouncer = createDebouncer({
|
|
60
|
-
func: mockFunc,
|
|
61
|
-
delay: 300,
|
|
62
|
-
leading: true,
|
|
63
|
-
trailing: false,
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('should execute immediately on first trigger', () => {
|
|
68
|
-
debouncer.trigger('test');
|
|
69
|
-
expect(mockFunc).toHaveBeenCalledWith('test');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('should not execute again within delay', () => {
|
|
73
|
-
debouncer.trigger('first');
|
|
74
|
-
expect(mockFunc).toHaveBeenCalledTimes(1);
|
|
75
|
-
debouncer.trigger('second');
|
|
76
|
-
jest.advanceTimersByTime(300);
|
|
77
|
-
expect(mockFunc).toHaveBeenCalledTimes(1);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should execute again after delay', () => {
|
|
81
|
-
debouncer.trigger('first');
|
|
82
|
-
jest.advanceTimersByTime(300);
|
|
83
|
-
debouncer.trigger('second');
|
|
84
|
-
expect(mockFunc).toHaveBeenCalledTimes(2);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
describe('Both Leading and Trailing', () => {
|
|
89
|
-
beforeEach(() => {
|
|
90
|
-
debouncer = createDebouncer({
|
|
91
|
-
func: mockFunc,
|
|
92
|
-
delay: 300,
|
|
93
|
-
leading: true,
|
|
94
|
-
trailing: true,
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('should execute immediately but not after delay on single trigger', () => {
|
|
99
|
-
debouncer.trigger('test');
|
|
100
|
-
expect(mockFunc).toHaveBeenCalledWith('test');
|
|
101
|
-
jest.advanceTimersByTime(300);
|
|
102
|
-
expect(mockFunc).toHaveBeenCalledTimes(1);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('should execute immediately, then trailing on last trigger', () => {
|
|
106
|
-
debouncer.trigger('first');
|
|
107
|
-
expect(mockFunc).toHaveBeenCalledTimes(1);
|
|
108
|
-
expect(mockFunc).toHaveBeenCalledWith('first');
|
|
109
|
-
jest.advanceTimersByTime(200);
|
|
110
|
-
debouncer.trigger('second');
|
|
111
|
-
jest.advanceTimersByTime(100);
|
|
112
|
-
debouncer.trigger('third');
|
|
113
|
-
jest.advanceTimersByTime(100);
|
|
114
|
-
expect(mockFunc).toHaveBeenCalledTimes(1);
|
|
115
|
-
jest.advanceTimersByTime(300);
|
|
116
|
-
expect(mockFunc).toHaveBeenCalledTimes(2);
|
|
117
|
-
expect(mockFunc).toHaveBeenLastCalledWith('third');
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
describe('Cancel Functionality', () => {
|
|
122
|
-
beforeEach(() => {
|
|
123
|
-
debouncer = createDebouncer({
|
|
124
|
-
func: mockFunc,
|
|
125
|
-
delay: 300,
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should cancel pending execution', () => {
|
|
130
|
-
debouncer.trigger('test');
|
|
131
|
-
expect(debouncer.isPending).toBe(true);
|
|
132
|
-
debouncer.cancel();
|
|
133
|
-
expect(debouncer.isPending).toBe(false);
|
|
134
|
-
jest.advanceTimersByTime(300);
|
|
135
|
-
expect(mockFunc).not.toHaveBeenCalled();
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it('should handle cancel on leading debounce', () => {
|
|
139
|
-
debouncer = createDebouncer({
|
|
140
|
-
func: mockFunc,
|
|
141
|
-
delay: 300,
|
|
142
|
-
leading: true,
|
|
143
|
-
});
|
|
144
|
-
debouncer.trigger('test');
|
|
145
|
-
expect(mockFunc).toHaveBeenCalledTimes(1);
|
|
146
|
-
debouncer.cancel();
|
|
147
|
-
jest.advanceTimersByTime(300);
|
|
148
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // No trailing call
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
describe('Flush Functionality', () => {
|
|
153
|
-
beforeEach(() => {
|
|
154
|
-
debouncer = createDebouncer({
|
|
155
|
-
func: mockFunc,
|
|
156
|
-
delay: 300,
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it('should execute immediately and cancel pending', () => {
|
|
161
|
-
debouncer.trigger('test');
|
|
162
|
-
expect(mockFunc).not.toHaveBeenCalled();
|
|
163
|
-
debouncer.flush();
|
|
164
|
-
expect(mockFunc).toHaveBeenCalledWith('test');
|
|
165
|
-
expect(debouncer.isPending).toBe(false);
|
|
166
|
-
jest.advanceTimersByTime(300);
|
|
167
|
-
expect(mockFunc).toHaveBeenCalledTimes(1);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it('should do nothing if no pending call', () => {
|
|
171
|
-
debouncer.flush();
|
|
172
|
-
expect(mockFunc).not.toHaveBeenCalled();
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
describe('MaxWait Functionality', () => {
|
|
177
|
-
beforeEach(() => {
|
|
178
|
-
debouncer = createDebouncer({
|
|
179
|
-
func: mockFunc,
|
|
180
|
-
delay: 300,
|
|
181
|
-
maxWait: 1000,
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
it('should execute after maxWait even with continuous triggers', () => {
|
|
186
|
-
debouncer.trigger('first');
|
|
187
|
-
jest.advanceTimersByTime(500);
|
|
188
|
-
debouncer.trigger('second');
|
|
189
|
-
jest.advanceTimersByTime(500);
|
|
190
|
-
expect(mockFunc).toHaveBeenCalledWith('first'); // After maxWait
|
|
191
|
-
debouncer.trigger('third');
|
|
192
|
-
jest.advanceTimersByTime(300);
|
|
193
|
-
expect(mockFunc).toHaveBeenCalledWith('third');
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
describe('ThisContext Binding', () => {
|
|
198
|
-
/**
|
|
199
|
-
* @type {{ value: string; }}
|
|
200
|
-
*/
|
|
201
|
-
let context;
|
|
202
|
-
|
|
203
|
-
beforeEach(() => {
|
|
204
|
-
context = {value: 'test'};
|
|
205
|
-
mockFunc = jest.fn(function () {
|
|
206
|
-
this.value = 'changed';
|
|
207
|
-
});
|
|
208
|
-
debouncer = createDebouncer({
|
|
209
|
-
func: mockFunc,
|
|
210
|
-
thisContext: context,
|
|
211
|
-
delay: 300,
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
it('should bind thisContext correctly', () => {
|
|
216
|
-
debouncer.trigger();
|
|
217
|
-
jest.advanceTimersByTime(300);
|
|
218
|
-
expect(context.value).toBe('changed');
|
|
219
|
-
});
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
describe('Edge Cases', () => {
|
|
223
|
-
it('should handle zero delay', () => {
|
|
224
|
-
debouncer = createDebouncer({
|
|
225
|
-
func: mockFunc,
|
|
226
|
-
delay: 0,
|
|
227
|
-
});
|
|
228
|
-
debouncer.trigger('test');
|
|
229
|
-
jest.advanceTimersByTime(0);
|
|
230
|
-
expect(mockFunc).toHaveBeenCalledWith('test');
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it('should handle no arguments', () => {
|
|
234
|
-
debouncer = createDebouncer({
|
|
235
|
-
func: mockFunc,
|
|
236
|
-
delay: 300,
|
|
237
|
-
});
|
|
238
|
-
debouncer.trigger();
|
|
239
|
-
jest.advanceTimersByTime(300);
|
|
240
|
-
expect(mockFunc).toHaveBeenCalledWith();
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
it('should handle multiple arguments', () => {
|
|
244
|
-
debouncer = createDebouncer({
|
|
245
|
-
func: mockFunc,
|
|
246
|
-
delay: 300,
|
|
247
|
-
});
|
|
248
|
-
debouncer.trigger('arg1', 'arg2', 123);
|
|
249
|
-
jest.advanceTimersByTime(300);
|
|
250
|
-
expect(mockFunc).toHaveBeenCalledWith('arg1', 'arg2', 123);
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
it('should not execute if func throws', () => {
|
|
254
|
-
mockFunc = jest.fn(() => {
|
|
255
|
-
throw new Error('test');
|
|
256
|
-
});
|
|
257
|
-
debouncer = createDebouncer({
|
|
258
|
-
func: mockFunc,
|
|
259
|
-
delay: 300,
|
|
260
|
-
});
|
|
261
|
-
debouncer.trigger();
|
|
262
|
-
expect(() => jest.advanceTimersByTime(300)).toThrow('test');
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
it('should double-invocation with leading: true, trailing: false, and maxWait on multiple trigger', () => {
|
|
266
|
-
debouncer = createDebouncer({
|
|
267
|
-
func: mockFunc,
|
|
268
|
-
delay: 300,
|
|
269
|
-
leading: true,
|
|
270
|
-
trailing: false,
|
|
271
|
-
maxWait: 500,
|
|
272
|
-
});
|
|
273
|
-
debouncer.trigger('first');
|
|
274
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // Leading call
|
|
275
|
-
jest.advanceTimersByTime(200);
|
|
276
|
-
debouncer.trigger('second');
|
|
277
|
-
jest.advanceTimersByTime(200);
|
|
278
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // Should not call again yet
|
|
279
|
-
jest.advanceTimersByTime(200); // Trigger maxWait, which may call flush
|
|
280
|
-
expect(mockFunc).toHaveBeenCalledTimes(2); // Should be called a second time due to maxWait
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
it('should prevent double-invocation with leading: true, trailing: false, and maxWait on single trigger', () => {
|
|
284
|
-
debouncer = createDebouncer({
|
|
285
|
-
func: mockFunc,
|
|
286
|
-
delay: 300,
|
|
287
|
-
leading: true,
|
|
288
|
-
trailing: false,
|
|
289
|
-
maxWait: 200,
|
|
290
|
-
});
|
|
291
|
-
debouncer.trigger('first');
|
|
292
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // Leading call
|
|
293
|
-
jest.advanceTimersByTime(300);
|
|
294
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // Should not call again
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
it('should prevent double-invocation with leading: true, trailing: false, and flush', () => {
|
|
298
|
-
debouncer = createDebouncer({
|
|
299
|
-
func: mockFunc,
|
|
300
|
-
delay: 300,
|
|
301
|
-
leading: true,
|
|
302
|
-
trailing: false,
|
|
303
|
-
});
|
|
304
|
-
debouncer.trigger('first');
|
|
305
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // Leading call
|
|
306
|
-
jest.advanceTimersByTime(100);
|
|
307
|
-
debouncer.flush();
|
|
308
|
-
debouncer.flush();
|
|
309
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // Should not call again
|
|
310
|
-
});
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
it('should execute after delay for trailing debounce', () => {
|
|
314
|
-
debouncer = createDebouncer({
|
|
315
|
-
func: mockFunc,
|
|
316
|
-
delay: 300,
|
|
317
|
-
leading: false,
|
|
318
|
-
trailing: true,
|
|
319
|
-
});
|
|
320
|
-
debouncer.trigger('first');
|
|
321
|
-
expect(mockFunc).toHaveBeenCalledTimes(0); // No call yet
|
|
322
|
-
jest.advanceTimersByTime(300);
|
|
323
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // Trailing call
|
|
324
|
-
});
|
|
325
|
-
it('should execute leading but skip trailing on single trigger', () => {
|
|
326
|
-
debouncer = createDebouncer({
|
|
327
|
-
func: mockFunc,
|
|
328
|
-
delay: 300,
|
|
329
|
-
leading: true,
|
|
330
|
-
trailing: true,
|
|
331
|
-
});
|
|
332
|
-
debouncer.trigger('first');
|
|
333
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // leading call
|
|
334
|
-
jest.advanceTimersByTime(300);
|
|
335
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // no trailing call on same argument
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
it('should execute leading and skip trailing after flush', () => {
|
|
339
|
-
debouncer = createDebouncer({
|
|
340
|
-
func: mockFunc,
|
|
341
|
-
delay: 300,
|
|
342
|
-
leading: true,
|
|
343
|
-
trailing: true,
|
|
344
|
-
});
|
|
345
|
-
debouncer.trigger('first');
|
|
346
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // leading call
|
|
347
|
-
jest.advanceTimersByTime(100);
|
|
348
|
-
debouncer.flush();
|
|
349
|
-
jest.advanceTimersByTime(100);
|
|
350
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // no trailing call on same argument
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
it('should execute leading and trailing on multiple triggers', () => {
|
|
354
|
-
debouncer = createDebouncer({
|
|
355
|
-
func: mockFunc,
|
|
356
|
-
delay: 300,
|
|
357
|
-
leading: true,
|
|
358
|
-
trailing: true,
|
|
359
|
-
});
|
|
360
|
-
debouncer.trigger('first');
|
|
361
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // leading call
|
|
362
|
-
debouncer.trigger('second');
|
|
363
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // No call again yet
|
|
364
|
-
jest.advanceTimersByTime(300);
|
|
365
|
-
expect(mockFunc).toHaveBeenCalledTimes(2); // Trailing call
|
|
366
|
-
expect(mockFunc).toHaveBeenLastCalledWith('second');
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
it('should execute leading and flush, skip trailing', () => {
|
|
370
|
-
debouncer = createDebouncer({
|
|
371
|
-
func: mockFunc,
|
|
372
|
-
delay: 300,
|
|
373
|
-
leading: true,
|
|
374
|
-
trailing: false,
|
|
375
|
-
});
|
|
376
|
-
debouncer.trigger('first');
|
|
377
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // leading call
|
|
378
|
-
debouncer.trigger('second');
|
|
379
|
-
expect(mockFunc).toHaveBeenCalledTimes(1); // No call again yet
|
|
380
|
-
debouncer.flush();
|
|
381
|
-
debouncer.flush();
|
|
382
|
-
expect(mockFunc).toHaveBeenCalledTimes(2);
|
|
383
|
-
expect(mockFunc).toHaveBeenLastCalledWith('second');
|
|
384
|
-
jest.advanceTimersByTime(300);
|
|
385
|
-
debouncer.flush();
|
|
386
|
-
expect(mockFunc).toHaveBeenCalledTimes(2); // no trailing call
|
|
387
|
-
});
|
|
388
|
-
});
|