tiny-essentials 1.18.0 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -3
- package/dist/legacy/get/countObj.cjs +2 -2
- package/dist/legacy/get/countObj.d.mts +1 -1
- package/dist/legacy/get/countObj.mjs +1 -1
- package/dist/legacy/index.cjs +2 -1
- package/dist/node_modules/firebase-functions/lib/common/trace.cjs +0 -1
- package/dist/node_modules/firebase-functions/lib/logger/index.cjs +1 -0
- package/dist/v1/ColorSafeStringify.min.js +1 -1
- package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
- package/dist/v1/TinyBasicsEs.js +402 -390
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyClipboard.min.js +1 -1
- package/dist/v1/TinyColorConverter.js +617 -0
- package/dist/v1/TinyColorConverter.min.js +1 -0
- package/dist/v1/TinyDomReadyManager.min.js +1 -1
- package/dist/v1/TinyDragger.js +6 -2433
- package/dist/v1/TinyDragger.min.js +1 -2
- package/dist/v1/TinyEssentials.js +3546 -1388
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyEvents.js +402 -0
- package/dist/v1/TinyEvents.min.js +1 -0
- package/dist/v1/TinyHtml.min.js +1 -1
- package/dist/v1/TinyLocalStorage.js +1292 -0
- package/dist/v1/TinyLocalStorage.min.js +1 -0
- package/dist/v1/TinyNotifications.min.js +1 -1
- package/dist/v1/TinyNotifyCenter.min.js +1 -1
- package/dist/v1/TinyPromiseQueue.min.js +1 -1
- package/dist/v1/TinyRateLimiter.js +2 -1
- package/dist/v1/TinyRateLimiter.min.js +1 -1
- package/dist/v1/TinySmartScroller.js +570 -52
- package/dist/v1/TinySmartScroller.min.js +1 -1
- package/dist/v1/TinyTextRangeEditor.min.js +1 -1
- package/dist/v1/TinyTimeout.js +233 -0
- package/dist/v1/TinyTimeout.min.js +1 -0
- package/dist/v1/TinyToastNotify.min.js +1 -1
- package/dist/v1/TinyUploadClicker.js +2087 -1129
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/UltraRandomMsgGen.min.js +1 -1
- package/dist/v1/basics/html.cjs +16 -9
- package/dist/v1/basics/html.d.mts +12 -4
- package/dist/v1/basics/html.mjs +14 -7
- package/dist/v1/basics/index.cjs +3 -2
- package/dist/v1/basics/index.d.mts +2 -2
- package/dist/v1/basics/index.mjs +2 -1
- package/dist/v1/basics/objChecker.cjs +46 -0
- package/dist/v1/basics/objChecker.d.mts +29 -0
- package/dist/v1/basics/objChecker.mjs +45 -0
- package/dist/v1/basics/objFilter.cjs +4 -45
- package/dist/v1/basics/objFilter.d.mts +3 -28
- package/dist/v1/basics/objFilter.mjs +2 -45
- package/dist/v1/build/TinyColorConverter.cjs +7 -0
- package/dist/v1/build/TinyColorConverter.d.mts +3 -0
- package/dist/v1/build/TinyColorConverter.mjs +2 -0
- package/dist/v1/build/TinyEvents.cjs +7 -0
- package/dist/v1/build/TinyEvents.d.mts +3 -0
- package/dist/v1/build/TinyEvents.mjs +2 -0
- package/dist/v1/build/TinyLocalStorage.cjs +7 -0
- package/dist/v1/build/TinyLocalStorage.d.mts +3 -0
- package/dist/v1/build/TinyLocalStorage.mjs +2 -0
- package/dist/v1/build/TinyTimeout.cjs +7 -0
- package/dist/v1/build/TinyTimeout.d.mts +3 -0
- package/dist/v1/build/TinyTimeout.mjs +2 -0
- package/dist/v1/index.cjs +11 -2
- package/dist/v1/index.d.mts +7 -3
- package/dist/v1/index.mjs +7 -2
- package/dist/v1/libs/TinyColorConverter.cjs +578 -0
- package/dist/v1/libs/TinyColorConverter.d.mts +396 -0
- package/dist/v1/libs/TinyColorConverter.mjs +520 -0
- package/dist/v1/libs/TinyDragger.cjs +3 -3
- package/dist/v1/libs/TinyDragger.mjs +1 -1
- package/dist/v1/libs/TinyEvents.cjs +363 -0
- package/dist/v1/libs/TinyEvents.d.mts +160 -0
- package/dist/v1/libs/TinyEvents.mjs +328 -0
- package/dist/v1/libs/TinyLocalStorage.cjs +847 -0
- package/dist/v1/libs/TinyLocalStorage.d.mts +407 -0
- package/dist/v1/libs/TinyLocalStorage.mjs +740 -0
- package/dist/v1/libs/TinySmartScroller.cjs +207 -52
- package/dist/v1/libs/TinySmartScroller.d.mts +164 -16
- package/dist/v1/libs/TinySmartScroller.mjs +181 -52
- package/dist/v1/libs/TinyTimeout.cjs +194 -0
- package/dist/v1/libs/TinyTimeout.d.mts +89 -0
- package/dist/v1/libs/TinyTimeout.mjs +179 -0
- package/dist/v1/libs/TinyUploadClicker.cjs +6 -4
- package/docs/v1/README.md +5 -0
- package/docs/v1/basics/objChecker.md +47 -0
- package/docs/v1/basics/objFilter.md +0 -40
- package/docs/v1/libs/TinyColorConverter.md +220 -0
- package/docs/v1/libs/TinyEvents.md +199 -0
- package/docs/v1/libs/TinyLocalStorage.md +350 -0
- package/docs/v1/libs/TinyRateLimiter.md +0 -3
- package/docs/v1/libs/TinyTimeout.md +190 -0
- package/package.json +28 -5
- package/dist/v1/TinyDragger.min.js.LICENSE.txt +0 -8
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import TinyHtml from './TinyHtml.mjs';
|
|
2
2
|
import * as TinyCollision from '../basics/collision.mjs';
|
|
3
|
+
import TinyEvents from './TinyEvents.mjs';
|
|
3
4
|
/**
|
|
4
5
|
* Represents the dimensions of a DOM element.
|
|
5
6
|
*
|
|
@@ -42,6 +43,179 @@ import * as TinyCollision from '../basics/collision.mjs';
|
|
|
42
43
|
*/
|
|
43
44
|
class TinySmartScroller {
|
|
44
45
|
static Utils = { ...TinyCollision, TinyHtml };
|
|
46
|
+
#events = new TinyEvents();
|
|
47
|
+
/**
|
|
48
|
+
* Enables or disables throwing an error when the maximum number of listeners is exceeded.
|
|
49
|
+
*
|
|
50
|
+
* @param {boolean} shouldThrow - If true, an error will be thrown when the max is exceeded.
|
|
51
|
+
*/
|
|
52
|
+
setThrowOnMaxListeners(shouldThrow) {
|
|
53
|
+
return this.#events.setThrowOnMaxListeners(shouldThrow);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Checks whether an error will be thrown when the max listener limit is exceeded.
|
|
57
|
+
*
|
|
58
|
+
* @returns {boolean} True if an error will be thrown, false if only a warning is shown.
|
|
59
|
+
*/
|
|
60
|
+
getThrowOnMaxListeners() {
|
|
61
|
+
return this.#events.getThrowOnMaxListeners();
|
|
62
|
+
}
|
|
63
|
+
/////////////////////////////////////////////////////////////
|
|
64
|
+
/**
|
|
65
|
+
* Adds a listener to the beginning of the listeners array for the specified event.
|
|
66
|
+
*
|
|
67
|
+
* @param {string} event - Event name.
|
|
68
|
+
* @param {ScrollListenersFunc} handler - The callback function.
|
|
69
|
+
*/
|
|
70
|
+
prependListener(event, handler) {
|
|
71
|
+
return this.#events.prependListener(event, handler);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Adds a one-time listener to the beginning of the listeners array for the specified event.
|
|
75
|
+
*
|
|
76
|
+
* @param {string} event - Event name.
|
|
77
|
+
* @param {ScrollListenersFunc} handler - The callback function.
|
|
78
|
+
* @returns {ScrollListenersFunc} - The wrapped handler used internally.
|
|
79
|
+
*/
|
|
80
|
+
prependListenerOnce(event, handler) {
|
|
81
|
+
return this.#events.prependListenerOnce(event, handler);
|
|
82
|
+
}
|
|
83
|
+
//////////////////////////////////////////////////////////////////////
|
|
84
|
+
/**
|
|
85
|
+
* Adds a event listener.
|
|
86
|
+
*
|
|
87
|
+
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
88
|
+
* @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
|
|
89
|
+
*/
|
|
90
|
+
appendListener(event, handler) {
|
|
91
|
+
return this.#events.appendListener(event, handler);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Registers an event listener that runs only once, then is removed.
|
|
95
|
+
*
|
|
96
|
+
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
97
|
+
* @param {ScrollListenersFunc} handler - The callback function to run on event.
|
|
98
|
+
* @returns {ScrollListenersFunc} - The wrapped version of the handler.
|
|
99
|
+
*/
|
|
100
|
+
appendListenerOnce(event, handler) {
|
|
101
|
+
return this.#events.appendListenerOnce(event, handler);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Adds a event listener.
|
|
105
|
+
*
|
|
106
|
+
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
107
|
+
* @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
|
|
108
|
+
*/
|
|
109
|
+
on(event, handler) {
|
|
110
|
+
return this.#events.on(event, handler);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Registers an event listener that runs only once, then is removed.
|
|
114
|
+
*
|
|
115
|
+
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
116
|
+
* @param {ScrollListenersFunc} handler - The callback function to run on event.
|
|
117
|
+
* @returns {ScrollListenersFunc} - The wrapped version of the handler.
|
|
118
|
+
*/
|
|
119
|
+
once(event, handler) {
|
|
120
|
+
return this.#events.once(event, handler);
|
|
121
|
+
}
|
|
122
|
+
////////////////////////////////////////////////////////////////////
|
|
123
|
+
/**
|
|
124
|
+
* Removes a previously registered event listener.
|
|
125
|
+
*
|
|
126
|
+
* @param {string} event - The name of the event to remove the handler from.
|
|
127
|
+
* @param {ScrollListenersFunc} handler - The specific callback function to remove.
|
|
128
|
+
*/
|
|
129
|
+
off(event, handler) {
|
|
130
|
+
return this.#events.off(event, handler);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Removes all event listeners of a specific type from the element.
|
|
134
|
+
*
|
|
135
|
+
* @param {string} event - The event type to remove (e.g. 'onScrollBoundary').
|
|
136
|
+
*/
|
|
137
|
+
offAll(event) {
|
|
138
|
+
return this.#events.offAll(event);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Removes all event listeners of all types from the element.
|
|
142
|
+
*/
|
|
143
|
+
offAllTypes() {
|
|
144
|
+
return this.#events.offAllTypes();
|
|
145
|
+
}
|
|
146
|
+
////////////////////////////////////////////////////////////
|
|
147
|
+
/**
|
|
148
|
+
* Returns the number of listeners for a given event.
|
|
149
|
+
*
|
|
150
|
+
* @param {string} event - The name of the event.
|
|
151
|
+
* @returns {number} Number of listeners for the event.
|
|
152
|
+
*/
|
|
153
|
+
listenerCount(event) {
|
|
154
|
+
return this.#events.listenerCount(event);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Returns a copy of the array of listeners for the specified event.
|
|
158
|
+
*
|
|
159
|
+
* @param {string} event - The name of the event.
|
|
160
|
+
* @returns {ScrollListenersFunc[]} Array of listener functions.
|
|
161
|
+
*/
|
|
162
|
+
listeners(event) {
|
|
163
|
+
return this.#events.listeners(event);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Returns a copy of the array of listeners for the specified event.
|
|
167
|
+
*
|
|
168
|
+
* @param {string} event - The name of the event.
|
|
169
|
+
* @returns {ScrollListenersFunc[]} Array of listener functions.
|
|
170
|
+
*/
|
|
171
|
+
onceListeners(event) {
|
|
172
|
+
return this.#events.onceListeners(event);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Returns a copy of the internal listeners array for the specified event,
|
|
176
|
+
* including wrapper functions like those used by `.once()`.
|
|
177
|
+
* @param {string | symbol} event - The event name.
|
|
178
|
+
* @returns {ScrollListenersFunc[]} An array of raw listener functions.
|
|
179
|
+
*/
|
|
180
|
+
allListeners(event) {
|
|
181
|
+
return this.#events.allListeners(event);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Returns an array of event names for which there are registered listeners.
|
|
185
|
+
*
|
|
186
|
+
* @returns {string[]} Array of registered event names.
|
|
187
|
+
*/
|
|
188
|
+
eventNames() {
|
|
189
|
+
return this.#events.eventNames();
|
|
190
|
+
}
|
|
191
|
+
//////////////////////////////////////////////////////
|
|
192
|
+
/**
|
|
193
|
+
* Emits an event, triggering all registered handlers for that event.
|
|
194
|
+
*
|
|
195
|
+
* @param {string} event - The event name to emit.
|
|
196
|
+
* @param {...any} payload - Optional data to pass to each handler.
|
|
197
|
+
* @returns {boolean} True if any listeners were called, false otherwise.
|
|
198
|
+
*/
|
|
199
|
+
emit(event, ...payload) {
|
|
200
|
+
return this.#events.emit(event, ...payload);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Sets the maximum number of listeners per event before a warning is shown.
|
|
204
|
+
*
|
|
205
|
+
* @param {number} n - The maximum number of listeners.
|
|
206
|
+
*/
|
|
207
|
+
setMaxListeners(n) {
|
|
208
|
+
return this.#events.setMaxListeners(n);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Gets the maximum number of listeners allowed per event.
|
|
212
|
+
*
|
|
213
|
+
* @returns {number} The maximum number of listeners.
|
|
214
|
+
*/
|
|
215
|
+
getMaxListeners() {
|
|
216
|
+
return this.#events.getMaxListeners();
|
|
217
|
+
}
|
|
218
|
+
///////////////////////////////////////////////////
|
|
45
219
|
/** @type {WeakMap<Element, NodeSizes>} */
|
|
46
220
|
#oldSizes = new WeakMap();
|
|
47
221
|
/** @type {WeakMap<Element, NodeSizes>} */
|
|
@@ -54,8 +228,6 @@ class TinySmartScroller {
|
|
|
54
228
|
#newVisiblesByTime = new WeakMap();
|
|
55
229
|
/** @type {WeakMap<Element, boolean>} */
|
|
56
230
|
#oldVisiblesByTime = new WeakMap();
|
|
57
|
-
/** @type {Record<string, ScrollListenersFunc[]>} */
|
|
58
|
-
#scrollListeners = {};
|
|
59
231
|
/** @type {ResizeObserver|null} */
|
|
60
232
|
#resizeObserver = null;
|
|
61
233
|
/** @type {MutationObserver|null} */
|
|
@@ -319,46 +491,6 @@ class TinySmartScroller {
|
|
|
319
491
|
throw new TypeError('offSize(handler): handler must be a function');
|
|
320
492
|
this.#sizeFilter.delete(handler);
|
|
321
493
|
}
|
|
322
|
-
/**
|
|
323
|
-
* Adds a scroll-related event listener.
|
|
324
|
-
*
|
|
325
|
-
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
326
|
-
* @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
|
|
327
|
-
*/
|
|
328
|
-
on(event, handler) {
|
|
329
|
-
if (this.#destroyed)
|
|
330
|
-
return;
|
|
331
|
-
if (typeof event !== 'string')
|
|
332
|
-
throw new TypeError('on(event, handler): event name must be a string');
|
|
333
|
-
if (typeof handler !== 'function')
|
|
334
|
-
throw new TypeError('on(event, handler): handler must be a function');
|
|
335
|
-
if (!this.#scrollListeners[event])
|
|
336
|
-
this.#scrollListeners[event] = [];
|
|
337
|
-
this.#scrollListeners[event].push(handler);
|
|
338
|
-
}
|
|
339
|
-
/**
|
|
340
|
-
* Removes a previously registered scroll-related event listener.
|
|
341
|
-
*
|
|
342
|
-
* @param {string} event - The name of the event to remove the handler from.
|
|
343
|
-
* @param {ScrollListenersFunc} handler - The specific callback function to remove.
|
|
344
|
-
*/
|
|
345
|
-
off(event, handler) {
|
|
346
|
-
if (this.#destroyed)
|
|
347
|
-
return;
|
|
348
|
-
if (typeof event !== 'string')
|
|
349
|
-
throw new TypeError('off(event, handler): event name must be a string');
|
|
350
|
-
if (typeof handler !== 'function')
|
|
351
|
-
throw new TypeError('off(event, handler): handler must be a function');
|
|
352
|
-
const listeners = this.#scrollListeners[event];
|
|
353
|
-
if (!Array.isArray(listeners))
|
|
354
|
-
return;
|
|
355
|
-
const index = listeners.indexOf(handler);
|
|
356
|
-
if (index !== -1)
|
|
357
|
-
listeners.splice(index, 1);
|
|
358
|
-
// Optionally clean up empty arrays (optional)
|
|
359
|
-
if (listeners.length === 0)
|
|
360
|
-
delete this.#scrollListeners[event];
|
|
361
|
-
}
|
|
362
494
|
/**
|
|
363
495
|
* Checks which elements inside the target are currently visible and updates internal maps.
|
|
364
496
|
*
|
|
@@ -380,13 +512,10 @@ class TinySmartScroller {
|
|
|
380
512
|
*
|
|
381
513
|
* @param {string} event - Event name.
|
|
382
514
|
* @param {*} [payload] - Optional event data payload.
|
|
515
|
+
* @deprecated - Use emit() instead.
|
|
383
516
|
*/
|
|
384
517
|
_emit(event, payload) {
|
|
385
|
-
|
|
386
|
-
return;
|
|
387
|
-
if (typeof event !== 'string')
|
|
388
|
-
throw new TypeError('_emit(event, payload): event name must be a string');
|
|
389
|
-
(this.#scrollListeners[event] || []).forEach((fn) => fn(payload));
|
|
518
|
+
this.emit(event, payload);
|
|
390
519
|
}
|
|
391
520
|
/**
|
|
392
521
|
* Handles scroll events, calculates position-related statuses, and emits appropriate events.
|
|
@@ -428,13 +557,13 @@ class TinySmartScroller {
|
|
|
428
557
|
this.#scrollPaused = !(this.#autoScrollBottom && this.#isAtBottom);
|
|
429
558
|
this.#lastKnownScrollBottomOffset = scrollHeight - scrollTop - clientHeight;
|
|
430
559
|
// Send results
|
|
431
|
-
this.
|
|
432
|
-
this.
|
|
560
|
+
this.emit('onScrollBoundary', { status: atResult, ...scrollResult, scrollCache });
|
|
561
|
+
this.emit('onExtraScrollBoundary', { status: atCustomResult, ...scrollResult, scrollCache });
|
|
433
562
|
if (!this.#scrollPaused) {
|
|
434
|
-
this.
|
|
563
|
+
this.emit('onAutoScroll', { ...scrollResult, scrollCache });
|
|
435
564
|
}
|
|
436
565
|
else {
|
|
437
|
-
this.
|
|
566
|
+
this.emit('onScrollPause', { ...scrollResult, scrollCache });
|
|
438
567
|
}
|
|
439
568
|
}
|
|
440
569
|
/**
|
|
@@ -848,7 +977,7 @@ class TinySmartScroller {
|
|
|
848
977
|
this.#newVisiblesByTime = new WeakMap();
|
|
849
978
|
this.#oldVisiblesByTime = new WeakMap();
|
|
850
979
|
// Cleans listeners and filters
|
|
851
|
-
this.#
|
|
980
|
+
this.#events.offAllTypes();
|
|
852
981
|
this.#sizeFilter.clear();
|
|
853
982
|
this.#loadTags.clear();
|
|
854
983
|
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A utility class to manage dynamically adjusted timeouts based on how often
|
|
5
|
+
* each unique ID is triggered. Also provides polling support for asynchronous conditions.
|
|
6
|
+
*/
|
|
7
|
+
class TinyTimeout {
|
|
8
|
+
/** @type {boolean} Whether this instance has been destroyed. */
|
|
9
|
+
#isDestroyed = false;
|
|
10
|
+
|
|
11
|
+
/** @type {boolean} Whether to allow auto-updating an ID's timeout config if `value` changes. */
|
|
12
|
+
#allowAutoConfigChange;
|
|
13
|
+
|
|
14
|
+
/** @type {number} The interval time (ms) used to decrement cooldown counters. */
|
|
15
|
+
#cooldownWatcherTime;
|
|
16
|
+
|
|
17
|
+
/** @type {NodeJS.Timeout|null} Reference to the internal cooldown interval. */
|
|
18
|
+
#cooldownWatcher = null;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Internal map that keeps track of how many times each ID has been triggered,
|
|
22
|
+
* along with the base multiplier used to calculate delays.
|
|
23
|
+
*
|
|
24
|
+
* @type {Map<string, { value: number, now: number }>}
|
|
25
|
+
*/
|
|
26
|
+
#timeoutFixer = new Map();
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates a new instance of TinyTimeout.
|
|
30
|
+
*
|
|
31
|
+
* @param {Object} [options={}] Optional configuration object.
|
|
32
|
+
* @param {number} [options.cooldownWatcherTime=5000] Interval in milliseconds for reducing `now` counters.
|
|
33
|
+
* @param {boolean} [options.allowAutoConfigChange=false] Whether to allow auto value changes for existing IDs.
|
|
34
|
+
*/
|
|
35
|
+
constructor({ cooldownWatcherTime = 5000, allowAutoConfigChange = false } = {}) {
|
|
36
|
+
if (!Number.isFinite(cooldownWatcherTime) || cooldownWatcherTime <= 0)
|
|
37
|
+
throw new TypeError(`Expected 'cooldownWatcherTime' to be a positive number.`);
|
|
38
|
+
if (typeof allowAutoConfigChange !== 'boolean')
|
|
39
|
+
throw new TypeError(`Expected 'allowAutoConfigChange' to be a boolean.`);
|
|
40
|
+
this.#cooldownWatcherTime = cooldownWatcherTime;
|
|
41
|
+
this.#allowAutoConfigChange = allowAutoConfigChange;
|
|
42
|
+
this.setCooldownWatcherTime(cooldownWatcherTime);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Whether this instance has been destroyed and is no longer usable.
|
|
47
|
+
*
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
*/
|
|
50
|
+
isDestroyed() {
|
|
51
|
+
return this.#isDestroyed;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Whether auto config change is enabled.
|
|
56
|
+
*
|
|
57
|
+
* @returns {boolean}
|
|
58
|
+
*/
|
|
59
|
+
getAllowAutoConfigChange() {
|
|
60
|
+
return this.#allowAutoConfigChange;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Gets the interval time used for cooldown decrementing.
|
|
65
|
+
*
|
|
66
|
+
* @returns {number}
|
|
67
|
+
*/
|
|
68
|
+
getCooldownWatcherTime() {
|
|
69
|
+
return this.#cooldownWatcherTime;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Sets whether to allow auto-updating an ID's timeout config if `value` changes.
|
|
74
|
+
*
|
|
75
|
+
* @param {boolean} value
|
|
76
|
+
*/
|
|
77
|
+
setAllowAutoConfigChange(value) {
|
|
78
|
+
if (typeof value !== 'boolean') throw new TypeError(`Expected 'value' to be a boolean.`);
|
|
79
|
+
this.#allowAutoConfigChange = value;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Sets the cooldown watcher interval time.
|
|
84
|
+
* Automatically resets the interval if it was already running.
|
|
85
|
+
*
|
|
86
|
+
* @param {number} value
|
|
87
|
+
*/
|
|
88
|
+
setCooldownWatcherTime(value) {
|
|
89
|
+
if (this.#isDestroyed) throw new Error('TinyTimeout has been destroyed.');
|
|
90
|
+
if (!Number.isFinite(value) || value <= 0)
|
|
91
|
+
throw new TypeError(`Expected 'value' to be a positive number.`);
|
|
92
|
+
|
|
93
|
+
this.#cooldownWatcherTime = value;
|
|
94
|
+
|
|
95
|
+
if (this.#cooldownWatcher) clearInterval(this.#cooldownWatcher);
|
|
96
|
+
this.#cooldownWatcher = setInterval(() => {
|
|
97
|
+
this.#timeoutFixer.forEach((data) => {
|
|
98
|
+
if (data.now > 0) data.now--;
|
|
99
|
+
});
|
|
100
|
+
}, this.#cooldownWatcherTime);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Schedules a callback using a dynamically adjusted timeout based on usage frequency.
|
|
105
|
+
* The more often an ID is triggered, the longer the timeout becomes,
|
|
106
|
+
* scaled by the provided `value`. Optionally, the delay can be limited by `limit`.
|
|
107
|
+
*
|
|
108
|
+
* @param {string} id - A unique identifier to track timeout usage.
|
|
109
|
+
* @param {Function} callback - The function to execute after the delay.
|
|
110
|
+
* @param {number} value - Base delay multiplier in milliseconds.
|
|
111
|
+
* @param {number|null} [limit=null] - Optional maximum delay cap.
|
|
112
|
+
* @returns {number} Handle to the scheduled timeout.
|
|
113
|
+
* @throws {Error} Throws if the instance has been destroyed or arguments are invalid.
|
|
114
|
+
*/
|
|
115
|
+
set(id, callback, value, limit = null) {
|
|
116
|
+
if (this.#isDestroyed) throw new Error('TinyTimeout has been destroyed.');
|
|
117
|
+
if (typeof id !== 'string' || id.trim() === '')
|
|
118
|
+
throw new TypeError(`Expected 'id' to be a non-empty string.`);
|
|
119
|
+
if (typeof callback !== 'function')
|
|
120
|
+
throw new TypeError(`Expected 'callback' to be a function.`);
|
|
121
|
+
if (!Number.isFinite(value) || value < 0)
|
|
122
|
+
throw new TypeError(`Expected 'value' to be a non-negative number.`);
|
|
123
|
+
if (limit !== null && (!Number.isFinite(limit) || limit < 0))
|
|
124
|
+
throw new TypeError(`Expected 'limit' to be null or a non-negative number.`);
|
|
125
|
+
|
|
126
|
+
let entry = this.#timeoutFixer.get(id);
|
|
127
|
+
if (!entry || (this.#allowAutoConfigChange && value !== entry.value)) {
|
|
128
|
+
entry = { value, now: 0 };
|
|
129
|
+
this.#timeoutFixer.set(id, entry);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const delay = entry.value * entry.now;
|
|
133
|
+
entry.now++;
|
|
134
|
+
|
|
135
|
+
return setTimeout(callback, typeof limit === 'number' ? Math.min(delay, limit) : delay);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Waits until a provided function returns `true`, checking repeatedly at the defined interval.
|
|
140
|
+
* Useful for polling asynchronous conditions.
|
|
141
|
+
*
|
|
142
|
+
* @param {() => boolean} getValue - A function that returns `true` when the condition is met.
|
|
143
|
+
* @param {number} [checkInterval=100] - How often (in ms) to check the condition.
|
|
144
|
+
* @returns {Promise<void>} Resolves when the condition is met.
|
|
145
|
+
* @throws {TypeError} If arguments are invalid.
|
|
146
|
+
*/
|
|
147
|
+
static waitForTrue(getValue, checkInterval = 100) {
|
|
148
|
+
if (typeof getValue !== 'function')
|
|
149
|
+
throw new TypeError(`Expected 'getValue' to be a function.`);
|
|
150
|
+
if (!Number.isFinite(checkInterval) || checkInterval <= 0)
|
|
151
|
+
throw new TypeError(`Expected 'checkInterval' to be a positive number.`);
|
|
152
|
+
|
|
153
|
+
return new Promise((resolve) => {
|
|
154
|
+
const interval = setInterval(() => {
|
|
155
|
+
if (getValue()) {
|
|
156
|
+
clearInterval(interval);
|
|
157
|
+
resolve();
|
|
158
|
+
}
|
|
159
|
+
}, checkInterval);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Instance version of `waitForTrue`, which defaults to using the instance's
|
|
165
|
+
* cooldownWatcherTime if not explicitly provided.
|
|
166
|
+
*
|
|
167
|
+
* @param {() => boolean} getValue - A function that returns `true` when the condition is met.
|
|
168
|
+
* @param {number|null} [checkInterval=100] - How often (in ms) to check the condition.
|
|
169
|
+
* @returns {Promise<void>} Resolves when the condition is met.
|
|
170
|
+
* @throws {Error} If the instance is destroyed or arguments are invalid.
|
|
171
|
+
*/
|
|
172
|
+
waitForTrue(getValue, checkInterval = 100) {
|
|
173
|
+
if (this.#isDestroyed) throw new Error('TinyTimeout has been destroyed.');
|
|
174
|
+
if (typeof getValue !== 'function')
|
|
175
|
+
throw new TypeError(`Expected 'getValue' to be a function.`);
|
|
176
|
+
if (checkInterval !== null && (!Number.isFinite(checkInterval) || checkInterval <= 0))
|
|
177
|
+
throw new TypeError(`Expected 'checkInterval' to be null or a positive number.`);
|
|
178
|
+
return TinyTimeout.waitForTrue(getValue, checkInterval ?? this.#cooldownWatcherTime);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Cleans up all internal references and stops the cooldown watcher.
|
|
183
|
+
* After calling this, the instance becomes unusable.
|
|
184
|
+
*/
|
|
185
|
+
destroy() {
|
|
186
|
+
if (this.#isDestroyed) return;
|
|
187
|
+
this.#isDestroyed = true;
|
|
188
|
+
if (this.#cooldownWatcher) clearInterval(this.#cooldownWatcher);
|
|
189
|
+
this.#cooldownWatcher = null;
|
|
190
|
+
this.#timeoutFixer.clear();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
module.exports = TinyTimeout;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export default TinyTimeout;
|
|
2
|
+
/**
|
|
3
|
+
* A utility class to manage dynamically adjusted timeouts based on how often
|
|
4
|
+
* each unique ID is triggered. Also provides polling support for asynchronous conditions.
|
|
5
|
+
*/
|
|
6
|
+
declare class TinyTimeout {
|
|
7
|
+
/**
|
|
8
|
+
* Waits until a provided function returns `true`, checking repeatedly at the defined interval.
|
|
9
|
+
* Useful for polling asynchronous conditions.
|
|
10
|
+
*
|
|
11
|
+
* @param {() => boolean} getValue - A function that returns `true` when the condition is met.
|
|
12
|
+
* @param {number} [checkInterval=100] - How often (in ms) to check the condition.
|
|
13
|
+
* @returns {Promise<void>} Resolves when the condition is met.
|
|
14
|
+
* @throws {TypeError} If arguments are invalid.
|
|
15
|
+
*/
|
|
16
|
+
static waitForTrue(getValue: () => boolean, checkInterval?: number): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Creates a new instance of TinyTimeout.
|
|
19
|
+
*
|
|
20
|
+
* @param {Object} [options={}] Optional configuration object.
|
|
21
|
+
* @param {number} [options.cooldownWatcherTime=5000] Interval in milliseconds for reducing `now` counters.
|
|
22
|
+
* @param {boolean} [options.allowAutoConfigChange=false] Whether to allow auto value changes for existing IDs.
|
|
23
|
+
*/
|
|
24
|
+
constructor({ cooldownWatcherTime, allowAutoConfigChange }?: {
|
|
25
|
+
cooldownWatcherTime?: number | undefined;
|
|
26
|
+
allowAutoConfigChange?: boolean | undefined;
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Whether this instance has been destroyed and is no longer usable.
|
|
30
|
+
*
|
|
31
|
+
* @returns {boolean}
|
|
32
|
+
*/
|
|
33
|
+
isDestroyed(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Whether auto config change is enabled.
|
|
36
|
+
*
|
|
37
|
+
* @returns {boolean}
|
|
38
|
+
*/
|
|
39
|
+
getAllowAutoConfigChange(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Gets the interval time used for cooldown decrementing.
|
|
42
|
+
*
|
|
43
|
+
* @returns {number}
|
|
44
|
+
*/
|
|
45
|
+
getCooldownWatcherTime(): number;
|
|
46
|
+
/**
|
|
47
|
+
* Sets whether to allow auto-updating an ID's timeout config if `value` changes.
|
|
48
|
+
*
|
|
49
|
+
* @param {boolean} value
|
|
50
|
+
*/
|
|
51
|
+
setAllowAutoConfigChange(value: boolean): void;
|
|
52
|
+
/**
|
|
53
|
+
* Sets the cooldown watcher interval time.
|
|
54
|
+
* Automatically resets the interval if it was already running.
|
|
55
|
+
*
|
|
56
|
+
* @param {number} value
|
|
57
|
+
*/
|
|
58
|
+
setCooldownWatcherTime(value: number): void;
|
|
59
|
+
/**
|
|
60
|
+
* Schedules a callback using a dynamically adjusted timeout based on usage frequency.
|
|
61
|
+
* The more often an ID is triggered, the longer the timeout becomes,
|
|
62
|
+
* scaled by the provided `value`. Optionally, the delay can be limited by `limit`.
|
|
63
|
+
*
|
|
64
|
+
* @param {string} id - A unique identifier to track timeout usage.
|
|
65
|
+
* @param {Function} callback - The function to execute after the delay.
|
|
66
|
+
* @param {number} value - Base delay multiplier in milliseconds.
|
|
67
|
+
* @param {number|null} [limit=null] - Optional maximum delay cap.
|
|
68
|
+
* @returns {number} Handle to the scheduled timeout.
|
|
69
|
+
* @throws {Error} Throws if the instance has been destroyed or arguments are invalid.
|
|
70
|
+
*/
|
|
71
|
+
set(id: string, callback: Function, value: number, limit?: number | null): number;
|
|
72
|
+
/**
|
|
73
|
+
* Instance version of `waitForTrue`, which defaults to using the instance's
|
|
74
|
+
* cooldownWatcherTime if not explicitly provided.
|
|
75
|
+
*
|
|
76
|
+
* @param {() => boolean} getValue - A function that returns `true` when the condition is met.
|
|
77
|
+
* @param {number|null} [checkInterval=100] - How often (in ms) to check the condition.
|
|
78
|
+
* @returns {Promise<void>} Resolves when the condition is met.
|
|
79
|
+
* @throws {Error} If the instance is destroyed or arguments are invalid.
|
|
80
|
+
*/
|
|
81
|
+
waitForTrue(getValue: () => boolean, checkInterval?: number | null): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Cleans up all internal references and stops the cooldown watcher.
|
|
84
|
+
* After calling this, the instance becomes unusable.
|
|
85
|
+
*/
|
|
86
|
+
destroy(): void;
|
|
87
|
+
#private;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=TinyTimeout.d.mts.map
|