git-watchtower 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/utils/async.js +17 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-watchtower",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "description": "Terminal-based Git branch monitor with activity sparklines and optional dev server with live reload",
5
5
  "main": "bin/git-watchtower.js",
6
6
  "bin": {
@@ -175,6 +175,18 @@ function sleep(ms) {
175
175
 
176
176
  /**
177
177
  * Debounce a function - only execute after delay with no calls
178
+ *
179
+ * cancel() both clears the pending timer and sets an internal flag
180
+ * that the scheduled callback checks at the top. Without the flag,
181
+ * cancel() racing with a timer whose callback has already been
182
+ * dequeued (the timer fired, but the callback hadn't executed yet)
183
+ * was a no-op — clearTimeout can't recall a callback that libuv
184
+ * has already promoted — so fn would run anyway and write into
185
+ * state the caller had just asked to abandon.
186
+ *
187
+ * Calling debounced(...) re-arms: the cancelled flag resets so a new
188
+ * schedule is not pre-squelched by a prior cancel().
189
+ *
178
190
  * @template {(...args: any[]) => void} T
179
191
  * @param {T} fn - Function to debounce
180
192
  * @param {number} delay - Delay in milliseconds
@@ -182,18 +194,22 @@ function sleep(ms) {
182
194
  */
183
195
  function debounce(fn, delay) {
184
196
  let timeoutId = null;
197
+ let cancelled = false;
185
198
 
186
199
  const debounced = (...args) => {
187
200
  if (timeoutId) {
188
201
  clearTimeout(timeoutId);
189
202
  }
203
+ cancelled = false;
190
204
  timeoutId = setTimeout(() => {
191
- fn(...args);
192
205
  timeoutId = null;
206
+ if (cancelled) return;
207
+ fn(...args);
193
208
  }, delay);
194
209
  };
195
210
 
196
211
  debounced.cancel = () => {
212
+ cancelled = true;
197
213
  if (timeoutId) {
198
214
  clearTimeout(timeoutId);
199
215
  timeoutId = null;