tiny-essentials 1.18.1 → 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.
Files changed (74) hide show
  1. package/README.md +17 -3
  2. package/dist/node_modules/firebase-functions/lib/common/trace.cjs +0 -1
  3. package/dist/node_modules/firebase-functions/lib/logger/index.cjs +1 -0
  4. package/dist/v1/ColorSafeStringify.min.js +1 -1
  5. package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
  6. package/dist/v1/TinyBasicsEs.js +13 -6
  7. package/dist/v1/TinyBasicsEs.min.js +1 -1
  8. package/dist/v1/TinyClipboard.min.js +1 -1
  9. package/dist/v1/TinyColorConverter.js +617 -0
  10. package/dist/v1/TinyColorConverter.min.js +1 -0
  11. package/dist/v1/TinyDomReadyManager.min.js +1 -1
  12. package/dist/v1/TinyDragger.min.js +1 -1
  13. package/dist/v1/TinyEssentials.js +2635 -482
  14. package/dist/v1/TinyEssentials.min.js +1 -1
  15. package/dist/v1/TinyEvents.js +402 -0
  16. package/dist/v1/TinyEvents.min.js +1 -0
  17. package/dist/v1/TinyHtml.min.js +1 -1
  18. package/dist/v1/TinyLocalStorage.js +1292 -0
  19. package/dist/v1/TinyLocalStorage.min.js +1 -0
  20. package/dist/v1/TinyNotifications.min.js +1 -1
  21. package/dist/v1/TinyNotifyCenter.min.js +1 -1
  22. package/dist/v1/TinyPromiseQueue.min.js +1 -1
  23. package/dist/v1/TinyRateLimiter.js +2 -1
  24. package/dist/v1/TinyRateLimiter.min.js +1 -1
  25. package/dist/v1/TinySmartScroller.js +570 -52
  26. package/dist/v1/TinySmartScroller.min.js +1 -1
  27. package/dist/v1/TinyTextRangeEditor.min.js +1 -1
  28. package/dist/v1/TinyTimeout.js +233 -0
  29. package/dist/v1/TinyTimeout.min.js +1 -0
  30. package/dist/v1/TinyToastNotify.min.js +1 -1
  31. package/dist/v1/TinyUploadClicker.js +1457 -106
  32. package/dist/v1/TinyUploadClicker.min.js +1 -1
  33. package/dist/v1/UltraRandomMsgGen.min.js +1 -1
  34. package/dist/v1/basics/html.cjs +13 -6
  35. package/dist/v1/basics/html.d.mts +12 -4
  36. package/dist/v1/basics/html.mjs +13 -6
  37. package/dist/v1/build/TinyColorConverter.cjs +7 -0
  38. package/dist/v1/build/TinyColorConverter.d.mts +3 -0
  39. package/dist/v1/build/TinyColorConverter.mjs +2 -0
  40. package/dist/v1/build/TinyEvents.cjs +7 -0
  41. package/dist/v1/build/TinyEvents.d.mts +3 -0
  42. package/dist/v1/build/TinyEvents.mjs +2 -0
  43. package/dist/v1/build/TinyLocalStorage.cjs +7 -0
  44. package/dist/v1/build/TinyLocalStorage.d.mts +3 -0
  45. package/dist/v1/build/TinyLocalStorage.mjs +2 -0
  46. package/dist/v1/build/TinyTimeout.cjs +7 -0
  47. package/dist/v1/build/TinyTimeout.d.mts +3 -0
  48. package/dist/v1/build/TinyTimeout.mjs +2 -0
  49. package/dist/v1/index.cjs +8 -0
  50. package/dist/v1/index.d.mts +5 -1
  51. package/dist/v1/index.mjs +5 -1
  52. package/dist/v1/libs/TinyColorConverter.cjs +578 -0
  53. package/dist/v1/libs/TinyColorConverter.d.mts +396 -0
  54. package/dist/v1/libs/TinyColorConverter.mjs +520 -0
  55. package/dist/v1/libs/TinyEvents.cjs +363 -0
  56. package/dist/v1/libs/TinyEvents.d.mts +160 -0
  57. package/dist/v1/libs/TinyEvents.mjs +328 -0
  58. package/dist/v1/libs/TinyLocalStorage.cjs +847 -0
  59. package/dist/v1/libs/TinyLocalStorage.d.mts +407 -0
  60. package/dist/v1/libs/TinyLocalStorage.mjs +740 -0
  61. package/dist/v1/libs/TinySmartScroller.cjs +207 -52
  62. package/dist/v1/libs/TinySmartScroller.d.mts +164 -16
  63. package/dist/v1/libs/TinySmartScroller.mjs +181 -52
  64. package/dist/v1/libs/TinyTimeout.cjs +194 -0
  65. package/dist/v1/libs/TinyTimeout.d.mts +89 -0
  66. package/dist/v1/libs/TinyTimeout.mjs +179 -0
  67. package/dist/v1/libs/TinyUploadClicker.cjs +1 -0
  68. package/docs/v1/README.md +4 -0
  69. package/docs/v1/libs/TinyColorConverter.md +220 -0
  70. package/docs/v1/libs/TinyEvents.md +199 -0
  71. package/docs/v1/libs/TinyLocalStorage.md +350 -0
  72. package/docs/v1/libs/TinyRateLimiter.md +0 -3
  73. package/docs/v1/libs/TinyTimeout.md +190 -0
  74. package/package.json +28 -5
@@ -5535,10 +5535,374 @@ class TinyHtml {
5535
5535
 
5536
5536
  /* harmony default export */ const libs_TinyHtml = (TinyHtml);
5537
5537
 
5538
+ ;// ./src/v1/libs/TinyEvents.mjs
5539
+ /**
5540
+ * A generic event listener callback function.
5541
+ *
5542
+ * @callback handler
5543
+ * @param {...any} payload - The data payload passed when the event is triggered.
5544
+ * @returns {void}
5545
+ */
5546
+
5547
+ /**
5548
+ * TinyEvents provides a minimalistic event emitter system similar to Node.js's EventEmitter,
5549
+ * enabling components to subscribe to, emit, and manage events and their listeners.
5550
+ *
5551
+ * Features include:
5552
+ * - Adding/removing event listeners (`on`, `off`, `offAll`, `offAllTypes`)
5553
+ * - One-time listeners (`once`)
5554
+ * - Emitting events (`emit`)
5555
+ * - Listener inspection and limits (`listenerCount`, `listeners`, `eventNames`)
5556
+ * - Maximum listener control (`setMaxListeners`, `getMaxListeners`)
5557
+ *
5558
+ * This class is useful for lightweight, dependency-free publish/subscribe event handling
5559
+ * within modular JavaScript applications.
5560
+ *
5561
+ * @class
5562
+ */
5563
+ class TinyEvents {
5564
+ /** @type {Map<string, { handler: handler; config: { once: boolean } }[]>} */
5565
+ #listeners = new Map();
5566
+
5567
+ /** @type {number} */
5568
+ #maxListeners = 10;
5569
+
5570
+ /** @type {boolean} */
5571
+ #throwMaxListeners = false;
5572
+
5573
+ /**
5574
+ * Enables or disables throwing an error when the maximum number of listeners is exceeded.
5575
+ *
5576
+ * @param {boolean} shouldThrow - If true, an error will be thrown when the max is exceeded.
5577
+ */
5578
+ setThrowOnMaxListeners(shouldThrow) {
5579
+ if (typeof shouldThrow !== 'boolean')
5580
+ throw new TypeError('setThrowOnMaxListeners(value): value must be a boolean');
5581
+ this.#throwMaxListeners = shouldThrow;
5582
+ }
5583
+
5584
+ /**
5585
+ * Checks whether an error will be thrown when the max listener limit is exceeded.
5586
+ *
5587
+ * @returns {boolean} True if an error will be thrown, false if only a warning is shown.
5588
+ */
5589
+ getThrowOnMaxListeners() {
5590
+ return this.#throwMaxListeners;
5591
+ }
5592
+
5593
+ ///////////////////////////////////////////////////
5594
+
5595
+ /**
5596
+ * Internal method to prepend a listener with options.
5597
+ *
5598
+ * @param {string} event - Event name.
5599
+ * @param {handler} handler - The callback function.
5600
+ * @param {Object} [settings={}] - Optional settings.
5601
+ * @param {boolean} [settings.once=false] - If the listener should be executed once.
5602
+ */
5603
+ #prepend(event, handler, { once = false } = {}) {
5604
+ let eventData = this.#listeners.get(event);
5605
+ if (!Array.isArray(eventData)) {
5606
+ eventData = [];
5607
+ this.#listeners.set(event, eventData);
5608
+ }
5609
+ eventData.unshift({ handler, config: { once } });
5610
+
5611
+ const max = this.#maxListeners;
5612
+ if (max > 0 && eventData.length > max) {
5613
+ const warnMessage =
5614
+ `Possible memory leak detected. ${eventData.length} "${event}" listeners added. ` +
5615
+ `Use setMaxListeners() to increase limit.`;
5616
+ if (!this.#throwMaxListeners) console.warn(warnMessage);
5617
+ else throw new Error(warnMessage);
5618
+ }
5619
+ }
5620
+
5621
+ /**
5622
+ * Adds a listener to the beginning of the listeners array for the specified event.
5623
+ *
5624
+ * @param {string} event - Event name.
5625
+ * @param {handler} handler - The callback function.
5626
+ */
5627
+ prependListener(event, handler) {
5628
+ if (typeof event !== 'string')
5629
+ throw new TypeError('prepend(event, handler): event name must be a string');
5630
+ if (typeof handler !== 'function')
5631
+ throw new TypeError('prepend(event, handler): handler must be a function');
5632
+ this.#prepend(event, handler);
5633
+ }
5634
+
5635
+ /**
5636
+ * Adds a one-time listener to the beginning of the listeners array for the specified event.
5637
+ *
5638
+ * @param {string} event - Event name.
5639
+ * @param {handler} handler - The callback function.
5640
+ * @returns {handler} - The wrapped handler used internally.
5641
+ */
5642
+ prependListenerOnce(event, handler) {
5643
+ if (typeof event !== 'string')
5644
+ throw new TypeError('prependOnceListener(event, handler): event name must be a string');
5645
+ if (typeof handler !== 'function')
5646
+ throw new TypeError('prependOnceListener(event, handler): handler must be a function');
5647
+
5648
+ /** @type {handler} */
5649
+ const wrapped = (...args) => {
5650
+ this.off(event, wrapped);
5651
+ handler(...args);
5652
+ };
5653
+
5654
+ this.#prepend(event, wrapped, { once: true });
5655
+ return wrapped;
5656
+ }
5657
+
5658
+ ////////////////////////////////////////////////////////////
5659
+
5660
+ /**
5661
+ * Adds a event listener.
5662
+ *
5663
+ * @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
5664
+ * @param {handler} handler - Callback function to be called when event fires.
5665
+ * @param {Object} [settings={}] - Optional settings.
5666
+ * @param {boolean} [settings.once=false] - This is a once event.
5667
+ */
5668
+ #on(event, handler, { once = false } = {}) {
5669
+ let eventData = this.#listeners.get(event);
5670
+ if (!Array.isArray(eventData)) {
5671
+ eventData = [];
5672
+ this.#listeners.set(event, eventData);
5673
+ }
5674
+ eventData.push({ handler, config: { once } });
5675
+ // Warn if listener count exceeds the max allowed
5676
+ const max = this.#maxListeners;
5677
+ if (max > 0 && eventData.length > max) {
5678
+ const warnMessage =
5679
+ `Possible memory leak detected. ${eventData.length} "${event}" listeners added. ` +
5680
+ `Use setMaxListeners() to increase limit.`;
5681
+ if (!this.#throwMaxListeners) console.warn(warnMessage);
5682
+ else throw new Error(warnMessage);
5683
+ }
5684
+ }
5685
+
5686
+ /**
5687
+ * Adds a event listener.
5688
+ *
5689
+ * @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
5690
+ * @param {handler} handler - Callback function to be called when event fires.
5691
+ */
5692
+ on(event, handler) {
5693
+ if (typeof event !== 'string')
5694
+ throw new TypeError('on(event, handler): event name must be a string');
5695
+ if (typeof handler !== 'function')
5696
+ throw new TypeError('on(event, handler): handler must be a function');
5697
+ return this.#on(event, handler);
5698
+ }
5699
+
5700
+ /**
5701
+ * Registers an event listener that runs only once, then is removed.
5702
+ *
5703
+ * @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
5704
+ * @param {handler} handler - The callback function to run on event.
5705
+ * @returns {handler} - The wrapped version of the handler.
5706
+ */
5707
+ once(event, handler) {
5708
+ if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
5709
+ if (typeof handler !== 'function')
5710
+ throw new TypeError('once(event, handler): handler must be a function');
5711
+
5712
+ /** @type {handler} */
5713
+ const wrapped = (e) => {
5714
+ this.off(event, wrapped);
5715
+ if (typeof handler === 'function') handler(e);
5716
+ };
5717
+ this.#on(event, wrapped, { once: true });
5718
+ return wrapped;
5719
+ }
5720
+
5721
+ /**
5722
+ * Adds a event listener.
5723
+ *
5724
+ * @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
5725
+ * @param {handler} handler - Callback function to be called when event fires.
5726
+ */
5727
+ appendListener(event, handler) {
5728
+ return this.on(event, handler);
5729
+ }
5730
+
5731
+ /**
5732
+ * Registers an event listener that runs only once, then is removed.
5733
+ *
5734
+ * @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
5735
+ * @param {handler} handler - The callback function to run on event.
5736
+ * @returns {handler} - The wrapped version of the handler.
5737
+ */
5738
+ appendListenerOnce(event, handler) {
5739
+ return this.once(event, handler);
5740
+ }
5741
+
5742
+ ///////////////////////////////////////////////
5743
+
5744
+ /**
5745
+ * Removes a previously registered event listener.
5746
+ *
5747
+ * @param {string} event - The name of the event to remove the handler from.
5748
+ * @param {handler} handler - The specific callback function to remove.
5749
+ */
5750
+ off(event, handler) {
5751
+ if (typeof event !== 'string')
5752
+ throw new TypeError('off(event, handler): event name must be a string');
5753
+ if (typeof handler !== 'function')
5754
+ throw new TypeError('off(event, handler): handler must be a function');
5755
+
5756
+ const listeners = this.#listeners.get(event);
5757
+ if (!Array.isArray(listeners)) return;
5758
+
5759
+ const index = listeners.findIndex((listener) => listener.handler === handler);
5760
+ if (index !== -1) listeners.splice(index, 1);
5761
+
5762
+ // Optionally clean up empty arrays (optional)
5763
+ if (listeners.length === 0) this.#listeners.delete(event);
5764
+ }
5765
+
5766
+ /**
5767
+ * Removes all event listeners of a specific type from the element.
5768
+ *
5769
+ * @param {string} event - The event type to remove (e.g. 'onScrollBoundary').
5770
+ */
5771
+ offAll(event) {
5772
+ if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
5773
+ this.#listeners.delete(event);
5774
+ }
5775
+
5776
+ /**
5777
+ * Removes all event listeners of all types from the element.
5778
+ */
5779
+ offAllTypes() {
5780
+ this.#listeners.clear();
5781
+ }
5782
+
5783
+ /////////////////////////////////////////////
5784
+
5785
+ /**
5786
+ * Returns the number of listeners for a given event.
5787
+ *
5788
+ * @param {string} event - The name of the event.
5789
+ * @returns {number} Number of listeners for the event.
5790
+ */
5791
+ listenerCount(event) {
5792
+ if (typeof event !== 'string')
5793
+ throw new TypeError('listenerCount(event): event name must be a string');
5794
+
5795
+ const listeners = this.#listeners.get(event);
5796
+ return Array.isArray(listeners) ? listeners.length : 0;
5797
+ }
5798
+
5799
+ /**
5800
+ * Returns a copy of the array of listeners for the specified event.
5801
+ *
5802
+ * @param {string} event - The name of the event.
5803
+ * @returns {handler[]} Array of listener functions.
5804
+ */
5805
+ listeners(event) {
5806
+ if (typeof event !== 'string')
5807
+ throw new TypeError('listeners(event): event name must be a string');
5808
+
5809
+ const listeners = this.#listeners.get(event);
5810
+ return Array.isArray(listeners)
5811
+ ? [...listeners]
5812
+ .filter((listener) => !listener.config.once)
5813
+ .map((listener) => listener.handler)
5814
+ : [];
5815
+ }
5816
+
5817
+ /**
5818
+ * Returns a copy of the array of listeners for the specified event.
5819
+ *
5820
+ * @param {string} event - The name of the event.
5821
+ * @returns {handler[]} Array of listener functions.
5822
+ */
5823
+ onceListeners(event) {
5824
+ if (typeof event !== 'string')
5825
+ throw new TypeError('onceListeners(event): event name must be a string');
5826
+
5827
+ const listeners = this.#listeners.get(event);
5828
+ return Array.isArray(listeners)
5829
+ ? [...listeners]
5830
+ .filter((listener) => listener.config.once)
5831
+ .map((listener) => listener.handler)
5832
+ : [];
5833
+ }
5834
+
5835
+ /**
5836
+ * Returns a copy of the internal listeners array for the specified event,
5837
+ * including wrapper functions like those used by `.once()`.
5838
+ * @param {string | symbol} event - The event name.
5839
+ * @returns {handler[]} An array of raw listener functions.
5840
+ */
5841
+ allListeners(event) {
5842
+ if (typeof event !== 'string')
5843
+ throw new TypeError('allListeners(event): event name must be a string');
5844
+ const listeners = this.#listeners.get(event);
5845
+ return Array.isArray(listeners) ? [...listeners].map((listener) => listener.handler) : [];
5846
+ }
5847
+
5848
+ /**
5849
+ * Returns an array of event names for which there are registered listeners.
5850
+ *
5851
+ * @returns {string[]} Array of registered event names.
5852
+ */
5853
+ eventNames() {
5854
+ return [...this.#listeners.keys()];
5855
+ }
5856
+
5857
+ /**
5858
+ * Emits an event, triggering all registered handlers for that event.
5859
+ *
5860
+ * @param {string} event - The event name to emit.
5861
+ * @param {...any} payload - Optional data to pass to each handler.
5862
+ * @returns {boolean} True if any listeners were called, false otherwise.
5863
+ */
5864
+ emit(event, ...payload) {
5865
+ if (typeof event !== 'string')
5866
+ throw new TypeError('emit(event, data): event name must be a string');
5867
+
5868
+ const listeners = this.#listeners.get(event);
5869
+ if (!Array.isArray(listeners) || listeners.length === 0) return false;
5870
+
5871
+ // Call all listeners with the provided data
5872
+ listeners.forEach((listener) => listener.handler(...payload));
5873
+ return true;
5874
+ }
5875
+
5876
+ ///////////////////////////////////
5877
+
5878
+ /**
5879
+ * Sets the maximum number of listeners per event before a warning is shown.
5880
+ *
5881
+ * @param {number} n - The maximum number of listeners.
5882
+ */
5883
+ setMaxListeners(n) {
5884
+ if (!Number.isInteger(n) || n < 0)
5885
+ throw new TypeError('setMaxListeners(n): n must be a non-negative integer');
5886
+ this.#maxListeners = n;
5887
+ }
5888
+
5889
+ /**
5890
+ * Gets the maximum number of listeners allowed per event.
5891
+ *
5892
+ * @returns {number} The maximum number of listeners.
5893
+ */
5894
+ getMaxListeners() {
5895
+ return this.#maxListeners;
5896
+ }
5897
+ }
5898
+
5899
+ /* harmony default export */ const libs_TinyEvents = (TinyEvents);
5900
+
5538
5901
  ;// ./src/v1/libs/TinySmartScroller.mjs
5539
5902
 
5540
5903
 
5541
5904
 
5905
+
5542
5906
  /**
5543
5907
  * Represents the dimensions of a DOM element.
5544
5908
  *
@@ -5585,6 +5949,205 @@ class TinyHtml {
5585
5949
  class TinySmartScroller {
5586
5950
  static Utils = { ...collision_namespaceObject, TinyHtml: libs_TinyHtml };
5587
5951
 
5952
+ #events = new libs_TinyEvents();
5953
+
5954
+ /**
5955
+ * Enables or disables throwing an error when the maximum number of listeners is exceeded.
5956
+ *
5957
+ * @param {boolean} shouldThrow - If true, an error will be thrown when the max is exceeded.
5958
+ */
5959
+ setThrowOnMaxListeners(shouldThrow) {
5960
+ return this.#events.setThrowOnMaxListeners(shouldThrow);
5961
+ }
5962
+
5963
+ /**
5964
+ * Checks whether an error will be thrown when the max listener limit is exceeded.
5965
+ *
5966
+ * @returns {boolean} True if an error will be thrown, false if only a warning is shown.
5967
+ */
5968
+ getThrowOnMaxListeners() {
5969
+ return this.#events.getThrowOnMaxListeners();
5970
+ }
5971
+
5972
+ /////////////////////////////////////////////////////////////
5973
+
5974
+ /**
5975
+ * Adds a listener to the beginning of the listeners array for the specified event.
5976
+ *
5977
+ * @param {string} event - Event name.
5978
+ * @param {ScrollListenersFunc} handler - The callback function.
5979
+ */
5980
+ prependListener(event, handler) {
5981
+ return this.#events.prependListener(event, handler);
5982
+ }
5983
+
5984
+ /**
5985
+ * Adds a one-time listener to the beginning of the listeners array for the specified event.
5986
+ *
5987
+ * @param {string} event - Event name.
5988
+ * @param {ScrollListenersFunc} handler - The callback function.
5989
+ * @returns {ScrollListenersFunc} - The wrapped handler used internally.
5990
+ */
5991
+ prependListenerOnce(event, handler) {
5992
+ return this.#events.prependListenerOnce(event, handler);
5993
+ }
5994
+
5995
+ //////////////////////////////////////////////////////////////////////
5996
+
5997
+ /**
5998
+ * Adds a event listener.
5999
+ *
6000
+ * @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
6001
+ * @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
6002
+ */
6003
+ appendListener(event, handler) {
6004
+ return this.#events.appendListener(event, handler);
6005
+ }
6006
+
6007
+ /**
6008
+ * Registers an event listener that runs only once, then is removed.
6009
+ *
6010
+ * @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
6011
+ * @param {ScrollListenersFunc} handler - The callback function to run on event.
6012
+ * @returns {ScrollListenersFunc} - The wrapped version of the handler.
6013
+ */
6014
+ appendListenerOnce(event, handler) {
6015
+ return this.#events.appendListenerOnce(event, handler);
6016
+ }
6017
+
6018
+ /**
6019
+ * Adds a event listener.
6020
+ *
6021
+ * @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
6022
+ * @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
6023
+ */
6024
+ on(event, handler) {
6025
+ return this.#events.on(event, handler);
6026
+ }
6027
+
6028
+ /**
6029
+ * Registers an event listener that runs only once, then is removed.
6030
+ *
6031
+ * @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
6032
+ * @param {ScrollListenersFunc} handler - The callback function to run on event.
6033
+ * @returns {ScrollListenersFunc} - The wrapped version of the handler.
6034
+ */
6035
+ once(event, handler) {
6036
+ return this.#events.once(event, handler);
6037
+ }
6038
+
6039
+ ////////////////////////////////////////////////////////////////////
6040
+
6041
+ /**
6042
+ * Removes a previously registered event listener.
6043
+ *
6044
+ * @param {string} event - The name of the event to remove the handler from.
6045
+ * @param {ScrollListenersFunc} handler - The specific callback function to remove.
6046
+ */
6047
+ off(event, handler) {
6048
+ return this.#events.off(event, handler);
6049
+ }
6050
+
6051
+ /**
6052
+ * Removes all event listeners of a specific type from the element.
6053
+ *
6054
+ * @param {string} event - The event type to remove (e.g. 'onScrollBoundary').
6055
+ */
6056
+ offAll(event) {
6057
+ return this.#events.offAll(event);
6058
+ }
6059
+
6060
+ /**
6061
+ * Removes all event listeners of all types from the element.
6062
+ */
6063
+ offAllTypes() {
6064
+ return this.#events.offAllTypes();
6065
+ }
6066
+
6067
+ ////////////////////////////////////////////////////////////
6068
+
6069
+ /**
6070
+ * Returns the number of listeners for a given event.
6071
+ *
6072
+ * @param {string} event - The name of the event.
6073
+ * @returns {number} Number of listeners for the event.
6074
+ */
6075
+ listenerCount(event) {
6076
+ return this.#events.listenerCount(event);
6077
+ }
6078
+
6079
+ /**
6080
+ * Returns a copy of the array of listeners for the specified event.
6081
+ *
6082
+ * @param {string} event - The name of the event.
6083
+ * @returns {ScrollListenersFunc[]} Array of listener functions.
6084
+ */
6085
+ listeners(event) {
6086
+ return this.#events.listeners(event);
6087
+ }
6088
+
6089
+ /**
6090
+ * Returns a copy of the array of listeners for the specified event.
6091
+ *
6092
+ * @param {string} event - The name of the event.
6093
+ * @returns {ScrollListenersFunc[]} Array of listener functions.
6094
+ */
6095
+ onceListeners(event) {
6096
+ return this.#events.onceListeners(event);
6097
+ }
6098
+
6099
+ /**
6100
+ * Returns a copy of the internal listeners array for the specified event,
6101
+ * including wrapper functions like those used by `.once()`.
6102
+ * @param {string | symbol} event - The event name.
6103
+ * @returns {ScrollListenersFunc[]} An array of raw listener functions.
6104
+ */
6105
+ allListeners(event) {
6106
+ return this.#events.allListeners(event);
6107
+ }
6108
+
6109
+ /**
6110
+ * Returns an array of event names for which there are registered listeners.
6111
+ *
6112
+ * @returns {string[]} Array of registered event names.
6113
+ */
6114
+ eventNames() {
6115
+ return this.#events.eventNames();
6116
+ }
6117
+
6118
+ //////////////////////////////////////////////////////
6119
+
6120
+ /**
6121
+ * Emits an event, triggering all registered handlers for that event.
6122
+ *
6123
+ * @param {string} event - The event name to emit.
6124
+ * @param {...any} payload - Optional data to pass to each handler.
6125
+ * @returns {boolean} True if any listeners were called, false otherwise.
6126
+ */
6127
+ emit(event, ...payload) {
6128
+ return this.#events.emit(event, ...payload);
6129
+ }
6130
+
6131
+ /**
6132
+ * Sets the maximum number of listeners per event before a warning is shown.
6133
+ *
6134
+ * @param {number} n - The maximum number of listeners.
6135
+ */
6136
+ setMaxListeners(n) {
6137
+ return this.#events.setMaxListeners(n);
6138
+ }
6139
+
6140
+ /**
6141
+ * Gets the maximum number of listeners allowed per event.
6142
+ *
6143
+ * @returns {number} The maximum number of listeners.
6144
+ */
6145
+ getMaxListeners() {
6146
+ return this.#events.getMaxListeners();
6147
+ }
6148
+
6149
+ ///////////////////////////////////////////////////
6150
+
5588
6151
  /** @type {WeakMap<Element, NodeSizes>} */
5589
6152
  #oldSizes = new WeakMap();
5590
6153
  /** @type {WeakMap<Element, NodeSizes>} */
@@ -5600,9 +6163,6 @@ class TinySmartScroller {
5600
6163
  /** @type {WeakMap<Element, boolean>} */
5601
6164
  #oldVisiblesByTime = new WeakMap();
5602
6165
 
5603
- /** @type {Record<string, ScrollListenersFunc[]>} */
5604
- #scrollListeners = {};
5605
-
5606
6166
  /** @type {ResizeObserver|null} */
5607
6167
  #resizeObserver = null;
5608
6168
  /** @type {MutationObserver|null} */
@@ -5916,46 +6476,6 @@ class TinySmartScroller {
5916
6476
  this.#sizeFilter.delete(handler);
5917
6477
  }
5918
6478
 
5919
- /**
5920
- * Adds a scroll-related event listener.
5921
- *
5922
- * @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
5923
- * @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
5924
- */
5925
- on(event, handler) {
5926
- if (this.#destroyed) return;
5927
- if (typeof event !== 'string')
5928
- throw new TypeError('on(event, handler): event name must be a string');
5929
- if (typeof handler !== 'function')
5930
- throw new TypeError('on(event, handler): handler must be a function');
5931
-
5932
- if (!this.#scrollListeners[event]) this.#scrollListeners[event] = [];
5933
- this.#scrollListeners[event].push(handler);
5934
- }
5935
-
5936
- /**
5937
- * Removes a previously registered scroll-related event listener.
5938
- *
5939
- * @param {string} event - The name of the event to remove the handler from.
5940
- * @param {ScrollListenersFunc} handler - The specific callback function to remove.
5941
- */
5942
- off(event, handler) {
5943
- if (this.#destroyed) return;
5944
- if (typeof event !== 'string')
5945
- throw new TypeError('off(event, handler): event name must be a string');
5946
- if (typeof handler !== 'function')
5947
- throw new TypeError('off(event, handler): handler must be a function');
5948
-
5949
- const listeners = this.#scrollListeners[event];
5950
- if (!Array.isArray(listeners)) return;
5951
-
5952
- const index = listeners.indexOf(handler);
5953
- if (index !== -1) listeners.splice(index, 1);
5954
-
5955
- // Optionally clean up empty arrays (optional)
5956
- if (listeners.length === 0) delete this.#scrollListeners[event];
5957
- }
5958
-
5959
6479
  /**
5960
6480
  * Checks which elements inside the target are currently visible and updates internal maps.
5961
6481
  *
@@ -5980,12 +6500,10 @@ class TinySmartScroller {
5980
6500
  *
5981
6501
  * @param {string} event - Event name.
5982
6502
  * @param {*} [payload] - Optional event data payload.
6503
+ * @deprecated - Use emit() instead.
5983
6504
  */
5984
6505
  _emit(event, payload) {
5985
- if (this.#destroyed) return;
5986
- if (typeof event !== 'string')
5987
- throw new TypeError('_emit(event, payload): event name must be a string');
5988
- (this.#scrollListeners[event] || []).forEach((fn) => fn(payload));
6506
+ this.emit(event, payload);
5989
6507
  }
5990
6508
 
5991
6509
  /**
@@ -6031,13 +6549,13 @@ class TinySmartScroller {
6031
6549
  this.#lastKnownScrollBottomOffset = scrollHeight - scrollTop - clientHeight;
6032
6550
 
6033
6551
  // Send results
6034
- this._emit('onScrollBoundary', { status: atResult, ...scrollResult, scrollCache });
6035
- this._emit('onExtraScrollBoundary', { status: atCustomResult, ...scrollResult, scrollCache });
6552
+ this.emit('onScrollBoundary', { status: atResult, ...scrollResult, scrollCache });
6553
+ this.emit('onExtraScrollBoundary', { status: atCustomResult, ...scrollResult, scrollCache });
6036
6554
 
6037
6555
  if (!this.#scrollPaused) {
6038
- this._emit('onAutoScroll', { ...scrollResult, scrollCache });
6556
+ this.emit('onAutoScroll', { ...scrollResult, scrollCache });
6039
6557
  } else {
6040
- this._emit('onScrollPause', { ...scrollResult, scrollCache });
6558
+ this.emit('onScrollPause', { ...scrollResult, scrollCache });
6041
6559
  }
6042
6560
  }
6043
6561
 
@@ -6503,7 +7021,7 @@ class TinySmartScroller {
6503
7021
  this.#oldVisiblesByTime = new WeakMap();
6504
7022
 
6505
7023
  // Cleans listeners and filters
6506
- this.#scrollListeners = {};
7024
+ this.#events.offAllTypes();
6507
7025
  this.#sizeFilter.clear();
6508
7026
  this.#loadTags.clear();
6509
7027
  }