tiny-essentials 1.28.0 → 1.28.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog/1/28/1.md +23 -0
- package/dist/v1/TinyAdvancedRaffle.min.js +1 -1
- package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
- package/dist/v1/TinyAnalogClock.min.js +1 -1
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyDayNightCycle.min.js +1 -1
- package/dist/v1/TinyDragDropDetector.min.js +1 -1
- package/dist/v1/TinyDragger.min.js +1 -1
- package/dist/v1/TinyElementObserver.min.js +1 -1
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyGamepad.min.js +1 -1
- package/dist/v1/TinyHtml.min.js +1 -1
- package/dist/v1/TinyI18.min.js +1 -1
- package/dist/v1/TinyIframeEvents.min.js +1 -1
- package/dist/v1/TinyLocalStorage.min.js +1 -1
- package/dist/v1/TinyMediaPlayer.min.js +1 -1
- package/dist/v1/TinyNewWinEvents.min.js +1 -1
- package/dist/v1/TinyNotifyCenter.min.js +1 -1
- package/dist/v1/TinyRadioFm.min.js +1 -1
- package/dist/v1/TinyRateLimiter.min.js +1 -1
- package/dist/v1/TinySmartScroller.min.js +1 -1
- package/dist/v1/TinyTextDiffer.min.js +1 -1
- package/dist/v1/TinyTextarea.min.js +1 -1
- package/dist/v1/TinyTimeout.min.js +1 -1
- package/dist/v1/TinyToastNotify.min.js +1 -1
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/UltraRandomMsgGen.min.js +1 -1
- package/dist/v1/basics/array.cjs +57 -9
- package/dist/v1/basics/array.d.mts +27 -11
- package/dist/v1/basics/array.mjs +51 -9
- package/dist/v1/basics/clock.cjs +94 -42
- package/dist/v1/basics/clock.d.mts +10 -10
- package/dist/v1/basics/clock.mjs +91 -54
- package/dist/v1/basics/deprecated/html.cjs +246 -0
- package/dist/v1/basics/deprecated/html.d.mts +63 -0
- package/dist/v1/basics/deprecated/html.mjs +190 -0
- package/dist/v1/basics/html.cjs +149 -130
- package/dist/v1/basics/html.d.mts +26 -61
- package/dist/v1/basics/html.mjs +113 -105
- package/dist/v1/basics/index.cjs +2 -0
- package/dist/v1/basics/index.d.mts +3 -1
- package/dist/v1/basics/index.mjs +3 -3
- package/dist/v1/basics/mediaContent.cjs +51 -9
- package/dist/v1/basics/mediaContent.d.mts +0 -87
- package/dist/v1/basics/mediaContent.mjs +40 -10
- package/dist/v1/basics/objChecker.cjs +7 -5
- package/dist/v1/basics/objChecker.d.mts +3 -2
- package/dist/v1/basics/objChecker.mjs +6 -6
- package/dist/v1/basics/objFilter.cjs +40 -7
- package/dist/v1/basics/objFilter.d.mts +6 -6
- package/dist/v1/basics/objFilter.mjs +32 -7
- package/dist/v1/basics/simpleMath.cjs +81 -25
- package/dist/v1/basics/simpleMath.d.mts +2 -2
- package/dist/v1/basics/simpleMath.mjs +70 -27
- package/dist/v1/basics/text.cjs +76 -31
- package/dist/v1/basics/text.d.mts +69 -7
- package/dist/v1/basics/text.mjs +62 -31
- package/dist/v1/index.cjs +4 -0
- package/dist/v1/index.d.mts +4 -1
- package/dist/v1/index.mjs +4 -3
- package/dist/v1/libs/TinyAdvancedRaffle.cjs +64 -50
- package/dist/v1/libs/TinyAdvancedRaffle.d.mts +4 -13
- package/dist/v1/libs/TinyAdvancedRaffle.mjs +62 -49
- package/dist/v1/libs/TinyAfterScrollWatcher.cjs +17 -1
- package/dist/v1/libs/TinyAfterScrollWatcher.d.mts +4 -1
- package/dist/v1/libs/TinyAfterScrollWatcher.mjs +15 -1
- package/dist/v1/libs/TinyAnalogClock.cjs +60 -0
- package/dist/v1/libs/TinyAnalogClock.d.mts +6 -0
- package/dist/v1/libs/TinyAnalogClock.mjs +57 -0
- package/dist/v1/libs/TinyClipboard.cjs +2 -0
- package/dist/v1/libs/TinyClipboard.d.mts +4 -2
- package/dist/v1/libs/TinyClipboard.mjs +2 -0
- package/dist/v1/libs/TinyColorConverter.cjs +1 -0
- package/dist/v1/libs/TinyColorConverter.d.mts +2 -1
- package/dist/v1/libs/TinyColorConverter.mjs +1 -0
- package/dist/v1/libs/TinyDayNightCycle.cjs +67 -42
- package/dist/v1/libs/TinyDayNightCycle.d.mts +2 -7
- package/dist/v1/libs/TinyDayNightCycle.mjs +65 -41
- package/dist/v1/libs/TinyDragDropDetector.cjs +25 -0
- package/dist/v1/libs/TinyDragDropDetector.d.mts +6 -0
- package/dist/v1/libs/TinyDragDropDetector.mjs +22 -0
- package/dist/v1/libs/TinyDragger.cjs +46 -19
- package/dist/v1/libs/TinyDragger.mjs +45 -18
- package/dist/v1/libs/TinyElementObserver.cjs +39 -0
- package/dist/v1/libs/TinyElementObserver.d.mts +6 -0
- package/dist/v1/libs/TinyElementObserver.mjs +36 -0
- package/dist/v1/libs/TinyGamepad.cjs +131 -1
- package/dist/v1/libs/TinyGamepad.mjs +129 -1
- package/dist/v1/libs/TinyHtml.cjs +1 -1
- package/dist/v1/libs/TinyHtml.mjs +2 -2
- package/dist/v1/libs/TinyI18.cjs +61 -0
- package/dist/v1/libs/TinyI18.d.mts +14 -0
- package/dist/v1/libs/TinyI18.mjs +55 -0
- package/dist/v1/libs/TinyIframeEvents.cjs +18 -1
- package/dist/v1/libs/TinyIframeEvents.mjs +18 -1
- package/dist/v1/libs/TinyLocalStorage.cjs +48 -0
- package/dist/v1/libs/TinyLocalStorage.d.mts +6 -0
- package/dist/v1/libs/TinyLocalStorage.mjs +45 -0
- package/dist/v1/libs/TinyMediaPlayer.cjs +72 -0
- package/dist/v1/libs/TinyMediaPlayer.d.mts +10 -0
- package/dist/v1/libs/TinyMediaPlayer.mjs +66 -0
- package/dist/v1/libs/TinyNewWinEvents.cjs +29 -0
- package/dist/v1/libs/TinyNewWinEvents.d.mts +6 -0
- package/dist/v1/libs/TinyNewWinEvents.mjs +26 -0
- package/dist/v1/libs/TinyNotifyCenter.cjs +36 -0
- package/dist/v1/libs/TinyNotifyCenter.d.mts +6 -0
- package/dist/v1/libs/TinyNotifyCenter.mjs +32 -0
- package/dist/v1/libs/TinyRadioFm.cjs +38 -0
- package/dist/v1/libs/TinyRadioFm.d.mts +1 -0
- package/dist/v1/libs/TinyRadioFm.mjs +35 -0
- package/dist/v1/libs/TinyRateLimiter.cjs +52 -0
- package/dist/v1/libs/TinyRateLimiter.d.mts +6 -0
- package/dist/v1/libs/TinyRateLimiter.mjs +48 -0
- package/dist/v1/libs/TinySmartScroller.cjs +52 -3
- package/dist/v1/libs/TinySmartScroller.d.mts +17 -15
- package/dist/v1/libs/TinySmartScroller.mjs +51 -5
- package/dist/v1/libs/TinyTextDiffer.cjs +19 -18
- package/dist/v1/libs/TinyTextDiffer.d.mts +1 -0
- package/dist/v1/libs/TinyTextDiffer.mjs +16 -17
- package/dist/v1/libs/TinyTextarea.cjs +19 -0
- package/dist/v1/libs/TinyTextarea.d.mts +6 -0
- package/dist/v1/libs/TinyTextarea.mjs +17 -0
- package/dist/v1/libs/TinyTimeout.cjs +11 -1
- package/dist/v1/libs/TinyTimeout.mjs +9 -1
- package/dist/v1/libs/TinyToastNotify.cjs +35 -0
- package/dist/v1/libs/TinyToastNotify.d.mts +6 -0
- package/dist/v1/libs/TinyToastNotify.mjs +31 -0
- package/dist/v1/libs/TinyUploadClicker.cjs +19 -0
- package/dist/v1/libs/TinyUploadClicker.d.mts +6 -0
- package/dist/v1/libs/TinyUploadClicker.mjs +17 -0
- package/dist/v1/libs/UltraRandomMsgGen.cjs +148 -35
- package/dist/v1/libs/UltraRandomMsgGen.d.mts +17 -3
- package/dist/v1/libs/UltraRandomMsgGen.mjs +133 -34
- package/dist/v1/libs/utils.cjs +21 -0
- package/dist/v1/libs/utils.d.mts +2 -0
- package/dist/v1/libs/utils.mjs +16 -0
- package/docs/v1/README.md +1 -0
- package/docs/v1/basics/array.md +2 -2
- package/docs/v1/basics/deprecated/html.md +17 -0
- package/docs/v1/basics/fullScreen.md +1 -1
- package/docs/v1/basics/html.md +12 -26
- package/docs/v1/basics/mediaContent.md +1 -1
- package/docs/v1/basics/objChecker.md +1 -1
- package/docs/v1/basics/text.md +2 -2
- package/docs/v1/fileManager/main.md +1 -1
- package/docs/v1/libs/ColorSafeStringify.md +1 -1
- package/docs/v1/libs/TinyAfterScrollWatcher.md +1 -1
- package/docs/v1/libs/TinyAnalogClock.md +1 -1
- package/docs/v1/libs/TinyArrayComparator.md +1 -1
- package/docs/v1/libs/TinyArrayPaginator.md +1 -1
- package/docs/v1/libs/TinyClassManager/TinyPluginInliner.md +2 -2
- package/docs/v1/libs/TinyClassManager.md +1 -1
- package/docs/v1/libs/TinyClipboard.md +1 -1
- package/docs/v1/libs/TinyCookieConsent.md +1 -1
- package/docs/v1/libs/TinyDomReadyManager.md +1 -1
- package/docs/v1/libs/TinyDragDropDetector.md +1 -1
- package/docs/v1/libs/TinyDragger.md +1 -1
- package/docs/v1/libs/TinyElementObserver.md +1 -1
- package/docs/v1/libs/TinyHtml.md +1 -1
- package/docs/v1/libs/TinyIframeEvents.md +2 -2
- package/docs/v1/libs/TinyLevelUp.md +1 -1
- package/docs/v1/libs/TinyLoadingScreen.md +1 -1
- package/docs/v1/libs/TinyNewWinEvents.md +2 -2
- package/docs/v1/libs/TinyNotifications.md +1 -1
- package/docs/v1/libs/TinyPromiseQueue.md +2 -2
- package/docs/v1/libs/TinyTextDiffer.md +1 -1
- package/docs/v1/libs/TinyTextarea.md +1 -1
- package/package.json +10 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { createCheckDestroyed } from './utils.mjs';
|
|
2
|
+
const checkDestroy = createCheckDestroyed('TinyRateLimiter');
|
|
1
3
|
/**
|
|
2
4
|
* Callback triggered when a group's stored hit history exceeds
|
|
3
5
|
* the configured memory limit.
|
|
@@ -66,6 +68,19 @@
|
|
|
66
68
|
* and safe to use in long-running Node.js processes.
|
|
67
69
|
*/
|
|
68
70
|
class TinyRateLimiter {
|
|
71
|
+
/**
|
|
72
|
+
* Tracks whether the instance has been destroyed.
|
|
73
|
+
* @type {boolean}
|
|
74
|
+
*/
|
|
75
|
+
#destroyed = false;
|
|
76
|
+
/**
|
|
77
|
+
* Gets the current destruction status of the instance.
|
|
78
|
+
*
|
|
79
|
+
* @returns {boolean} True if the instance is destroyed, false otherwise.
|
|
80
|
+
*/
|
|
81
|
+
get destroyed() {
|
|
82
|
+
return this.#destroyed;
|
|
83
|
+
}
|
|
69
84
|
/**
|
|
70
85
|
* Maximum number of timestamps stored per group.
|
|
71
86
|
* When exceeded, older entries are discarded.
|
|
@@ -170,6 +185,7 @@ class TinyRateLimiter {
|
|
|
170
185
|
* @param {OnMemoryExceeded} callback
|
|
171
186
|
*/
|
|
172
187
|
setOnMemoryExceeded(callback) {
|
|
188
|
+
checkDestroy(this.#destroyed);
|
|
173
189
|
if (typeof callback !== 'function')
|
|
174
190
|
throw new Error('onMemoryExceeded must be a function');
|
|
175
191
|
this.#onMemoryExceeded = callback;
|
|
@@ -178,6 +194,7 @@ class TinyRateLimiter {
|
|
|
178
194
|
* Removes the memory-exceeded callback.
|
|
179
195
|
*/
|
|
180
196
|
clearOnMemoryExceeded() {
|
|
197
|
+
checkDestroy(this.#destroyed);
|
|
181
198
|
this.#onMemoryExceeded = null;
|
|
182
199
|
}
|
|
183
200
|
/**
|
|
@@ -195,6 +212,7 @@ class TinyRateLimiter {
|
|
|
195
212
|
* @param {OnGroupExpired} callback - A function that receives the expired groupId.
|
|
196
213
|
*/
|
|
197
214
|
setOnGroupExpired(callback) {
|
|
215
|
+
checkDestroy(this.#destroyed);
|
|
198
216
|
if (typeof callback !== 'function')
|
|
199
217
|
throw new Error('onGroupExpired must be a function');
|
|
200
218
|
this.#onGroupExpired = callback;
|
|
@@ -203,6 +221,7 @@ class TinyRateLimiter {
|
|
|
203
221
|
* Removes the group-expiration callback.
|
|
204
222
|
*/
|
|
205
223
|
clearOnGroupExpired() {
|
|
224
|
+
checkDestroy(this.#destroyed);
|
|
206
225
|
this.#onGroupExpired = null;
|
|
207
226
|
}
|
|
208
227
|
/**
|
|
@@ -262,6 +281,7 @@ class TinyRateLimiter {
|
|
|
262
281
|
* @returns {boolean}
|
|
263
282
|
*/
|
|
264
283
|
isGroupId(id) {
|
|
284
|
+
checkDestroy(this.#destroyed);
|
|
265
285
|
const result = this.groupFlags.get(id);
|
|
266
286
|
return typeof result === 'boolean' ? result : false;
|
|
267
287
|
}
|
|
@@ -271,6 +291,7 @@ class TinyRateLimiter {
|
|
|
271
291
|
* @returns {string[]}
|
|
272
292
|
*/
|
|
273
293
|
getUsersInGroup(groupId) {
|
|
294
|
+
checkDestroy(this.#destroyed);
|
|
274
295
|
const users = [];
|
|
275
296
|
for (const [userId, assignedGroup] of this.userToGroup.entries()) {
|
|
276
297
|
if (assignedGroup === groupId) {
|
|
@@ -285,6 +306,7 @@ class TinyRateLimiter {
|
|
|
285
306
|
* @param {number} ttl
|
|
286
307
|
*/
|
|
287
308
|
setGroupTTL(groupId, ttl) {
|
|
309
|
+
checkDestroy(this.#destroyed);
|
|
288
310
|
if (typeof ttl !== 'number' || !Number.isFinite(ttl) || ttl <= 0)
|
|
289
311
|
throw new Error('TTL must be a positive number in milliseconds');
|
|
290
312
|
this.groupTTL.set(groupId, ttl);
|
|
@@ -295,6 +317,7 @@ class TinyRateLimiter {
|
|
|
295
317
|
* @returns {number|null}
|
|
296
318
|
*/
|
|
297
319
|
getGroupTTL(groupId) {
|
|
320
|
+
checkDestroy(this.#destroyed);
|
|
298
321
|
return this.groupTTL.get(groupId) ?? null;
|
|
299
322
|
}
|
|
300
323
|
/**
|
|
@@ -302,6 +325,7 @@ class TinyRateLimiter {
|
|
|
302
325
|
* @param {string} groupId
|
|
303
326
|
*/
|
|
304
327
|
deleteGroupTTL(groupId) {
|
|
328
|
+
checkDestroy(this.#destroyed);
|
|
305
329
|
this.groupTTL.delete(groupId);
|
|
306
330
|
}
|
|
307
331
|
/**
|
|
@@ -315,6 +339,7 @@ class TinyRateLimiter {
|
|
|
315
339
|
* @throws {Error} If the user belongs to another group
|
|
316
340
|
*/
|
|
317
341
|
assignToGroup(userId, groupId) {
|
|
342
|
+
checkDestroy(this.#destroyed);
|
|
318
343
|
const existingGroup = this.userToGroup.get(userId);
|
|
319
344
|
if (existingGroup && existingGroup !== groupId)
|
|
320
345
|
throw new Error(`User ${userId} is already assigned to group ${existingGroup}`);
|
|
@@ -363,6 +388,7 @@ class TinyRateLimiter {
|
|
|
363
388
|
* @returns {string}
|
|
364
389
|
*/
|
|
365
390
|
getGroupId(userId) {
|
|
391
|
+
checkDestroy(this.#destroyed);
|
|
366
392
|
return this.userToGroup.get(userId) || userId; // fallback: use userId as own group
|
|
367
393
|
}
|
|
368
394
|
/**
|
|
@@ -388,6 +414,7 @@ class TinyRateLimiter {
|
|
|
388
414
|
* @param {string} userId
|
|
389
415
|
*/
|
|
390
416
|
hit(userId) {
|
|
417
|
+
checkDestroy(this.#destroyed);
|
|
391
418
|
const groupId = this.getGroupId(userId);
|
|
392
419
|
const now = Date.now();
|
|
393
420
|
if (!this.groupData.has(groupId)) {
|
|
@@ -437,6 +464,7 @@ class TinyRateLimiter {
|
|
|
437
464
|
* @returns {boolean}
|
|
438
465
|
*/
|
|
439
466
|
isRateLimited(userId) {
|
|
467
|
+
checkDestroy(this.#destroyed);
|
|
440
468
|
const groupId = this.getGroupId(userId);
|
|
441
469
|
if (!this.groupData.has(groupId))
|
|
442
470
|
return false;
|
|
@@ -468,6 +496,7 @@ class TinyRateLimiter {
|
|
|
468
496
|
* @param {string} groupId
|
|
469
497
|
*/
|
|
470
498
|
resetGroup(groupId) {
|
|
499
|
+
checkDestroy(this.#destroyed);
|
|
471
500
|
this.groupFlags.delete(groupId);
|
|
472
501
|
this.groupData.delete(groupId);
|
|
473
502
|
this.lastSeen.delete(groupId);
|
|
@@ -478,6 +507,7 @@ class TinyRateLimiter {
|
|
|
478
507
|
* @param {string} userId
|
|
479
508
|
*/
|
|
480
509
|
resetUserGroup(userId) {
|
|
510
|
+
checkDestroy(this.#destroyed);
|
|
481
511
|
this.userToGroup.delete(userId);
|
|
482
512
|
}
|
|
483
513
|
/**
|
|
@@ -486,6 +516,7 @@ class TinyRateLimiter {
|
|
|
486
516
|
* @param {number[]} timestamps
|
|
487
517
|
*/
|
|
488
518
|
setData(groupId, timestamps) {
|
|
519
|
+
checkDestroy(this.#destroyed);
|
|
489
520
|
if (!Array.isArray(timestamps))
|
|
490
521
|
throw new Error('timestamps must be an array of numbers.');
|
|
491
522
|
for (const t of timestamps) {
|
|
@@ -504,6 +535,7 @@ class TinyRateLimiter {
|
|
|
504
535
|
* @returns {boolean}
|
|
505
536
|
*/
|
|
506
537
|
hasData(groupId) {
|
|
538
|
+
checkDestroy(this.#destroyed);
|
|
507
539
|
return this.groupData.has(groupId);
|
|
508
540
|
}
|
|
509
541
|
/**
|
|
@@ -512,6 +544,7 @@ class TinyRateLimiter {
|
|
|
512
544
|
* @returns {number[]}
|
|
513
545
|
*/
|
|
514
546
|
getData(groupId) {
|
|
547
|
+
checkDestroy(this.#destroyed);
|
|
515
548
|
return this.groupData.get(groupId) || [];
|
|
516
549
|
}
|
|
517
550
|
/**
|
|
@@ -519,6 +552,7 @@ class TinyRateLimiter {
|
|
|
519
552
|
* @returns {number}
|
|
520
553
|
*/
|
|
521
554
|
getMaxIdle() {
|
|
555
|
+
checkDestroy(this.#destroyed);
|
|
522
556
|
if (typeof this.#maxIdle !== 'number' || !Number.isFinite(this.#maxIdle) || this.#maxIdle < 0) {
|
|
523
557
|
throw new Error("'maxIdle' must be a non-negative finite number.");
|
|
524
558
|
}
|
|
@@ -529,6 +563,7 @@ class TinyRateLimiter {
|
|
|
529
563
|
* @param {number} ms
|
|
530
564
|
*/
|
|
531
565
|
setMaxIdle(ms) {
|
|
566
|
+
checkDestroy(this.#destroyed);
|
|
532
567
|
if (typeof ms !== 'number' || !Number.isFinite(ms) || ms < 0) {
|
|
533
568
|
throw new Error("'maxIdle' must be a non-negative finite number.");
|
|
534
569
|
}
|
|
@@ -559,6 +594,7 @@ class TinyRateLimiter {
|
|
|
559
594
|
* @returns {string[]}
|
|
560
595
|
*/
|
|
561
596
|
getActiveGroups() {
|
|
597
|
+
checkDestroy(this.#destroyed);
|
|
562
598
|
return Array.from(this.groupData.keys());
|
|
563
599
|
}
|
|
564
600
|
/**
|
|
@@ -566,6 +602,7 @@ class TinyRateLimiter {
|
|
|
566
602
|
* @returns {Record<string, string>}
|
|
567
603
|
*/
|
|
568
604
|
getAllUserMappings() {
|
|
605
|
+
checkDestroy(this.#destroyed);
|
|
569
606
|
return Object.fromEntries(this.userToGroup);
|
|
570
607
|
}
|
|
571
608
|
/**
|
|
@@ -577,6 +614,7 @@ class TinyRateLimiter {
|
|
|
577
614
|
* @returns {number}
|
|
578
615
|
*/
|
|
579
616
|
getInterval() {
|
|
617
|
+
checkDestroy(this.#destroyed);
|
|
580
618
|
if (typeof this.#interval !== 'number' || !Number.isFinite(this.#interval)) {
|
|
581
619
|
throw new Error("'interval' is not a valid finite number.");
|
|
582
620
|
}
|
|
@@ -587,6 +625,7 @@ class TinyRateLimiter {
|
|
|
587
625
|
* @returns {number}
|
|
588
626
|
*/
|
|
589
627
|
getMaxHits() {
|
|
628
|
+
checkDestroy(this.#destroyed);
|
|
590
629
|
if (typeof this.#maxHits !== 'number' || !Number.isFinite(this.#maxHits)) {
|
|
591
630
|
throw new Error("'maxHits' is not a valid finite number.");
|
|
592
631
|
}
|
|
@@ -598,6 +637,7 @@ class TinyRateLimiter {
|
|
|
598
637
|
* @returns {number}
|
|
599
638
|
*/
|
|
600
639
|
getTotalHits(groupId) {
|
|
640
|
+
checkDestroy(this.#destroyed);
|
|
601
641
|
const history = this.groupData.get(groupId);
|
|
602
642
|
return Array.isArray(history) ? history.length : 0;
|
|
603
643
|
}
|
|
@@ -607,6 +647,7 @@ class TinyRateLimiter {
|
|
|
607
647
|
* @returns {number|null}
|
|
608
648
|
*/
|
|
609
649
|
getLastHit(groupId) {
|
|
650
|
+
checkDestroy(this.#destroyed);
|
|
610
651
|
const history = this.groupData.get(groupId);
|
|
611
652
|
return history?.length ? history[history.length - 1] : null;
|
|
612
653
|
}
|
|
@@ -616,6 +657,7 @@ class TinyRateLimiter {
|
|
|
616
657
|
* @returns {number|null}
|
|
617
658
|
*/
|
|
618
659
|
getTimeSinceLastHit(groupId) {
|
|
660
|
+
checkDestroy(this.#destroyed);
|
|
619
661
|
const last = this.getLastHit(groupId);
|
|
620
662
|
return last !== null ? Date.now() - last : null;
|
|
621
663
|
}
|
|
@@ -640,6 +682,7 @@ class TinyRateLimiter {
|
|
|
640
682
|
* @returns {number|null}
|
|
641
683
|
*/
|
|
642
684
|
getAverageHitSpacing(groupId) {
|
|
685
|
+
checkDestroy(this.#destroyed);
|
|
643
686
|
return this._calculateAverageSpacing(this.groupData.get(groupId));
|
|
644
687
|
}
|
|
645
688
|
/**
|
|
@@ -653,6 +696,7 @@ class TinyRateLimiter {
|
|
|
653
696
|
* }}
|
|
654
697
|
*/
|
|
655
698
|
getMetrics(groupId) {
|
|
699
|
+
checkDestroy(this.#destroyed);
|
|
656
700
|
const history = this.groupData.get(groupId);
|
|
657
701
|
if (!Array.isArray(history) || history.length === 0) {
|
|
658
702
|
return {
|
|
@@ -677,6 +721,8 @@ class TinyRateLimiter {
|
|
|
677
721
|
* Destroy the rate limiter, stopping cleanup and clearing data
|
|
678
722
|
*/
|
|
679
723
|
destroy() {
|
|
724
|
+
if (this.destroyed)
|
|
725
|
+
return;
|
|
680
726
|
if (this.#cleanupTimer)
|
|
681
727
|
clearInterval(this.#cleanupTimer);
|
|
682
728
|
this._cleanup();
|
|
@@ -685,6 +731,8 @@ class TinyRateLimiter {
|
|
|
685
731
|
this.userToGroup.clear();
|
|
686
732
|
this.groupTTL.clear();
|
|
687
733
|
this.groupFlags.clear();
|
|
734
|
+
// Lock the instance
|
|
735
|
+
this.#destroyed = true;
|
|
688
736
|
}
|
|
689
737
|
}
|
|
690
738
|
export default TinyRateLimiter;
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
var events = require('events');
|
|
4
4
|
var TinyHtml = require('./TinyHtml.cjs');
|
|
5
5
|
var collision = require('../basics/collision.cjs');
|
|
6
|
+
var utils = require('./utils.cjs');
|
|
7
|
+
|
|
8
|
+
const checkDestroy = utils.createCheckDestroyed('TinySmartScroller');
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* Represents the dimensions of a DOM element.
|
|
@@ -227,6 +230,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
227
230
|
* @returns {NodeSizesEvent} A function that compares previous and current height, returning height delta.
|
|
228
231
|
*/
|
|
229
232
|
getSimpleOnHeight(filter = []) {
|
|
233
|
+
checkDestroy(this.#destroyed);
|
|
230
234
|
if (!Array.isArray(filter))
|
|
231
235
|
throw new TypeError('getSimpleOnHeight(filter): filter must be an array of tag names');
|
|
232
236
|
return (elem, sizes, amounts) => {
|
|
@@ -246,6 +250,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
246
250
|
* @returns {NodeSizesEvent} The added size difference callback.
|
|
247
251
|
*/
|
|
248
252
|
addSimpleOnHeight(filter) {
|
|
253
|
+
checkDestroy(this.#destroyed);
|
|
249
254
|
if (!Array.isArray(filter))
|
|
250
255
|
throw new TypeError('addSimpleOnHeight(filter): filter must be an array of tag names');
|
|
251
256
|
const result = this.getSimpleOnHeight(filter);
|
|
@@ -259,6 +264,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
259
264
|
* @returns {string[]} Array of tag names.
|
|
260
265
|
*/
|
|
261
266
|
getLoadTags() {
|
|
267
|
+
checkDestroy(this.#destroyed);
|
|
262
268
|
return Array.from(this.#loadTags);
|
|
263
269
|
}
|
|
264
270
|
|
|
@@ -268,6 +274,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
268
274
|
* @param {string} tag - The tag name to add (e.g., 'IMG').
|
|
269
275
|
*/
|
|
270
276
|
addLoadTag(tag) {
|
|
277
|
+
checkDestroy(this.#destroyed);
|
|
271
278
|
if (typeof tag !== 'string') throw new TypeError('addLoadTag(tag): tag must be a string');
|
|
272
279
|
this.#loadTags.add(tag.toUpperCase());
|
|
273
280
|
}
|
|
@@ -278,6 +285,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
278
285
|
* @param {string} tag - The tag name to remove.
|
|
279
286
|
*/
|
|
280
287
|
removeLoadTag(tag) {
|
|
288
|
+
checkDestroy(this.#destroyed);
|
|
281
289
|
if (typeof tag !== 'string') throw new TypeError('removeLoadTag(tag): tag must be a string');
|
|
282
290
|
this.#loadTags.delete(tag.toUpperCase());
|
|
283
291
|
}
|
|
@@ -289,6 +297,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
289
297
|
* @returns {boolean} True if the tag is being tracked.
|
|
290
298
|
*/
|
|
291
299
|
hasLoadTag(tag) {
|
|
300
|
+
checkDestroy(this.#destroyed);
|
|
292
301
|
if (typeof tag !== 'string') throw new TypeError('hasLoadTag(tag): tag must be a string');
|
|
293
302
|
return this.#loadTags.has(tag.toUpperCase());
|
|
294
303
|
}
|
|
@@ -300,6 +309,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
300
309
|
* @throws {TypeError} If `addDefault` is not a boolean.
|
|
301
310
|
*/
|
|
302
311
|
resetLoadTags(addDefault = false) {
|
|
312
|
+
checkDestroy(this.#destroyed);
|
|
303
313
|
if (typeof addDefault !== 'boolean')
|
|
304
314
|
throw new TypeError('resetLoadTags(addDefault): addDefault must be a boolean');
|
|
305
315
|
this.#loadTags.clear();
|
|
@@ -315,6 +325,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
315
325
|
* @returns {string[]} Array of attribute names.
|
|
316
326
|
*/
|
|
317
327
|
getAttributeFilters() {
|
|
328
|
+
checkDestroy(this.#destroyed);
|
|
318
329
|
return Array.from(this.#attributeFilter);
|
|
319
330
|
}
|
|
320
331
|
|
|
@@ -324,6 +335,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
324
335
|
* @param {string} attr - The attribute name to add.
|
|
325
336
|
*/
|
|
326
337
|
addAttributeFilter(attr) {
|
|
338
|
+
checkDestroy(this.#destroyed);
|
|
327
339
|
if (typeof attr !== 'string')
|
|
328
340
|
throw new TypeError('addAttributeFilter(attr): attr must be a string');
|
|
329
341
|
this.#attributeFilter.add(attr);
|
|
@@ -335,6 +347,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
335
347
|
* @param {string} attr - The attribute name to remove.
|
|
336
348
|
*/
|
|
337
349
|
removeAttributeFilter(attr) {
|
|
350
|
+
checkDestroy(this.#destroyed);
|
|
338
351
|
if (typeof attr !== 'string')
|
|
339
352
|
throw new TypeError('removeAttributeFilter(attr): attr must be a string');
|
|
340
353
|
this.#attributeFilter.delete(attr);
|
|
@@ -347,6 +360,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
347
360
|
* @returns {boolean} True if the attribute is being filtered.
|
|
348
361
|
*/
|
|
349
362
|
hasAttributeFilter(attr) {
|
|
363
|
+
checkDestroy(this.#destroyed);
|
|
350
364
|
if (typeof attr !== 'string')
|
|
351
365
|
throw new TypeError('hasAttributeFilter(attr): attr must be a string');
|
|
352
366
|
return this.#attributeFilter.has(attr);
|
|
@@ -360,6 +374,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
360
374
|
* @throws {TypeError} If `addDefault` is not a boolean.
|
|
361
375
|
*/
|
|
362
376
|
resetAttributeFilters(addDefault = false) {
|
|
377
|
+
checkDestroy(this.#destroyed);
|
|
363
378
|
if (typeof addDefault !== 'boolean')
|
|
364
379
|
throw new TypeError('resetAttributeFilters(addDefault): addDefault must be a boolean');
|
|
365
380
|
this.#attributeFilter.clear();
|
|
@@ -375,7 +390,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
375
390
|
* @param {NodeSizesEvent} handler - Function that compares old and new sizes.
|
|
376
391
|
*/
|
|
377
392
|
onSize(handler) {
|
|
378
|
-
|
|
393
|
+
checkDestroy(this.#destroyed);
|
|
379
394
|
if (typeof handler !== 'function')
|
|
380
395
|
throw new TypeError('onSize(handler): handler must be a function');
|
|
381
396
|
this.#sizeFilter.add(handler);
|
|
@@ -387,7 +402,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
387
402
|
* @param {NodeSizesEvent} handler - The handler function to remove.
|
|
388
403
|
*/
|
|
389
404
|
offSize(handler) {
|
|
390
|
-
|
|
405
|
+
checkDestroy(this.#destroyed);
|
|
391
406
|
if (typeof handler !== 'function')
|
|
392
407
|
throw new TypeError('offSize(handler): handler must be a function');
|
|
393
408
|
this.#sizeFilter.delete(handler);
|
|
@@ -397,6 +412,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
397
412
|
* Checks which elements inside the target are currently visible and updates internal maps.
|
|
398
413
|
*
|
|
399
414
|
* @returns {Map<Element, { oldIsVisible: boolean; isVisible: boolean }>} Visibility comparison results.
|
|
415
|
+
* @private
|
|
400
416
|
*/
|
|
401
417
|
_scrollDataUpdater() {
|
|
402
418
|
const results = new Map();
|
|
@@ -414,6 +430,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
414
430
|
|
|
415
431
|
/**
|
|
416
432
|
* Handles scroll events, calculates position-related statuses, and emits appropriate events.
|
|
433
|
+
* @private
|
|
417
434
|
*/
|
|
418
435
|
_onScroll() {
|
|
419
436
|
if (this.#destroyed) return;
|
|
@@ -475,6 +492,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
475
492
|
* Attempts to correct the scroll position when layout shifts happen, preserving the user position if needed.
|
|
476
493
|
*
|
|
477
494
|
* @param {Element[]} [targets=[]] - List of elements involved in the size change.
|
|
495
|
+
* @private
|
|
478
496
|
*/
|
|
479
497
|
_fixScroll(targets = []) {
|
|
480
498
|
if (this.#destroyed) return;
|
|
@@ -564,6 +582,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
564
582
|
}
|
|
565
583
|
/**
|
|
566
584
|
* Sets up a MutationObserver to watch for DOM changes and react accordingly to maintain scroll consistency.
|
|
585
|
+
* @private
|
|
567
586
|
*/
|
|
568
587
|
_observeMutations() {
|
|
569
588
|
this.#mutationObserver = new MutationObserver((mutations) => {
|
|
@@ -604,6 +623,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
604
623
|
* Adds a ResizeObserver to monitor elements' size changes and trigger layout adjustments.
|
|
605
624
|
*
|
|
606
625
|
* @param {NodeListOf<Element>|Element[]|HTMLCollection} elements - Elements to observe.
|
|
626
|
+
* @private
|
|
607
627
|
*/
|
|
608
628
|
_observeResizes(elements) {
|
|
609
629
|
// Add resize observer
|
|
@@ -644,6 +664,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
644
664
|
* Listens for media/content load events (e.g., images, iframes, videos) to trigger scroll updates.
|
|
645
665
|
*
|
|
646
666
|
* @param {NodeListOf<Element>|Element} elements - Target element(s) to listen on.
|
|
667
|
+
* @private
|
|
647
668
|
*/
|
|
648
669
|
_listenLoadEvents(elements) {
|
|
649
670
|
if (this.#destroyed) return;
|
|
@@ -682,6 +703,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
682
703
|
* @returns {NodeSizes|null} The old size, or undefined.
|
|
683
704
|
*/
|
|
684
705
|
getOldSize(el) {
|
|
706
|
+
checkDestroy(this.#destroyed);
|
|
685
707
|
return this.#oldSizes.get(el) ?? null;
|
|
686
708
|
}
|
|
687
709
|
|
|
@@ -692,6 +714,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
692
714
|
* @returns {NodeSizes|null} The new size, or undefined.
|
|
693
715
|
*/
|
|
694
716
|
getNewSize(el) {
|
|
717
|
+
checkDestroy(this.#destroyed);
|
|
695
718
|
return this.#newSizes.get(el) ?? null;
|
|
696
719
|
}
|
|
697
720
|
|
|
@@ -702,6 +725,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
702
725
|
* @returns {boolean} True if visible, false if not, or undefined if not tracked.
|
|
703
726
|
*/
|
|
704
727
|
wasVisible(el) {
|
|
728
|
+
checkDestroy(this.#destroyed);
|
|
705
729
|
return this.#oldVisibles.get(el) ?? false;
|
|
706
730
|
}
|
|
707
731
|
|
|
@@ -712,6 +736,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
712
736
|
* @returns {boolean} True if visible, false if not, or undefined if not tracked.
|
|
713
737
|
*/
|
|
714
738
|
isVisible(el) {
|
|
739
|
+
checkDestroy(this.#destroyed);
|
|
715
740
|
return this.#newVisibles.get(el) ?? false;
|
|
716
741
|
}
|
|
717
742
|
|
|
@@ -722,6 +747,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
722
747
|
* @returns {boolean} Visibility state from the previous timed check.
|
|
723
748
|
*/
|
|
724
749
|
wasTimedVisible(el) {
|
|
750
|
+
checkDestroy(this.#destroyed);
|
|
725
751
|
return this.#oldVisiblesByTime.get(el) ?? false;
|
|
726
752
|
}
|
|
727
753
|
|
|
@@ -732,6 +758,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
732
758
|
* @returns {boolean} Visibility state from the current timed check.
|
|
733
759
|
*/
|
|
734
760
|
isTimedVisible(el) {
|
|
761
|
+
checkDestroy(this.#destroyed);
|
|
735
762
|
return this.#newVisiblesByTime.get(el) ?? false;
|
|
736
763
|
}
|
|
737
764
|
|
|
@@ -741,6 +768,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
741
768
|
* @param {number} value - Pixels of additional margin to use.
|
|
742
769
|
*/
|
|
743
770
|
setExtraScrollBoundary(value) {
|
|
771
|
+
checkDestroy(this.#destroyed);
|
|
744
772
|
if (typeof value !== 'number' || Number.isNaN(value))
|
|
745
773
|
throw new TypeError('setExtraScrollBoundary(value): value must be a valid number');
|
|
746
774
|
this.#extraScrollBoundary = value;
|
|
@@ -752,6 +780,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
752
780
|
* @returns {number}
|
|
753
781
|
*/
|
|
754
782
|
getExtraScrollBoundary() {
|
|
783
|
+
checkDestroy(this.#destroyed);
|
|
755
784
|
return this.#extraScrollBoundary;
|
|
756
785
|
}
|
|
757
786
|
|
|
@@ -761,6 +790,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
761
790
|
* @returns {number}
|
|
762
791
|
*/
|
|
763
792
|
getLastKnownScrollBottomOffset() {
|
|
793
|
+
checkDestroy(this.#destroyed);
|
|
764
794
|
return this.#lastKnownScrollBottomOffset;
|
|
765
795
|
}
|
|
766
796
|
|
|
@@ -768,6 +798,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
768
798
|
* Forces the scroll position to move to the very bottom of the target.
|
|
769
799
|
*/
|
|
770
800
|
scrollToBottom() {
|
|
801
|
+
checkDestroy(this.#destroyed);
|
|
771
802
|
this.#targetElement.scrollTop = this.#targetElement.scrollHeight;
|
|
772
803
|
}
|
|
773
804
|
|
|
@@ -775,6 +806,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
775
806
|
* Forces the scroll position to move to the very top of the target.
|
|
776
807
|
*/
|
|
777
808
|
scrollToTop() {
|
|
809
|
+
checkDestroy(this.#destroyed);
|
|
778
810
|
this.#targetElement.scrollTop = 0;
|
|
779
811
|
}
|
|
780
812
|
|
|
@@ -784,6 +816,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
784
816
|
* @returns {boolean}
|
|
785
817
|
*/
|
|
786
818
|
isAtCustomBottom() {
|
|
819
|
+
checkDestroy(this.#destroyed);
|
|
787
820
|
return this.#isAtCustomBottom;
|
|
788
821
|
}
|
|
789
822
|
|
|
@@ -793,6 +826,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
793
826
|
* @returns {boolean}
|
|
794
827
|
*/
|
|
795
828
|
isAtCustomTop() {
|
|
829
|
+
checkDestroy(this.#destroyed);
|
|
796
830
|
return this.#isAtCustomTop;
|
|
797
831
|
}
|
|
798
832
|
|
|
@@ -802,6 +836,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
802
836
|
* @returns {boolean}
|
|
803
837
|
*/
|
|
804
838
|
isAtBottom() {
|
|
839
|
+
checkDestroy(this.#destroyed);
|
|
805
840
|
return this.#isAtBottom;
|
|
806
841
|
}
|
|
807
842
|
|
|
@@ -811,6 +846,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
811
846
|
* @returns {boolean}
|
|
812
847
|
*/
|
|
813
848
|
isAtTop() {
|
|
849
|
+
checkDestroy(this.#destroyed);
|
|
814
850
|
return this.#isAtTop;
|
|
815
851
|
}
|
|
816
852
|
|
|
@@ -820,6 +856,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
820
856
|
* @returns {boolean}
|
|
821
857
|
*/
|
|
822
858
|
isPastAtBottom() {
|
|
859
|
+
checkDestroy(this.#destroyed);
|
|
823
860
|
return this.#isPastAtBottom;
|
|
824
861
|
}
|
|
825
862
|
|
|
@@ -829,6 +866,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
829
866
|
* @returns {boolean}
|
|
830
867
|
*/
|
|
831
868
|
isPastAtTop() {
|
|
869
|
+
checkDestroy(this.#destroyed);
|
|
832
870
|
return this.#isPastAtTop;
|
|
833
871
|
}
|
|
834
872
|
|
|
@@ -838,6 +876,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
838
876
|
* @returns {boolean}
|
|
839
877
|
*/
|
|
840
878
|
isPastAtCustomTop() {
|
|
879
|
+
checkDestroy(this.#destroyed);
|
|
841
880
|
return this.#isPastAtCustomTop;
|
|
842
881
|
}
|
|
843
882
|
|
|
@@ -847,6 +886,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
847
886
|
* @returns {boolean}
|
|
848
887
|
*/
|
|
849
888
|
isPastAtCustomBottom() {
|
|
889
|
+
checkDestroy(this.#destroyed);
|
|
850
890
|
return this.#isPastAtCustomBottom;
|
|
851
891
|
}
|
|
852
892
|
|
|
@@ -856,6 +896,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
856
896
|
* @returns {boolean}
|
|
857
897
|
*/
|
|
858
898
|
isScrollPaused() {
|
|
899
|
+
checkDestroy(this.#destroyed);
|
|
859
900
|
return this.#scrollPaused;
|
|
860
901
|
}
|
|
861
902
|
|
|
@@ -865,6 +906,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
865
906
|
* @returns {boolean} True if the scroll target is window, false otherwise.
|
|
866
907
|
*/
|
|
867
908
|
isWindow() {
|
|
909
|
+
checkDestroy(this.#destroyed);
|
|
868
910
|
return this.#useWindow;
|
|
869
911
|
}
|
|
870
912
|
|
|
@@ -883,6 +925,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
883
925
|
* @returns {boolean} True if auto-scroll is active, false otherwise.
|
|
884
926
|
*/
|
|
885
927
|
getAutoScrollBottom() {
|
|
928
|
+
checkDestroy(this.#destroyed);
|
|
886
929
|
return this.#autoScrollBottom;
|
|
887
930
|
}
|
|
888
931
|
|
|
@@ -892,6 +935,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
892
935
|
* @returns {boolean} True if mutation observation is active, false otherwise.
|
|
893
936
|
*/
|
|
894
937
|
getObserveMutations() {
|
|
938
|
+
checkDestroy(this.#destroyed);
|
|
895
939
|
return this.#observeMutations;
|
|
896
940
|
}
|
|
897
941
|
|
|
@@ -901,6 +945,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
901
945
|
* @returns {boolean} True if scroll preservation is active, false otherwise.
|
|
902
946
|
*/
|
|
903
947
|
getPreserveScrollOnLayoutShift() {
|
|
948
|
+
checkDestroy(this.#destroyed);
|
|
904
949
|
return this.#preserveScrollOnLayoutShift;
|
|
905
950
|
}
|
|
906
951
|
|
|
@@ -910,6 +955,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
910
955
|
* @returns {number} Debounce delay time.
|
|
911
956
|
*/
|
|
912
957
|
getDebounceTime() {
|
|
958
|
+
checkDestroy(this.#destroyed);
|
|
913
959
|
return this.#debounceTime;
|
|
914
960
|
}
|
|
915
961
|
|
|
@@ -919,6 +965,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
919
965
|
* @returns {number} Current count of matching elements.
|
|
920
966
|
*/
|
|
921
967
|
getElemAmount() {
|
|
968
|
+
checkDestroy(this.#destroyed);
|
|
922
969
|
return this.#elemAmount;
|
|
923
970
|
}
|
|
924
971
|
|
|
@@ -928,6 +975,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
928
975
|
* @returns {number} Previous count of matching elements.
|
|
929
976
|
*/
|
|
930
977
|
getPrevElemAmount() {
|
|
978
|
+
checkDestroy(this.#destroyed);
|
|
931
979
|
return this.#elemOldAmount;
|
|
932
980
|
}
|
|
933
981
|
|
|
@@ -937,6 +985,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
937
985
|
* @returns {string} The CSS selector string, or an empty string if none was provided.
|
|
938
986
|
*/
|
|
939
987
|
getQuerySelector() {
|
|
988
|
+
checkDestroy(this.#destroyed);
|
|
940
989
|
return this.#querySelector;
|
|
941
990
|
}
|
|
942
991
|
|
|
@@ -946,7 +995,6 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
946
995
|
*/
|
|
947
996
|
destroy() {
|
|
948
997
|
if (this.#destroyed) return;
|
|
949
|
-
this.#destroyed = true;
|
|
950
998
|
|
|
951
999
|
// Disconnects MutationObserver
|
|
952
1000
|
if (this.#mutationObserver) {
|
|
@@ -976,6 +1024,7 @@ class TinySmartScroller extends events.EventEmitter {
|
|
|
976
1024
|
this.removeAllListeners();
|
|
977
1025
|
this.#sizeFilter.clear();
|
|
978
1026
|
this.#loadTags.clear();
|
|
1027
|
+
this.#destroyed = true;
|
|
979
1028
|
}
|
|
980
1029
|
}
|
|
981
1030
|
|