@avatijs/debounce 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +232 -0
- package/README.md +242 -0
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/debouce.d.ts +72 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/types/debouce.d.ts +72 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/umd/index.js +8 -0
- package/dist/umd/index.js.map +1 -0
- package/package.json +135 -0
package/CHANGELOG.md
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
# Advanced TypeScript Debounce Utility
|
2
|
+
|
3
|
+
A highly configurable debounce utility with TypeScript support, providing features like leading/trailing edge execution, cancellation, immediate flush, maximum wait time, and proper Promise handling.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
- ๐ฏ Configurable leading/trailing edge execution
|
8
|
+
- ๐ซ Cancelable debounced functions
|
9
|
+
- โก Immediate flush capability
|
10
|
+
- โฑ๏ธ Maximum wait time option
|
11
|
+
- ๐ Promise-based return values
|
12
|
+
- ๐ญ AbortController support
|
13
|
+
- ๐ Debug mode
|
14
|
+
- ๐ Comprehensive TypeScript types
|
15
|
+
- ๐งน Proper cleanup utilities
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
```bash
|
20
|
+
npm install @your-org/debounce-utility
|
21
|
+
```
|
22
|
+
|
23
|
+
## Basic Usage
|
24
|
+
|
25
|
+
```typescript
|
26
|
+
import { debounce } from '@your-org/debounce-utility';
|
27
|
+
|
28
|
+
// Simple debounce
|
29
|
+
const debouncedFn = debounce(async (x: number) => x * 2, {
|
30
|
+
wait: 1000,
|
31
|
+
});
|
32
|
+
|
33
|
+
// Call the debounced function
|
34
|
+
await debouncedFn(5); // Will execute after 1000ms
|
35
|
+
|
36
|
+
// With debug logging
|
37
|
+
const debuggedFn = debounce(async (x: number) => x * 2, {
|
38
|
+
wait: 1000,
|
39
|
+
debug: true,
|
40
|
+
});
|
41
|
+
|
42
|
+
// With abort controller
|
43
|
+
const controller = new AbortController();
|
44
|
+
const abortableFn = debounce(async (x: number) => x * 2, {
|
45
|
+
wait: 1000,
|
46
|
+
signal: controller.signal,
|
47
|
+
});
|
48
|
+
|
49
|
+
// Cleanup when done
|
50
|
+
debouncedFn.cleanup();
|
51
|
+
```
|
52
|
+
|
53
|
+
## API Reference
|
54
|
+
|
55
|
+
### `debounce<T>(func: T, options?: DebounceOptions): DebouncedFunction<T>`
|
56
|
+
|
57
|
+
Creates a debounced version of the provided function.
|
58
|
+
|
59
|
+
#### Parameters
|
60
|
+
|
61
|
+
##### `func: T`
|
62
|
+
|
63
|
+
The function to debounce. Can be synchronous or asynchronous.
|
64
|
+
|
65
|
+
##### `options: DebounceOptions`
|
66
|
+
|
67
|
+
Configuration options for the debounced function.
|
68
|
+
|
69
|
+
```typescript
|
70
|
+
interface DebounceOptions {
|
71
|
+
readonly wait?: number; // Delay in milliseconds (default: 0)
|
72
|
+
readonly leading?: boolean; // Execute on leading edge (default: false)
|
73
|
+
readonly trailing?: boolean; // Execute on trailing edge (default: true)
|
74
|
+
readonly maxWait?: number; // Maximum time to wait
|
75
|
+
readonly debug?: boolean; // Enable debug logging (default: false)
|
76
|
+
readonly signal?: AbortSignal; // AbortController signal
|
77
|
+
}
|
78
|
+
```
|
79
|
+
|
80
|
+
#### Returns
|
81
|
+
|
82
|
+
Returns a debounced function with the following interface:
|
83
|
+
|
84
|
+
```typescript
|
85
|
+
interface DebouncedFunction<T> {
|
86
|
+
(...args: Parameters<T>): Promise<Awaited<ReturnType<T>>>;
|
87
|
+
readonly cancel: () => void;
|
88
|
+
readonly flush: (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
|
89
|
+
readonly pending: () => boolean;
|
90
|
+
readonly cleanup: () => void;
|
91
|
+
}
|
92
|
+
```
|
93
|
+
|
94
|
+
## Advanced Usage Examples
|
95
|
+
|
96
|
+
### Leading Edge Execution
|
97
|
+
|
98
|
+
```typescript
|
99
|
+
const leadingDebounce = debounce((value: string) => console.log(value), {
|
100
|
+
wait: 1000,
|
101
|
+
leading: true,
|
102
|
+
trailing: false,
|
103
|
+
});
|
104
|
+
|
105
|
+
// Executes immediately, then ignores calls for 1000ms
|
106
|
+
leadingDebounce('First');
|
107
|
+
leadingDebounce('Second'); // Ignored
|
108
|
+
leadingDebounce('Third'); // Ignored
|
109
|
+
```
|
110
|
+
|
111
|
+
### Maximum Wait Time
|
112
|
+
|
113
|
+
```typescript
|
114
|
+
const maxWaitDebounce = debounce((value: string) => console.log(value), {
|
115
|
+
wait: 1000,
|
116
|
+
maxWait: 5000,
|
117
|
+
});
|
118
|
+
|
119
|
+
// Will execute after 5000ms maximum, even if called continuously
|
120
|
+
const interval = setInterval(() => maxWaitDebounce('test'), 100);
|
121
|
+
```
|
122
|
+
|
123
|
+
### With AbortController
|
124
|
+
|
125
|
+
```typescript
|
126
|
+
const controller = new AbortController();
|
127
|
+
|
128
|
+
const abortableDebounce = debounce(
|
129
|
+
async (value: string) => {
|
130
|
+
await someAsyncOperation(value);
|
131
|
+
},
|
132
|
+
{
|
133
|
+
wait: 1000,
|
134
|
+
signal: controller.signal,
|
135
|
+
}
|
136
|
+
);
|
137
|
+
|
138
|
+
// Later, abort all pending operations
|
139
|
+
controller.abort();
|
140
|
+
```
|
141
|
+
|
142
|
+
### Debug Mode
|
143
|
+
|
144
|
+
```typescript
|
145
|
+
const debugDebounce = debounce((value: string) => console.log(value), {
|
146
|
+
wait: 1000,
|
147
|
+
debug: true,
|
148
|
+
});
|
149
|
+
|
150
|
+
// Will log detailed information about internal state
|
151
|
+
debugDebounce('test');
|
152
|
+
```
|
153
|
+
|
154
|
+
### Handling Return Values
|
155
|
+
|
156
|
+
```typescript
|
157
|
+
const asyncDebounce = debounce(
|
158
|
+
async (x: number): Promise<number> => {
|
159
|
+
await delay(100);
|
160
|
+
return x * 2;
|
161
|
+
},
|
162
|
+
{ wait: 1000 }
|
163
|
+
);
|
164
|
+
|
165
|
+
// Get the result
|
166
|
+
const result = await asyncDebounce(5);
|
167
|
+
console.log(result); // 10
|
168
|
+
```
|
169
|
+
|
170
|
+
### Cleanup
|
171
|
+
|
172
|
+
```typescript
|
173
|
+
const debouncedFn = debounce((x: number) => x * 2, { wait: 1000 });
|
174
|
+
|
175
|
+
// Use the function
|
176
|
+
debouncedFn(5);
|
177
|
+
|
178
|
+
// Clean up when done
|
179
|
+
debouncedFn.cleanup();
|
180
|
+
```
|
181
|
+
|
182
|
+
## Best Practices
|
183
|
+
|
184
|
+
1. **Always Clean Up**: Call `cleanup()` when you're done with the debounced function to prevent memory leaks:
|
185
|
+
|
186
|
+
```typescript
|
187
|
+
const debouncedFn = debounce(myFunc, { wait: 1000 });
|
188
|
+
|
189
|
+
// When done:
|
190
|
+
debouncedFn.cleanup();
|
191
|
+
```
|
192
|
+
|
193
|
+
2. **Error Handling**: Always handle potential errors in async operations:
|
194
|
+
|
195
|
+
```typescript
|
196
|
+
const debouncedFn = debounce(async () => {
|
197
|
+
try {
|
198
|
+
await debouncedOperation();
|
199
|
+
} catch (error) {
|
200
|
+
// Handle error
|
201
|
+
}
|
202
|
+
});
|
203
|
+
```
|
204
|
+
|
205
|
+
3. **TypeScript Usage**: Leverage TypeScript's type system:
|
206
|
+
|
207
|
+
```typescript
|
208
|
+
interface MyFuncParams {
|
209
|
+
id: number;
|
210
|
+
name: string;
|
211
|
+
}
|
212
|
+
|
213
|
+
const typedDebounce = debounce((params: MyFuncParams) => console.log(params), { wait: 1000 });
|
214
|
+
|
215
|
+
// TypeScript will enforce correct parameter types
|
216
|
+
typedDebounce({ id: 1, name: 'test' });
|
217
|
+
```
|
218
|
+
|
219
|
+
## Common Gotchas
|
220
|
+
|
221
|
+
1. **Memory Leaks**: Not calling `cleanup()` when done can lead to memory leaks.
|
222
|
+
2. **Shared State**: Be careful with shared state in debounced functions.
|
223
|
+
3. **Error Handling**: Always handle potential errors in async operations.
|
224
|
+
4. **Maximum Wait Time**: Setting `maxWait` less than `wait` will throw an error.
|
225
|
+
|
226
|
+
## Contributing
|
227
|
+
|
228
|
+
Contributions are welcome! Please read our [contributing guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
|
229
|
+
|
230
|
+
## License
|
231
|
+
|
232
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
package/README.md
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
# Advanced TypeScript Debounce Utility
|
2
|
+
|
3
|
+
A highly configurable debounce utility with TypeScript support, providing features like leading/trailing edge execution, cancellation, immediate flush, maximum wait time, and proper Promise handling.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
- ๐ฏ Configurable leading/trailing edge execution
|
8
|
+
- ๐ซ Cancelable debounced functions
|
9
|
+
- โก Immediate flush capability
|
10
|
+
- โฑ๏ธ Maximum wait time option
|
11
|
+
- ๐ Promise-based return values
|
12
|
+
- ๐ญ AbortController support
|
13
|
+
- ๐ Debug mode
|
14
|
+
- ๐ Comprehensive TypeScript types
|
15
|
+
- ๐งน Proper cleanup utilities
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
```bash
|
20
|
+
npm install @avatijs/debounce
|
21
|
+
```
|
22
|
+
|
23
|
+
## Basic Usage
|
24
|
+
|
25
|
+
```typescript
|
26
|
+
import { debounce } from '@your-org/debounce-utility';
|
27
|
+
|
28
|
+
// Simple debounce
|
29
|
+
const debouncedFn = debounce(async (x: number) => x * 2, {
|
30
|
+
wait: 1000
|
31
|
+
});
|
32
|
+
|
33
|
+
// Call the debounced function
|
34
|
+
await debouncedFn(5); // Will execute after 1000ms
|
35
|
+
|
36
|
+
// With debug logging
|
37
|
+
const debuggedFn = debounce(async (x: number) => x * 2, {
|
38
|
+
wait: 1000,
|
39
|
+
debug: true
|
40
|
+
});
|
41
|
+
|
42
|
+
// With abort controller
|
43
|
+
const controller = new AbortController();
|
44
|
+
const abortableFn = debounce(async (x: number) => x * 2, {
|
45
|
+
wait: 1000,
|
46
|
+
signal: controller.signal
|
47
|
+
});
|
48
|
+
|
49
|
+
// Cleanup when done
|
50
|
+
debouncedFn.cleanup();
|
51
|
+
```
|
52
|
+
|
53
|
+
## API Reference
|
54
|
+
|
55
|
+
### `debounce<T>(func: T, options?: DebounceOptions): DebouncedFunction<T>`
|
56
|
+
|
57
|
+
Creates a debounced version of the provided function.
|
58
|
+
|
59
|
+
#### Parameters
|
60
|
+
|
61
|
+
##### `func: T`
|
62
|
+
The function to debounce. Can be synchronous or asynchronous.
|
63
|
+
|
64
|
+
##### `options: DebounceOptions`
|
65
|
+
Configuration options for the debounced function.
|
66
|
+
|
67
|
+
```typescript
|
68
|
+
interface DebounceOptions {
|
69
|
+
readonly wait?: number; // Delay in milliseconds (default: 0)
|
70
|
+
readonly leading?: boolean; // Execute on leading edge (default: false)
|
71
|
+
readonly trailing?: boolean; // Execute on trailing edge (default: true)
|
72
|
+
readonly maxWait?: number; // Maximum time to wait
|
73
|
+
readonly debug?: boolean; // Enable debug logging (default: false)
|
74
|
+
readonly signal?: AbortSignal; // AbortController signal
|
75
|
+
}
|
76
|
+
```
|
77
|
+
|
78
|
+
#### Returns
|
79
|
+
|
80
|
+
Returns a debounced function with the following interface:
|
81
|
+
|
82
|
+
```typescript
|
83
|
+
interface DebouncedFunction<T> {
|
84
|
+
(...args: Parameters<T>): Promise<Awaited<ReturnType<T>>>;
|
85
|
+
readonly cancel: () => void;
|
86
|
+
readonly flush: (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
|
87
|
+
readonly pending: () => boolean;
|
88
|
+
readonly cleanup: () => void;
|
89
|
+
}
|
90
|
+
```
|
91
|
+
|
92
|
+
## Advanced Usage Examples
|
93
|
+
|
94
|
+
### Leading Edge Execution
|
95
|
+
|
96
|
+
```typescript
|
97
|
+
const leadingDebounce = debounce(
|
98
|
+
(value: string) => console.log(value),
|
99
|
+
{
|
100
|
+
wait: 1000,
|
101
|
+
leading: true,
|
102
|
+
trailing: false
|
103
|
+
}
|
104
|
+
);
|
105
|
+
|
106
|
+
// Executes immediately, then ignores calls for 1000ms
|
107
|
+
leadingDebounce("First");
|
108
|
+
leadingDebounce("Second"); // Ignored
|
109
|
+
leadingDebounce("Third"); // Ignored
|
110
|
+
```
|
111
|
+
|
112
|
+
### Maximum Wait Time
|
113
|
+
|
114
|
+
```typescript
|
115
|
+
const maxWaitDebounce = debounce(
|
116
|
+
(value: string) => console.log(value),
|
117
|
+
{
|
118
|
+
wait: 1000,
|
119
|
+
maxWait: 5000
|
120
|
+
}
|
121
|
+
);
|
122
|
+
|
123
|
+
// Will execute after 5000ms maximum, even if called continuously
|
124
|
+
const interval = setInterval(() => maxWaitDebounce("test"), 100);
|
125
|
+
```
|
126
|
+
|
127
|
+
### With AbortController
|
128
|
+
|
129
|
+
```typescript
|
130
|
+
const controller = new AbortController();
|
131
|
+
|
132
|
+
const abortableDebounce = debounce(
|
133
|
+
async (value: string) => {
|
134
|
+
await someAsyncOperation(value);
|
135
|
+
},
|
136
|
+
{
|
137
|
+
wait: 1000,
|
138
|
+
signal: controller.signal
|
139
|
+
}
|
140
|
+
);
|
141
|
+
|
142
|
+
// Later, abort all pending operations
|
143
|
+
controller.abort();
|
144
|
+
```
|
145
|
+
|
146
|
+
### Debug Mode
|
147
|
+
|
148
|
+
```typescript
|
149
|
+
const debugDebounce = debounce(
|
150
|
+
(value: string) => console.log(value),
|
151
|
+
{
|
152
|
+
wait: 1000,
|
153
|
+
debug: true
|
154
|
+
}
|
155
|
+
);
|
156
|
+
|
157
|
+
// Will log detailed information about internal state
|
158
|
+
debugDebounce("test");
|
159
|
+
```
|
160
|
+
|
161
|
+
### Handling Return Values
|
162
|
+
|
163
|
+
```typescript
|
164
|
+
const asyncDebounce = debounce(
|
165
|
+
async (x: number): Promise<number> => {
|
166
|
+
await delay(100);
|
167
|
+
return x * 2;
|
168
|
+
},
|
169
|
+
{ wait: 1000 }
|
170
|
+
);
|
171
|
+
|
172
|
+
// Get the result
|
173
|
+
const result = await asyncDebounce(5);
|
174
|
+
console.log(result); // 10
|
175
|
+
```
|
176
|
+
|
177
|
+
### Cleanup
|
178
|
+
|
179
|
+
```typescript
|
180
|
+
const debouncedFn = debounce((x: number) => x * 2, { wait: 1000 });
|
181
|
+
|
182
|
+
// Use the function
|
183
|
+
debouncedFn(5);
|
184
|
+
|
185
|
+
// Clean up when done
|
186
|
+
debouncedFn.cleanup();
|
187
|
+
```
|
188
|
+
|
189
|
+
## Best Practices
|
190
|
+
|
191
|
+
1. **Always Clean Up**: Call `cleanup()` when you're done with the debounced function to prevent memory leaks:
|
192
|
+
|
193
|
+
```typescript
|
194
|
+
const debouncedFn = debounce(myFunc, { wait: 1000 });
|
195
|
+
|
196
|
+
// When done:
|
197
|
+
debouncedFn.cleanup();
|
198
|
+
```
|
199
|
+
|
200
|
+
2. **Error Handling**: Always handle potential errors in async operations:
|
201
|
+
|
202
|
+
```typescript
|
203
|
+
const debouncedFn = debounce(async () => {
|
204
|
+
try {
|
205
|
+
await debouncedOperation();
|
206
|
+
} catch (error) {
|
207
|
+
// Handle error
|
208
|
+
}
|
209
|
+
});
|
210
|
+
```
|
211
|
+
|
212
|
+
3. **TypeScript Usage**: Leverage TypeScript's type system:
|
213
|
+
|
214
|
+
```typescript
|
215
|
+
interface MyFuncParams {
|
216
|
+
id: number;
|
217
|
+
name: string;
|
218
|
+
}
|
219
|
+
|
220
|
+
const typedDebounce = debounce(
|
221
|
+
(params: MyFuncParams) => console.log(params),
|
222
|
+
{ wait: 1000 }
|
223
|
+
);
|
224
|
+
|
225
|
+
// TypeScript will enforce correct parameter types
|
226
|
+
typedDebounce({ id: 1, name: "test" });
|
227
|
+
```
|
228
|
+
|
229
|
+
## Common Gotchas
|
230
|
+
|
231
|
+
1. **Memory Leaks**: Not calling `cleanup()` when done can lead to memory leaks.
|
232
|
+
2. **Shared State**: Be careful with shared state in debounced functions.
|
233
|
+
3. **Error Handling**: Always handle potential errors in async operations.
|
234
|
+
4. **Maximum Wait Time**: Setting `maxWait` less than `wait` will throw an error.
|
235
|
+
|
236
|
+
## Contributing
|
237
|
+
|
238
|
+
Contributions are welcome! Please read our [contributing guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
|
239
|
+
|
240
|
+
## License
|
241
|
+
|
242
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/*!
|
2
|
+
* @avatijs/debounce 0.1.1
|
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.js.map
|
@@ -0,0 +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":""}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
/**
|
2
|
+
* Advanced debounce utility with TypeScript support
|
3
|
+
* Provides a way to limit the rate at which a function can fire by delaying its execution
|
4
|
+
* until after a specified amount of time has elapsed since its last invocation.
|
5
|
+
* @module debounce
|
6
|
+
*/
|
7
|
+
/**
|
8
|
+
* Generic function type that can accept any arguments and return any value
|
9
|
+
* Used as a constraint for functions that can be debounced
|
10
|
+
*/
|
11
|
+
type AnyFunction = (...args: any[]) => any;
|
12
|
+
/**
|
13
|
+
* Configuration options for the debounce function
|
14
|
+
* @interface DebounceOptions
|
15
|
+
*/
|
16
|
+
interface DebounceOptions {
|
17
|
+
/** Number of milliseconds to delay execution (default: 0) */
|
18
|
+
readonly wait?: number;
|
19
|
+
/** Whether to execute on the leading edge of the timeout (default: false) */
|
20
|
+
readonly leading?: boolean;
|
21
|
+
/** Whether to execute on the trailing edge of the timeout (default: true) */
|
22
|
+
readonly trailing?: boolean;
|
23
|
+
/** Maximum time the function can be delayed before forced execution */
|
24
|
+
readonly maxWait?: number;
|
25
|
+
/** Enable debug logging for troubleshooting */
|
26
|
+
readonly debug?: boolean;
|
27
|
+
/** AbortController signal for cancellation */
|
28
|
+
readonly signal?: AbortSignal;
|
29
|
+
onError?: (error: Error) => void;
|
30
|
+
}
|
31
|
+
/**
|
32
|
+
* Interface for the debounced function, including utility methods
|
33
|
+
* @interface DebouncedFunction
|
34
|
+
* @template T - The type of the original function
|
35
|
+
*/
|
36
|
+
interface DebouncedFunction<T extends AnyFunction> {
|
37
|
+
/** Cancels any pending function invocations */
|
38
|
+
readonly cancel: () => void;
|
39
|
+
/** Immediately executes any pending function call */
|
40
|
+
readonly flush: (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
|
41
|
+
/** Checks if there are any pending invocations */
|
42
|
+
readonly pending: () => boolean;
|
43
|
+
/** Cleans up resources used by the debounced function */
|
44
|
+
readonly cleanup: () => void;
|
45
|
+
/** The debounced function that wraps the original */
|
46
|
+
(...args: Parameters<T>): Promise<Awaited<ReturnType<T>>>;
|
47
|
+
}
|
48
|
+
/**
|
49
|
+
* Creates a debounced version of the provided function that delays invoking func until after
|
50
|
+
* wait milliseconds have elapsed since the last time the debounced function was invoked.
|
51
|
+
*
|
52
|
+
* @template T - The type of the function to debounce
|
53
|
+
* @param {T} func - The function to debounce
|
54
|
+
* @param {DebounceOptions} [options={}] - Configuration options
|
55
|
+
* @returns {DebouncedFunction<T>} The debounced function
|
56
|
+
* @throws {TypeError} If func is not a function
|
57
|
+
* @throws {RangeError} If wait or maxWait values are invalid
|
58
|
+
* @throws {Error} If neither leading nor trailing is true
|
59
|
+
*
|
60
|
+
* @example
|
61
|
+
* const debouncedFn = debounce(async (x: number) => x * 2, { wait: 1000 });
|
62
|
+
* await debouncedFn(5); // Will execute after 1000ms of inactivity
|
63
|
+
* const debouncedFn = debounce(
|
64
|
+
* async (x: number) => x * 2,
|
65
|
+
* {
|
66
|
+
* wait: 1000,
|
67
|
+
* onError: (error) => console.error('Error in debounced function:', error)
|
68
|
+
* }
|
69
|
+
* );
|
70
|
+
*/
|
71
|
+
declare function debounce<T extends AnyFunction>(func: T, options?: DebounceOptions): DebouncedFunction<T>;
|
72
|
+
export { debounce, type DebouncedFunction, type DebounceOptions };
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/*!
|
2
|
+
* @avatijs/debounce 0.1.1
|
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
|
+
*/var e={d:(n,r)=>{for(var o in r)e.o(r,o)&&!e.o(n,o)&&Object.defineProperty(n,o,{enumerable:!0,get:r[o]})},o:(e,n)=>Object.prototype.hasOwnProperty.call(e,n)},n={};e.d(n,{s:()=>t});const r=new WeakMap,o=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=o(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 g(){s.log("Cancelling pending invocations"),v(),f.lastInvokeTime=0,f.lastArgs=void 0,f.lastThis=void 0,f.lastCallTime=void 0,b(Error("Debounced function cancelled")),f.pendingPromises.forEach((({reject:e})=>e(Error("Debounced function cancelled")))),f.pendingPromises=[]}function b(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 r=f.lastArgs,o=f.lastThis;f.lastArgs=void 0,f.lastThis=void 0;try{const n=await e.apply(o,r);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),b(n);const r=[...f.pendingPromises];f.pendingPromises=[],r.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(h,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 h(){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,g()}));const x=function(...e){if(f.aborted)return Promise.reject(Error("Debounced function aborted"));const n=Date.now(),r=w(n);return f.lastArgs=e,f.lastThis=this,f.lastCallTime=n,s.log("Function called",{time:n,isInvoking:r,args:e,pending:m()}),new Promise(((e,r)=>{f.pendingPromises.push({resolve:e,reject:r}),void 0===f.timerId?function(e){s.log("Leading edge triggered"),f.lastInvokeTime=e,p(e),i&&E(e)}(n):(v(),p(n))}))};return r.set(x,f),Object.defineProperties(x,{cancel:{value:g,writable:!1,configurable:!1},flush:{value:async function(...e){s.log("Flush requested");const n=e.length>0?e:f.lastArgs,r=f.lastThis;return v(),n?(f.lastArgs=n,f.lastThis=r,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"),g(),r.delete(x)},writable:!1,configurable:!1}}),x}var i=n.s;export{i as debounce};
|
7
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +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/./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))","/**\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","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","value","writable","configurable","flush","argsToUse","length","cleanup","delete"],"sourceRoot":""}
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export * from './debouce';
|
@@ -0,0 +1,72 @@
|
|
1
|
+
/**
|
2
|
+
* Advanced debounce utility with TypeScript support
|
3
|
+
* Provides a way to limit the rate at which a function can fire by delaying its execution
|
4
|
+
* until after a specified amount of time has elapsed since its last invocation.
|
5
|
+
* @module debounce
|
6
|
+
*/
|
7
|
+
/**
|
8
|
+
* Generic function type that can accept any arguments and return any value
|
9
|
+
* Used as a constraint for functions that can be debounced
|
10
|
+
*/
|
11
|
+
type AnyFunction = (...args: any[]) => any;
|
12
|
+
/**
|
13
|
+
* Configuration options for the debounce function
|
14
|
+
* @interface DebounceOptions
|
15
|
+
*/
|
16
|
+
interface DebounceOptions {
|
17
|
+
/** Number of milliseconds to delay execution (default: 0) */
|
18
|
+
readonly wait?: number;
|
19
|
+
/** Whether to execute on the leading edge of the timeout (default: false) */
|
20
|
+
readonly leading?: boolean;
|
21
|
+
/** Whether to execute on the trailing edge of the timeout (default: true) */
|
22
|
+
readonly trailing?: boolean;
|
23
|
+
/** Maximum time the function can be delayed before forced execution */
|
24
|
+
readonly maxWait?: number;
|
25
|
+
/** Enable debug logging for troubleshooting */
|
26
|
+
readonly debug?: boolean;
|
27
|
+
/** AbortController signal for cancellation */
|
28
|
+
readonly signal?: AbortSignal;
|
29
|
+
onError?: (error: Error) => void;
|
30
|
+
}
|
31
|
+
/**
|
32
|
+
* Interface for the debounced function, including utility methods
|
33
|
+
* @interface DebouncedFunction
|
34
|
+
* @template T - The type of the original function
|
35
|
+
*/
|
36
|
+
interface DebouncedFunction<T extends AnyFunction> {
|
37
|
+
/** Cancels any pending function invocations */
|
38
|
+
readonly cancel: () => void;
|
39
|
+
/** Immediately executes any pending function call */
|
40
|
+
readonly flush: (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
|
41
|
+
/** Checks if there are any pending invocations */
|
42
|
+
readonly pending: () => boolean;
|
43
|
+
/** Cleans up resources used by the debounced function */
|
44
|
+
readonly cleanup: () => void;
|
45
|
+
/** The debounced function that wraps the original */
|
46
|
+
(...args: Parameters<T>): Promise<Awaited<ReturnType<T>>>;
|
47
|
+
}
|
48
|
+
/**
|
49
|
+
* Creates a debounced version of the provided function that delays invoking func until after
|
50
|
+
* wait milliseconds have elapsed since the last time the debounced function was invoked.
|
51
|
+
*
|
52
|
+
* @template T - The type of the function to debounce
|
53
|
+
* @param {T} func - The function to debounce
|
54
|
+
* @param {DebounceOptions} [options={}] - Configuration options
|
55
|
+
* @returns {DebouncedFunction<T>} The debounced function
|
56
|
+
* @throws {TypeError} If func is not a function
|
57
|
+
* @throws {RangeError} If wait or maxWait values are invalid
|
58
|
+
* @throws {Error} If neither leading nor trailing is true
|
59
|
+
*
|
60
|
+
* @example
|
61
|
+
* const debouncedFn = debounce(async (x: number) => x * 2, { wait: 1000 });
|
62
|
+
* await debouncedFn(5); // Will execute after 1000ms of inactivity
|
63
|
+
* const debouncedFn = debounce(
|
64
|
+
* async (x: number) => x * 2,
|
65
|
+
* {
|
66
|
+
* wait: 1000,
|
67
|
+
* onError: (error) => console.error('Error in debounced function:', error)
|
68
|
+
* }
|
69
|
+
* );
|
70
|
+
*/
|
71
|
+
declare function debounce<T extends AnyFunction>(func: T, options?: DebounceOptions): DebouncedFunction<T>;
|
72
|
+
export { debounce, type DebouncedFunction, type DebounceOptions };
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './debouce';
|
@@ -0,0 +1,8 @@
|
|
1
|
+
/*!
|
2
|
+
* @avatijs/debounce 0.1.1
|
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
|
+
*/
|
7
|
+
!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("Avati",[],n):"object"==typeof exports?exports.Avati=n():e.Avati=n()}("undefined"!=typeof self?self:this,(()=>(()=>{"use strict";var e={d:(n,o)=>{for(var t in o)e.o(o,t)&&!e.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:o[t]})},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:()=>i});const o=new WeakMap,t=e=>({log:(...n)=>e&&void 0,warn:(...n)=>e&&void 0,error:(...n)=>e&&void 0});function i(e,n={}){if("function"!=typeof e)throw new TypeError("Expected a function");const{wait:i=0,leading:r=!1,trailing:c=!0,maxWait:a,debug:u=!1,signal:d,onError:l}=n;if(0>i||void 0!==a&&i>a)throw new RangeError("Invalid wait/maxWait values");if(!r&&!c)throw Error("At least one of leading or trailing must be true");const f=t(u),s={lastInvokeTime:0,pendingPromises:[],aborted:!1};function v(){void 0!==s.timerId&&(clearTimeout(s.timerId),s.timerId=void 0,f.log("Cleared debounce timer")),void 0!==s.maxTimerId&&(clearTimeout(s.maxTimerId),s.maxTimerId=void 0,f.log("Cleared max wait timer"))}function b(){f.log("Cancelling pending invocations"),v(),s.lastInvokeTime=0,s.lastArgs=void 0,s.lastThis=void 0,s.lastCallTime=void 0,g(Error("Debounced function cancelled")),s.pendingPromises.forEach((({reject:e})=>e(Error("Debounced function cancelled")))),s.pendingPromises=[]}function g(e){if(f.error("Error occurred:",e),l)try{l(e)}catch(e){f.error("Error in onError callback:",e)}}function m(){return void 0!==s.timerId}function p(e){if(s.aborted)return!1;const n=void 0===s.lastCallTime?0:e-s.lastCallTime;return void 0===s.lastCallTime||n>=i||0>n||void 0!==a&&e-s.lastInvokeTime>=a}async function w(n){f.log("Invoking function at "+n),s.lastInvokeTime=n;const o=s.lastArgs,t=s.lastThis;s.lastArgs=void 0,s.lastThis=void 0;try{const n=await e.apply(t,o);return s.result=n,s.pendingPromises.forEach((({resolve:e})=>e(n))),s.pendingPromises=[],f.log("Function invoked successfully",n),n}catch(e){const n=e instanceof Error?e:Error(e+"");f.error("Error in function invocation:",n),g(n);const o=[...s.pendingPromises];s.pendingPromises=[],o.forEach((({reject:e})=>e(n)))}}function y(e){const n=function(e){return Math.max(0,i-(s.lastCallTime?e-s.lastCallTime:0))}(e);if(s.timerId=setTimeout(E,n),f.log(`Started debounce timer for ${n}ms`),void 0!==a&&!s.maxTimerId){const n=a-(e-s.lastCallTime);s.maxTimerId=setTimeout((()=>{f.log("Max wait timer expired"),v(),w(Date.now())}),Math.max(0,n)),f.log(`Started max wait timer for ${n}ms`)}}function E(){const e=Date.now();if(f.log("Debounce timer expired"),p(e))return function(e){f.log("Trailing edge triggered"),v(),c&&s.lastArgs?w(e):(s.pendingPromises.forEach((({resolve:e})=>{e(s.result)})),s.pendingPromises=[])}(e);y(e)}d&&d.addEventListener("abort",(()=>{s.aborted=!0,b()}));const h=function(...e){if(s.aborted)return Promise.reject(Error("Debounced function aborted"));const n=Date.now(),o=p(n);return s.lastArgs=e,s.lastThis=this,s.lastCallTime=n,f.log("Function called",{time:n,isInvoking:o,args:e,pending:m()}),new Promise(((e,o)=>{s.pendingPromises.push({resolve:e,reject:o}),void 0===s.timerId?function(e){f.log("Leading edge triggered"),s.lastInvokeTime=e,y(e),r&&w(e)}(n):(v(),y(n))}))};return o.set(h,s),Object.defineProperties(h,{cancel:{value:b,writable:!1,configurable:!1},flush:{value:async function(...e){f.log("Flush requested");const n=e.length>0?e:s.lastArgs,o=s.lastThis;return v(),n?(s.lastArgs=n,s.lastThis=o,w(Date.now())):Promise.resolve(s.result)},writable:!1,configurable:!1},pending:{value:m,writable:!1,configurable:!1},cleanup:{value:function(){f.log("Cleanup initiated"),b(),o.delete(h)},writable:!1,configurable:!1}}),h}return n})()));
|
8
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","mappings":"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","sources":["webpack://Avati/webpack/universalModuleDefinition","webpack://Avati/webpack/bootstrap","webpack://Avati/webpack/runtime/define property getters","webpack://Avati/webpack/runtime/hasOwnProperty shorthand","webpack://Avati/webpack/runtime/make namespace object","webpack://Avati/./src/debouce.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"Avati\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Avati\"] = factory();\n\telse\n\t\troot[\"Avati\"] = factory();\n})(typeof self !== 'undefined' ? self : this, () => {\nreturn ","// 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":["root","factory","exports","module","define","amd","self","this","__webpack_require__","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","push","leadingEdge","set","defineProperties","writable","configurable","flush","argsToUse","length","cleanup","delete"],"sourceRoot":""}
|
package/package.json
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
{
|
2
|
+
"name": "@avatijs/debounce",
|
3
|
+
"version": "0.1.1",
|
4
|
+
"description": "Debounce package part of Avati project",
|
5
|
+
"main": "./dist/cjs/index.js",
|
6
|
+
"module": "./dist/esm/index.js",
|
7
|
+
"types": "./dist/types/index.d.ts",
|
8
|
+
"browser": "./dist/umd/index.js",
|
9
|
+
"unpkg": "./dist/umd/index.min.js",
|
10
|
+
"jsdelivr": "./dist/umd/index.min.js",
|
11
|
+
"exports": {
|
12
|
+
".": {
|
13
|
+
"types": "./dist/types/index.d.ts",
|
14
|
+
"import": "./dist/esm/index.js",
|
15
|
+
"require": "./dist/cjs/index.js",
|
16
|
+
"default": "./dist/umd/index.js"
|
17
|
+
},
|
18
|
+
"./package.json": "./package.json"
|
19
|
+
},
|
20
|
+
"sideEffects": false,
|
21
|
+
"engines": {
|
22
|
+
"node": ">=14.0.0"
|
23
|
+
},
|
24
|
+
"bundlesize": [
|
25
|
+
{
|
26
|
+
"path": "./dist/esm/index.js",
|
27
|
+
"maxSize": "3 kB",
|
28
|
+
"compression": "brotli"
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"path": "./dist/cjs/index.js",
|
32
|
+
"maxSize": "3 kB",
|
33
|
+
"compression": "brotli"
|
34
|
+
},
|
35
|
+
{
|
36
|
+
"path": "./dist/umd/*.js",
|
37
|
+
"maxSize": "3 kB",
|
38
|
+
"compression": "brotli"
|
39
|
+
}
|
40
|
+
],
|
41
|
+
"scripts": {
|
42
|
+
"build": "npm run clean && npm run build:types && npm run build:prod",
|
43
|
+
"build:dev": "webpack --mode development --progress",
|
44
|
+
"build:prod": "webpack --mode production --progress",
|
45
|
+
"build:types": "tsc --emitDeclarationOnly --outDir dist/types",
|
46
|
+
"watch": "webpack --mode=development --watch",
|
47
|
+
"watch:silent": "webpack --mode=development --watch --silent",
|
48
|
+
"clean": "rimraf dist",
|
49
|
+
"prepublishOnly": "npm run build",
|
50
|
+
"test": "jest",
|
51
|
+
"typecheck": "tsc --noEmit",
|
52
|
+
"size": "webpack --mode production --json > stats.json && webpack-bundle-analyzer stats.json",
|
53
|
+
"analyze:deps": "madge --circular --extensions ts ./src/index.ts",
|
54
|
+
"size:check": "bundlesize",
|
55
|
+
"size:watch": "bundlesize --watch",
|
56
|
+
"size:compression": "bundlesize --compression",
|
57
|
+
"analyze": "npm run analyze:size && npm run analyze:deps && npm run analyze:duplicates",
|
58
|
+
"analyze:size": "webpack --mode production --json > stats.json && webpack-bundle-analyzer stats.json",
|
59
|
+
"analyze:detailed": "webpack --config webpack.analysis.config.js",
|
60
|
+
"analyze:duplicates": "jscpd src",
|
61
|
+
"analyze:why": "webpack --mode production --display-reasons",
|
62
|
+
"analyze:tree": "webpack --mode production --display-used-exports",
|
63
|
+
"analyze:modules": "webpack --mode production --display-modules",
|
64
|
+
"analyze:full": "webpack --mode production --stats detailed"
|
65
|
+
},
|
66
|
+
"files": [
|
67
|
+
"dist",
|
68
|
+
"LICENSE",
|
69
|
+
"README.md",
|
70
|
+
"CHANGELOG.md"
|
71
|
+
],
|
72
|
+
"author": {
|
73
|
+
"name": "Khaled Sameer",
|
74
|
+
"email": "khaled.smq@hotmail.com",
|
75
|
+
"url": "https://khaled.ee/"
|
76
|
+
},
|
77
|
+
"homepage": "https://avati.io/",
|
78
|
+
"bugs": {
|
79
|
+
"url": "https://github.com/KhaledSMQ/avati/issues",
|
80
|
+
"email": "khaled.smq@hotmail.com"
|
81
|
+
},
|
82
|
+
"repository": {
|
83
|
+
"type": "git",
|
84
|
+
"url": "git+https://github.com/KhaledSMQ/avati.git",
|
85
|
+
"directory": "packages/debounce"
|
86
|
+
},
|
87
|
+
"license": "MIT",
|
88
|
+
"publishConfig": {
|
89
|
+
"access": "public"
|
90
|
+
},
|
91
|
+
"keywords": [
|
92
|
+
"avati",
|
93
|
+
"typescript",
|
94
|
+
"debounce",
|
95
|
+
"debouncer",
|
96
|
+
"throttle",
|
97
|
+
"throttling",
|
98
|
+
"delay",
|
99
|
+
"function control",
|
100
|
+
"rate limit",
|
101
|
+
"rate limiting",
|
102
|
+
"utility",
|
103
|
+
"helper",
|
104
|
+
"JavaScript",
|
105
|
+
"timing",
|
106
|
+
"event handling",
|
107
|
+
"event control",
|
108
|
+
"performance",
|
109
|
+
"optimization",
|
110
|
+
"function delay",
|
111
|
+
"input control",
|
112
|
+
"API calls"
|
113
|
+
],
|
114
|
+
"devDependencies": {
|
115
|
+
"@types/jest": "^29.5.14",
|
116
|
+
"@types/node": "^22.9.1",
|
117
|
+
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
118
|
+
"@typescript-eslint/parser": "^8.15.0",
|
119
|
+
"bundlesize": "^0.18.2",
|
120
|
+
"dependency-cruiser": "^16.6.0",
|
121
|
+
"eslint": "^8.57.1",
|
122
|
+
"jest": "^29.7.0",
|
123
|
+
"jscpd": "^4.0.5",
|
124
|
+
"madge": "^8.0.0",
|
125
|
+
"rimraf": "^6.0.1",
|
126
|
+
"source-map-explorer": "^2.5.3",
|
127
|
+
"terser-webpack-plugin": "^5.3.10",
|
128
|
+
"ts-jest": "^29.2.5",
|
129
|
+
"ts-loader": "^9.5.1",
|
130
|
+
"typescript": "^5.6.3",
|
131
|
+
"webpack": "^5.96.1",
|
132
|
+
"webpack-bundle-analyzer": "^4.10.2",
|
133
|
+
"webpack-cli": "^5.1.4"
|
134
|
+
}
|
135
|
+
}
|