tiny-essentials 1.28.0 → 1.28.2

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 (323) hide show
  1. package/changelog/1/28/1.md +23 -0
  2. package/changelog/1/28/2.md +43 -0
  3. package/dist/_/numbers.d.mts +91 -16
  4. package/dist/v1/TinyAdvancedRaffle.min.js +1 -1
  5. package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
  6. package/dist/v1/TinyAnalogClock.min.js +1 -1
  7. package/dist/v1/TinyBasicsEs.min.js +1 -1
  8. package/dist/v1/TinyDayNightCycle.min.js +1 -1
  9. package/dist/v1/TinyDragDropDetector.min.js +1 -1
  10. package/dist/v1/TinyDragger.min.js +1 -1
  11. package/dist/v1/TinyElementObserver.min.js +1 -1
  12. package/dist/v1/TinyEssentials.min.js +1 -1
  13. package/dist/v1/TinyGamepad.min.js +1 -1
  14. package/dist/v1/TinyHtml.min.js +1 -1
  15. package/dist/v1/TinyI18.min.js +1 -1
  16. package/dist/v1/TinyIframeEvents.min.js +1 -1
  17. package/dist/v1/TinyLocalStorage.min.js +1 -1
  18. package/dist/v1/TinyMediaPlayer.min.js +1 -1
  19. package/dist/v1/TinyNewWinEvents.min.js +1 -1
  20. package/dist/v1/TinyNotifyCenter.min.js +1 -1
  21. package/dist/v1/TinyRadioFm.min.js +1 -1
  22. package/dist/v1/TinyRateLimiter.min.js +1 -1
  23. package/dist/v1/TinySmartScroller.min.js +1 -1
  24. package/dist/v1/TinyTextDiffer.min.js +1 -1
  25. package/dist/v1/TinyTextarea.min.js +1 -1
  26. package/dist/v1/TinyTimeout.min.js +1 -1
  27. package/dist/v1/TinyToastNotify.min.js +1 -1
  28. package/dist/v1/TinyUploadClicker.min.js +1 -1
  29. package/dist/v1/UltraRandomMsgGen.min.js +1 -1
  30. package/dist/v1/basics/array.cjs +57 -9
  31. package/dist/v1/basics/array.d.mts +28 -12
  32. package/dist/v1/basics/array.mjs +51 -9
  33. package/dist/v1/basics/clock.cjs +94 -42
  34. package/dist/v1/basics/clock.d.mts +22 -22
  35. package/dist/v1/basics/clock.mjs +91 -54
  36. package/dist/v1/basics/collision.d.mts +245 -104
  37. package/dist/v1/basics/deprecated/html.cjs +246 -0
  38. package/dist/v1/basics/deprecated/html.d.mts +63 -0
  39. package/dist/v1/basics/deprecated/html.mjs +190 -0
  40. package/dist/v1/basics/extendObjType/Buffer.d.mts +1 -1
  41. package/dist/v1/basics/fullScreen.d.mts +47 -7
  42. package/dist/v1/basics/html.cjs +149 -130
  43. package/dist/v1/basics/html.d.mts +69 -113
  44. package/dist/v1/basics/html.mjs +113 -105
  45. package/dist/v1/basics/index.cjs +2 -0
  46. package/dist/v1/basics/index.d.mts +11 -65
  47. package/dist/v1/basics/index.mjs +3 -3
  48. package/dist/v1/basics/mediaContent.cjs +116 -32
  49. package/dist/v1/basics/mediaContent.d.mts +143 -159
  50. package/dist/v1/basics/mediaContent.mjs +105 -33
  51. package/dist/v1/basics/objChecker.cjs +7 -5
  52. package/dist/v1/basics/objChecker.d.mts +5 -4
  53. package/dist/v1/basics/objChecker.mjs +6 -6
  54. package/dist/v1/basics/objFilter.cjs +71 -14
  55. package/dist/v1/basics/objFilter.d.mts +16 -19
  56. package/dist/v1/basics/objFilter.mjs +63 -14
  57. package/dist/v1/basics/simpleMath.cjs +81 -25
  58. package/dist/v1/basics/simpleMath.d.mts +22 -22
  59. package/dist/v1/basics/simpleMath.mjs +70 -27
  60. package/dist/v1/basics/text.cjs +76 -31
  61. package/dist/v1/basics/text.d.mts +64 -14
  62. package/dist/v1/basics/text.mjs +62 -31
  63. package/dist/v1/build/ColorSafeStringify.d.mts +1 -1
  64. package/dist/v1/build/TinyAdvancedRaffle.d.mts +1 -1
  65. package/dist/v1/build/TinyAfterScrollWatcher.d.mts +1 -1
  66. package/dist/v1/build/TinyAnalogClock.d.mts +1 -1
  67. package/dist/v1/build/TinyArrayComparator.d.mts +1 -1
  68. package/dist/v1/build/TinyArrayPaginator.d.mts +1 -1
  69. package/dist/v1/build/TinyClassManager.d.mts +1 -1
  70. package/dist/v1/build/TinyClipboard.d.mts +1 -1
  71. package/dist/v1/build/TinyColorConverter.d.mts +1 -1
  72. package/dist/v1/build/TinyColorValidator.d.mts +1 -1
  73. package/dist/v1/build/TinyCookieConsent.d.mts +1 -1
  74. package/dist/v1/build/TinyDayNightCycle.d.mts +1 -1
  75. package/dist/v1/build/TinyDomReadyManager.d.mts +1 -1
  76. package/dist/v1/build/TinyDragDropDetector.d.mts +1 -1
  77. package/dist/v1/build/TinyDragger.d.mts +1 -1
  78. package/dist/v1/build/TinyElementObserver.d.mts +1 -1
  79. package/dist/v1/build/TinyGamepad.d.mts +1 -1
  80. package/dist/v1/build/TinyHtml.d.mts +1 -1
  81. package/dist/v1/build/TinyI18.d.mts +1 -1
  82. package/dist/v1/build/TinyIframeEvents.d.mts +1 -1
  83. package/dist/v1/build/TinyInventory.d.mts +1 -1
  84. package/dist/v1/build/TinyInventoryTrader.d.mts +1 -1
  85. package/dist/v1/build/TinyLevelUp.d.mts +1 -1
  86. package/dist/v1/build/TinyLoadingScreen.d.mts +1 -1
  87. package/dist/v1/build/TinyLocalStorage.d.mts +1 -1
  88. package/dist/v1/build/TinyMediaPlayer.d.mts +1 -1
  89. package/dist/v1/build/TinyNeedBar.d.mts +1 -1
  90. package/dist/v1/build/TinyNewWinEvents.d.mts +1 -1
  91. package/dist/v1/build/TinyNotifications.d.mts +1 -1
  92. package/dist/v1/build/TinyNotifyCenter.d.mts +1 -1
  93. package/dist/v1/build/TinyPromiseQueue.d.mts +1 -1
  94. package/dist/v1/build/TinyRadioFm.d.mts +1 -1
  95. package/dist/v1/build/TinyRateLimiter.d.mts +1 -1
  96. package/dist/v1/build/TinySimpleDice.d.mts +1 -1
  97. package/dist/v1/build/TinySmartScroller.d.mts +1 -1
  98. package/dist/v1/build/TinyTextDiffer.d.mts +1 -1
  99. package/dist/v1/build/TinyTextRangeEditor.d.mts +1 -1
  100. package/dist/v1/build/TinyTextarea.d.mts +1 -1
  101. package/dist/v1/build/TinyTimeout.d.mts +1 -1
  102. package/dist/v1/build/TinyToastNotify.d.mts +1 -1
  103. package/dist/v1/build/TinyUploadClicker.d.mts +1 -1
  104. package/dist/v1/build/UltraRandomMsgGen.d.mts +1 -1
  105. package/dist/v1/fileManager/asyncFuncs.d.mts +13 -13
  106. package/dist/v1/fileManager/index.d.mts +3 -29
  107. package/dist/v1/fileManager/normalFuncs.d.mts +22 -22
  108. package/dist/v1/index.cjs +4 -0
  109. package/dist/v1/index.d.mts +54 -137
  110. package/dist/v1/index.mjs +4 -3
  111. package/dist/v1/libs/ColorSafeStringify.d.mts +3 -12
  112. package/dist/v1/libs/TinyAdvancedRaffle.cjs +64 -50
  113. package/dist/v1/libs/TinyAdvancedRaffle.d.mts +64 -116
  114. package/dist/v1/libs/TinyAdvancedRaffle.mjs +62 -49
  115. package/dist/v1/libs/TinyAfterScrollWatcher.cjs +17 -1
  116. package/dist/v1/libs/TinyAfterScrollWatcher.d.mts +15 -19
  117. package/dist/v1/libs/TinyAfterScrollWatcher.mjs +15 -1
  118. package/dist/v1/libs/TinyAnalogClock.cjs +60 -0
  119. package/dist/v1/libs/TinyAnalogClock.d.mts +12 -9
  120. package/dist/v1/libs/TinyAnalogClock.mjs +57 -0
  121. package/dist/v1/libs/TinyArrayComparator.d.mts +14 -20
  122. package/dist/v1/libs/TinyArrayPaginator.d.mts +22 -26
  123. package/dist/v1/libs/TinyClassManager/TinyPluginInliner.d.mts +8 -8
  124. package/dist/v1/libs/TinyClassManager.cjs +5 -7
  125. package/dist/v1/libs/TinyClassManager.d.mts +16 -16
  126. package/dist/v1/libs/TinyClassManager.mjs +5 -6
  127. package/dist/v1/libs/TinyClipboard.cjs +2 -0
  128. package/dist/v1/libs/TinyClipboard.d.mts +12 -5
  129. package/dist/v1/libs/TinyClipboard.mjs +2 -0
  130. package/dist/v1/libs/TinyColorConverter.cjs +1 -0
  131. package/dist/v1/libs/TinyColorConverter.d.mts +10 -32
  132. package/dist/v1/libs/TinyColorConverter.mjs +1 -0
  133. package/dist/v1/libs/TinyColorValidator.d.mts +145 -184
  134. package/dist/v1/libs/TinyCookieConsent.d.mts +17 -17
  135. package/dist/v1/libs/TinyDayNightCycle.cjs +67 -42
  136. package/dist/v1/libs/TinyDayNightCycle.d.mts +87 -117
  137. package/dist/v1/libs/TinyDayNightCycle.mjs +65 -41
  138. package/dist/v1/libs/TinyDomReadyManager.d.mts +8 -16
  139. package/dist/v1/libs/TinyDragDropDetector.cjs +25 -0
  140. package/dist/v1/libs/TinyDragDropDetector.d.mts +32 -26
  141. package/dist/v1/libs/TinyDragDropDetector.mjs +22 -0
  142. package/dist/v1/libs/TinyDragger.cjs +46 -19
  143. package/dist/v1/libs/TinyDragger.d.mts +82 -81
  144. package/dist/v1/libs/TinyDragger.mjs +45 -18
  145. package/dist/v1/libs/TinyElementObserver.cjs +39 -0
  146. package/dist/v1/libs/TinyElementObserver.d.mts +28 -25
  147. package/dist/v1/libs/TinyElementObserver.mjs +36 -0
  148. package/dist/v1/libs/TinyGamepad.cjs +131 -2
  149. package/dist/v1/libs/TinyGamepad.d.mts +50 -122
  150. package/dist/v1/libs/TinyGamepad.mjs +129 -2
  151. package/dist/v1/libs/TinyHtml/TinyHtmlAnchor.cjs +2 -25
  152. package/dist/v1/libs/TinyHtml/TinyHtmlAnchor.d.mts +19 -25
  153. package/dist/v1/libs/TinyHtml/TinyHtmlAnchor.mjs +3 -27
  154. package/dist/v1/libs/TinyHtml/TinyHtmlButton.cjs +2 -1
  155. package/dist/v1/libs/TinyHtml/TinyHtmlButton.d.mts +55 -55
  156. package/dist/v1/libs/TinyHtml/TinyHtmlButton.mjs +2 -1
  157. package/dist/v1/libs/TinyHtml/TinyHtmlCanvas.d.mts +6 -6
  158. package/dist/v1/libs/TinyHtml/TinyHtmlDatalist.cjs +8 -4
  159. package/dist/v1/libs/TinyHtml/TinyHtmlDatalist.d.mts +19 -21
  160. package/dist/v1/libs/TinyHtml/TinyHtmlDatalist.mjs +7 -4
  161. package/dist/v1/libs/TinyHtml/TinyHtmlEmbed.d.mts +8 -8
  162. package/dist/v1/libs/TinyHtml/TinyHtmlForm.d.mts +18 -18
  163. package/dist/v1/libs/TinyHtml/TinyHtmlIcon.d.mts +5 -6
  164. package/dist/v1/libs/TinyHtml/TinyHtmlIframe.d.mts +19 -19
  165. package/dist/v1/libs/TinyHtml/TinyHtmlImage.cjs +0 -28
  166. package/dist/v1/libs/TinyHtml/TinyHtmlImage.d.mts +22 -28
  167. package/dist/v1/libs/TinyHtml/TinyHtmlImage.mjs +1 -27
  168. package/dist/v1/libs/TinyHtml/TinyHtmlInput.d.mts +11 -11
  169. package/dist/v1/libs/TinyHtml/TinyHtmlLink.d.mts +23 -23
  170. package/dist/v1/libs/TinyHtml/TinyHtmlMedia.d.mts +26 -26
  171. package/dist/v1/libs/TinyHtml/TinyHtmlScript.cjs +4 -30
  172. package/dist/v1/libs/TinyHtml/TinyHtmlScript.d.mts +20 -26
  173. package/dist/v1/libs/TinyHtml/TinyHtmlScript.mjs +5 -32
  174. package/dist/v1/libs/TinyHtml/TinyHtmlSelect.d.mts +19 -19
  175. package/dist/v1/libs/TinyHtml/TinyHtmlStyle.d.mts +8 -8
  176. package/dist/v1/libs/TinyHtml/TinyHtmlTemplate.d.mts +26 -28
  177. package/dist/v1/libs/TinyHtml/TinyHtmlTextarea.cjs +14 -15
  178. package/dist/v1/libs/TinyHtml/TinyHtmlTextarea.d.mts +32 -32
  179. package/dist/v1/libs/TinyHtml/TinyHtmlTextarea.mjs +15 -15
  180. package/dist/v1/libs/TinyHtml/index.d.mts +102 -45
  181. package/dist/v1/libs/TinyHtml/input/TinyHtmlColorInput.cjs +11 -9
  182. package/dist/v1/libs/TinyHtml/input/TinyHtmlColorInput.d.mts +21 -21
  183. package/dist/v1/libs/TinyHtml/input/TinyHtmlColorInput.mjs +11 -9
  184. package/dist/v1/libs/TinyHtml/input/TinyHtmlFileInput.d.mts +11 -11
  185. package/dist/v1/libs/TinyHtml/input/TinyHtmlHiddenInput.cjs +4 -4
  186. package/dist/v1/libs/TinyHtml/input/TinyHtmlHiddenInput.d.mts +17 -13
  187. package/dist/v1/libs/TinyHtml/input/TinyHtmlHiddenInput.mjs +4 -4
  188. package/dist/v1/libs/TinyHtml/input/TinyHtmlImageInput.d.mts +21 -21
  189. package/dist/v1/libs/TinyHtml/input/button/TinyHtmlButtonInput.cjs +5 -4
  190. package/dist/v1/libs/TinyHtml/input/button/TinyHtmlButtonInput.d.mts +14 -14
  191. package/dist/v1/libs/TinyHtml/input/button/TinyHtmlButtonInput.mjs +5 -4
  192. package/dist/v1/libs/TinyHtml/input/button/TinyHtmlResetInput.cjs +4 -3
  193. package/dist/v1/libs/TinyHtml/input/button/TinyHtmlResetInput.d.mts +10 -10
  194. package/dist/v1/libs/TinyHtml/input/button/TinyHtmlResetInput.mjs +4 -3
  195. package/dist/v1/libs/TinyHtml/input/button/TinyHtmlSubmitInput.cjs +4 -3
  196. package/dist/v1/libs/TinyHtml/input/button/TinyHtmlSubmitInput.d.mts +19 -19
  197. package/dist/v1/libs/TinyHtml/input/button/TinyHtmlSubmitInput.mjs +4 -3
  198. package/dist/v1/libs/TinyHtml/input/check/TinyHtmlCheckboxInput.cjs +5 -4
  199. package/dist/v1/libs/TinyHtml/input/check/TinyHtmlCheckboxInput.d.mts +11 -11
  200. package/dist/v1/libs/TinyHtml/input/check/TinyHtmlCheckboxInput.mjs +5 -4
  201. package/dist/v1/libs/TinyHtml/input/check/TinyHtmlRadioInput.cjs +4 -3
  202. package/dist/v1/libs/TinyHtml/input/check/TinyHtmlRadioInput.d.mts +15 -11
  203. package/dist/v1/libs/TinyHtml/input/check/TinyHtmlRadioInput.mjs +4 -3
  204. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlDateInput.cjs +49 -21
  205. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlDateInput.d.mts +34 -20
  206. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlDateInput.mjs +45 -20
  207. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlDateTimeInput.cjs +1 -1
  208. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlDateTimeInput.d.mts +14 -14
  209. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlDateTimeInput.mjs +1 -1
  210. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlMonthInput.cjs +1 -1
  211. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlMonthInput.d.mts +14 -14
  212. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlMonthInput.mjs +1 -1
  213. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlTimeInput.cjs +48 -25
  214. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlTimeInput.d.mts +27 -21
  215. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlTimeInput.mjs +40 -27
  216. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlWeekInput.cjs +1 -1
  217. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlWeekInput.d.mts +14 -14
  218. package/dist/v1/libs/TinyHtml/input/date/TinyHtmlWeekInput.mjs +1 -1
  219. package/dist/v1/libs/TinyHtml/input/number/TinyHtmlNumberInput.d.mts +14 -14
  220. package/dist/v1/libs/TinyHtml/input/number/TinyHtmlRangeInput.d.mts +14 -14
  221. package/dist/v1/libs/TinyHtml/input/text/TinyHtmlEmailInput.d.mts +25 -21
  222. package/dist/v1/libs/TinyHtml/input/text/TinyHtmlPasswordInput.d.mts +18 -18
  223. package/dist/v1/libs/TinyHtml/input/text/TinyHtmlSearchInput.d.mts +33 -29
  224. package/dist/v1/libs/TinyHtml/input/text/TinyHtmlTelInput.d.mts +22 -22
  225. package/dist/v1/libs/TinyHtml/input/text/TinyHtmlTextInput.d.mts +18 -18
  226. package/dist/v1/libs/TinyHtml/input/text/TinyHtmlUrlInput.d.mts +31 -27
  227. package/dist/v1/libs/TinyHtml/media/TinyHtmlAudio.d.mts +35 -11
  228. package/dist/v1/libs/TinyHtml/media/TinyHtmlObject.d.mts +10 -10
  229. package/dist/v1/libs/TinyHtml/media/TinyHtmlSource.d.mts +12 -12
  230. package/dist/v1/libs/TinyHtml/media/TinyHtmlVideo.d.mts +35 -27
  231. package/dist/v1/libs/TinyHtml.cjs +4 -5
  232. package/dist/v1/libs/TinyHtml.d.mts +1503 -1731
  233. package/dist/v1/libs/TinyHtml.mjs +5 -6
  234. package/dist/v1/libs/TinyI18.cjs +61 -0
  235. package/dist/v1/libs/TinyI18.d.mts +34 -58
  236. package/dist/v1/libs/TinyI18.mjs +55 -0
  237. package/dist/v1/libs/TinyIframeEvents.cjs +19 -2
  238. package/dist/v1/libs/TinyIframeEvents.d.mts +29 -38
  239. package/dist/v1/libs/TinyIframeEvents.mjs +19 -2
  240. package/dist/v1/libs/TinyInventory.d.mts +78 -141
  241. package/dist/v1/libs/TinyInventoryTrader.d.mts +19 -22
  242. package/dist/v1/libs/TinyLevelUp.d.mts +10 -13
  243. package/dist/v1/libs/TinyLoadingScreen.d.mts +21 -31
  244. package/dist/v1/libs/TinyLocalStorage.cjs +48 -0
  245. package/dist/v1/libs/TinyLocalStorage.d.mts +11 -30
  246. package/dist/v1/libs/TinyLocalStorage.mjs +45 -0
  247. package/dist/v1/libs/TinyMamdaniInferenceSystem.d.mts +37 -23
  248. package/dist/v1/libs/TinyMediaPlayer.cjs +77 -3
  249. package/dist/v1/libs/TinyMediaPlayer.d.mts +109 -106
  250. package/dist/v1/libs/TinyMediaPlayer.mjs +71 -3
  251. package/dist/v1/libs/TinyNeedBar.d.mts +25 -37
  252. package/dist/v1/libs/TinyNewWinEvents.cjs +29 -0
  253. package/dist/v1/libs/TinyNewWinEvents.d.mts +32 -29
  254. package/dist/v1/libs/TinyNewWinEvents.mjs +26 -0
  255. package/dist/v1/libs/TinyNotifications.d.mts +6 -6
  256. package/dist/v1/libs/TinyNotifyCenter.cjs +36 -0
  257. package/dist/v1/libs/TinyNotifyCenter.d.mts +15 -15
  258. package/dist/v1/libs/TinyNotifyCenter.mjs +32 -0
  259. package/dist/v1/libs/TinyPromiseQueue.d.mts +11 -11
  260. package/dist/v1/libs/TinyRadioFm.cjs +70 -12
  261. package/dist/v1/libs/TinyRadioFm.d.mts +45 -80
  262. package/dist/v1/libs/TinyRadioFm.mjs +64 -12
  263. package/dist/v1/libs/TinyRateLimiter.cjs +52 -0
  264. package/dist/v1/libs/TinyRateLimiter.d.mts +29 -36
  265. package/dist/v1/libs/TinyRateLimiter.mjs +48 -0
  266. package/dist/v1/libs/TinySimpleDice.d.mts +17 -36
  267. package/dist/v1/libs/TinySmartScroller.cjs +52 -3
  268. package/dist/v1/libs/TinySmartScroller.d.mts +62 -70
  269. package/dist/v1/libs/TinySmartScroller.mjs +51 -5
  270. package/dist/v1/libs/TinyTextDiffer.cjs +19 -18
  271. package/dist/v1/libs/TinyTextDiffer.d.mts +11 -13
  272. package/dist/v1/libs/TinyTextDiffer.mjs +16 -17
  273. package/dist/v1/libs/TinyTextRangeEditor.d.mts +8 -8
  274. package/dist/v1/libs/TinyTextarea.cjs +19 -0
  275. package/dist/v1/libs/TinyTextarea.d.mts +34 -28
  276. package/dist/v1/libs/TinyTextarea.mjs +17 -0
  277. package/dist/v1/libs/TinyTimeout.cjs +11 -1
  278. package/dist/v1/libs/TinyTimeout.d.mts +14 -14
  279. package/dist/v1/libs/TinyTimeout.mjs +9 -1
  280. package/dist/v1/libs/TinyToastNotify.cjs +36 -1
  281. package/dist/v1/libs/TinyToastNotify.d.mts +15 -17
  282. package/dist/v1/libs/TinyToastNotify.mjs +32 -1
  283. package/dist/v1/libs/TinyUploadClicker.cjs +19 -0
  284. package/dist/v1/libs/TinyUploadClicker.d.mts +38 -8
  285. package/dist/v1/libs/TinyUploadClicker.mjs +17 -0
  286. package/dist/v1/libs/UltraRandomMsgGen.cjs +148 -35
  287. package/dist/v1/libs/UltraRandomMsgGen.d.mts +52 -78
  288. package/dist/v1/libs/UltraRandomMsgGen.mjs +133 -34
  289. package/dist/v1/libs/utils.cjs +21 -0
  290. package/dist/v1/libs/utils.d.mts +6 -0
  291. package/dist/v1/libs/utils.mjs +16 -0
  292. package/docs/v1/README.md +1 -0
  293. package/docs/v1/basics/array.md +2 -2
  294. package/docs/v1/basics/deprecated/html.md +17 -0
  295. package/docs/v1/basics/fullScreen.md +1 -1
  296. package/docs/v1/basics/html.md +12 -26
  297. package/docs/v1/basics/mediaContent.md +1 -1
  298. package/docs/v1/basics/objChecker.md +1 -1
  299. package/docs/v1/basics/text.md +2 -2
  300. package/docs/v1/fileManager/main.md +1 -1
  301. package/docs/v1/libs/ColorSafeStringify.md +1 -1
  302. package/docs/v1/libs/TinyAfterScrollWatcher.md +1 -1
  303. package/docs/v1/libs/TinyAnalogClock.md +1 -1
  304. package/docs/v1/libs/TinyArrayComparator.md +1 -1
  305. package/docs/v1/libs/TinyArrayPaginator.md +1 -1
  306. package/docs/v1/libs/TinyClassManager/TinyPluginInliner.md +2 -2
  307. package/docs/v1/libs/TinyClassManager.md +1 -1
  308. package/docs/v1/libs/TinyClipboard.md +1 -1
  309. package/docs/v1/libs/TinyCookieConsent.md +1 -1
  310. package/docs/v1/libs/TinyDomReadyManager.md +1 -1
  311. package/docs/v1/libs/TinyDragDropDetector.md +1 -1
  312. package/docs/v1/libs/TinyDragger.md +1 -1
  313. package/docs/v1/libs/TinyElementObserver.md +1 -1
  314. package/docs/v1/libs/TinyHtml.md +1 -1
  315. package/docs/v1/libs/TinyIframeEvents.md +2 -2
  316. package/docs/v1/libs/TinyLevelUp.md +1 -1
  317. package/docs/v1/libs/TinyLoadingScreen.md +1 -1
  318. package/docs/v1/libs/TinyNewWinEvents.md +2 -2
  319. package/docs/v1/libs/TinyNotifications.md +1 -1
  320. package/docs/v1/libs/TinyPromiseQueue.md +2 -2
  321. package/docs/v1/libs/TinyTextDiffer.md +1 -1
  322. package/docs/v1/libs/TinyTextarea.md +1 -1
  323. package/package.json +11 -2
@@ -1,9 +1,12 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import { blobUrlToBase64, convertToBlobUrl, parseMediaMetadata, revokeContentUrls, } from '../basics/mediaContent.mjs';
3
+ import { createCheckDestroyed } from './utils.mjs';
4
+ const checkDestroy = createCheckDestroyed('TinyRadioFm');
3
5
  /**
6
+ * @typedef {import('../basics/mediaContent.mjs').PictureDataType} PictureDataType
4
7
  * @typedef {import('../basics/mediaContent.mjs').MediaContentBase} MediaContentBase
5
- * @typedef {import('../basics/mediaContent.mjs').MediaContentMetadata} MediaContentMetadata
6
- * @typedef {import('../basics/mediaContent.mjs').MediaContent} MediaContent
8
+ * @typedef {import('../basics/mediaContent.mjs').MediaContentMetadata<PictureDataType>} MediaContentMetadata
9
+ * @typedef {import('../basics/mediaContent.mjs').MediaContent<PictureDataType>} MediaContent
7
10
  * @typedef {import('../basics/mediaContent.mjs').IPicture} IPicture
8
11
  * @typedef {import('../basics/mediaContent.mjs').MediaNumber} MediaNumber
9
12
  * @typedef {import('../basics/mediaContent.mjs').MediaLoadingError} MediaLoadingError
@@ -147,11 +150,17 @@ class TinyRadioFm extends EventEmitter {
147
150
  throw new TypeError('unknownArtist must have an string or function.');
148
151
  TinyRadioFm.#unknownArtist = value;
149
152
  }
153
+ /** @type {boolean} */
154
+ #destroyed = false;
155
+ get destroyed() {
156
+ return this.#destroyed;
157
+ }
150
158
  /**
151
159
  * Gets the total count of all content items (music and voice) in the system.
152
160
  * @returns {number}
153
161
  */
154
162
  get size() {
163
+ checkDestroy(this.#destroyed);
155
164
  return this.#musicList.length + this.#voiceList.length;
156
165
  }
157
166
  /**
@@ -159,6 +168,7 @@ class TinyRadioFm extends EventEmitter {
159
168
  * @returns {number}
160
169
  */
161
170
  get musicSize() {
171
+ checkDestroy(this.#destroyed);
162
172
  return this.#musicList.length;
163
173
  }
164
174
  /**
@@ -166,6 +176,7 @@ class TinyRadioFm extends EventEmitter {
166
176
  * @returns {number}
167
177
  */
168
178
  get voiceSize() {
179
+ checkDestroy(this.#destroyed);
169
180
  return this.#voiceList.length;
170
181
  }
171
182
  /**
@@ -173,6 +184,7 @@ class TinyRadioFm extends EventEmitter {
173
184
  * @returns {number}
174
185
  */
175
186
  get customPosSize() {
187
+ checkDestroy(this.#destroyed);
176
188
  return this.#customPositions.length;
177
189
  }
178
190
  /**
@@ -180,6 +192,7 @@ class TinyRadioFm extends EventEmitter {
180
192
  * @returns {number}
181
193
  */
182
194
  get tasksSize() {
195
+ checkDestroy(this.#destroyed);
183
196
  return this.#scheduledTasks.length;
184
197
  }
185
198
  /**
@@ -187,6 +200,7 @@ class TinyRadioFm extends EventEmitter {
187
200
  * @returns {number}
188
201
  */
189
202
  get cycleCacheSize() {
203
+ checkDestroy(this.#destroyed);
190
204
  return this.#cycleCache.size;
191
205
  }
192
206
  /** @type {MediaContent[]} */
@@ -196,6 +210,7 @@ class TinyRadioFm extends EventEmitter {
196
210
  * @returns {MediaContent[]}
197
211
  */
198
212
  get musicList() {
213
+ checkDestroy(this.#destroyed);
199
214
  return structuredClone(this.#musicList);
200
215
  }
201
216
  /** @type {MediaContent[]} */
@@ -205,6 +220,7 @@ class TinyRadioFm extends EventEmitter {
205
220
  * @returns {MediaContent[]}
206
221
  */
207
222
  get voiceList() {
223
+ checkDestroy(this.#destroyed);
208
224
  return structuredClone(this.#voiceList);
209
225
  }
210
226
  /** @type {CustomPosition[]} */
@@ -214,6 +230,7 @@ class TinyRadioFm extends EventEmitter {
214
230
  * @returns {CustomPosition[]}
215
231
  */
216
232
  get customPositions() {
233
+ checkDestroy(this.#destroyed);
217
234
  return structuredClone(this.#customPositions);
218
235
  }
219
236
  /** @type {ScheduledTask[]} */
@@ -223,6 +240,7 @@ class TinyRadioFm extends EventEmitter {
223
240
  * @returns {ScheduledTask[]}
224
241
  */
225
242
  get scheduledTasks() {
243
+ checkDestroy(this.#destroyed);
226
244
  return structuredClone(this.#scheduledTasks);
227
245
  }
228
246
  /**
@@ -230,6 +248,7 @@ class TinyRadioFm extends EventEmitter {
230
248
  * @returns {MediaContent[]} A cloned object of the cache.
231
249
  */
232
250
  get allList() {
251
+ checkDestroy(this.#destroyed);
233
252
  return [...this.musicList, ...this.voiceList];
234
253
  }
235
254
  /** @type {number} */
@@ -239,6 +258,7 @@ class TinyRadioFm extends EventEmitter {
239
258
  * @returns {number}
240
259
  */
241
260
  get seed() {
261
+ checkDestroy(this.#destroyed);
242
262
  return this.#seed;
243
263
  }
244
264
  /**
@@ -246,6 +266,7 @@ class TinyRadioFm extends EventEmitter {
246
266
  * @param {number} seed - The new seed.
247
267
  */
248
268
  set seed(seed) {
269
+ checkDestroy(this.#destroyed);
249
270
  if (typeof seed !== 'number')
250
271
  throw new TypeError('Seed must be a number.');
251
272
  this.#seed = seed;
@@ -259,6 +280,7 @@ class TinyRadioFm extends EventEmitter {
259
280
  * @returns {number}
260
281
  */
261
282
  get anchorDate() {
283
+ checkDestroy(this.#destroyed);
262
284
  return this.#anchorDate;
263
285
  }
264
286
  /** @type {Map<number, CycleBlock>} */
@@ -280,6 +302,7 @@ class TinyRadioFm extends EventEmitter {
280
302
  * @returns {RadioConfig}
281
303
  */
282
304
  get config() {
305
+ checkDestroy(this.#destroyed);
283
306
  return structuredClone(this.#config);
284
307
  }
285
308
  /**
@@ -288,6 +311,7 @@ class TinyRadioFm extends EventEmitter {
288
311
  * @throws {TypeError|RangeError} If the new configuration is invalid.
289
312
  */
290
313
  set config(config) {
314
+ checkDestroy(this.#destroyed);
291
315
  // Validate the entire object before applying it
292
316
  this.#validateConfig(config);
293
317
  this.#config = structuredClone(config);
@@ -377,6 +401,7 @@ class TinyRadioFm extends EventEmitter {
377
401
  * @throws {TypeError} If the type is invalid or the data lacks a valid ID and numerical duration.
378
402
  */
379
403
  add(type, data, smartQueue = true) {
404
+ checkDestroy(this.#destroyed);
380
405
  if (!['music', 'voice', 'custom'].includes(type)) {
381
406
  throw new TypeError('Type must be "music", "voice", or "custom".');
382
407
  }
@@ -410,6 +435,7 @@ class TinyRadioFm extends EventEmitter {
410
435
  * @throws {TypeError} If arguments do not match the required types or action/type constraints.
411
436
  */
412
437
  scheduleTask(timestamp, action, type, payload, smartQueue = true) {
438
+ checkDestroy(this.#destroyed);
413
439
  if (typeof timestamp !== 'number' || isNaN(timestamp))
414
440
  throw new TypeError('timestamp must be a valid number.');
415
441
  if (!['add', 'remove', 'move'].includes(action))
@@ -467,6 +493,7 @@ class TinyRadioFm extends EventEmitter {
467
493
  * @throws {TypeError} If the id is not a string.
468
494
  */
469
495
  remove(id) {
496
+ checkDestroy(this.#destroyed);
470
497
  if (typeof id !== 'string')
471
498
  throw new TypeError('id must be a string.');
472
499
  // Revoke Blob URLs of items being removed to free memory
@@ -477,7 +504,7 @@ class TinyRadioFm extends EventEmitter {
477
504
  .forEach((cp) => revokeContentUrls(cp.content));
478
505
  /**
479
506
  * Filter function to match items against the provided ID.
480
- * @type {function(any): boolean}
507
+ * @type {(item: any) => boolean}
481
508
  */
482
509
  const filterFn = (item) => item.id !== id && item.content?.id !== id;
483
510
  this.#musicList = this.#musicList.filter(filterFn);
@@ -505,6 +532,7 @@ class TinyRadioFm extends EventEmitter {
505
532
  * @throws {TypeError|RangeError} If the provided values or the resulting state is invalid.
506
533
  */
507
534
  setConfig(config) {
535
+ checkDestroy(this.#destroyed);
508
536
  // First, validate the incoming partial object for basic type correctness
509
537
  this.#validateConfig(config);
510
538
  // Create the potential new state
@@ -520,6 +548,7 @@ class TinyRadioFm extends EventEmitter {
520
548
  * @returns {RadioEvent|null} The current active event, or null if empty.
521
549
  */
522
550
  getCurrentEvent() {
551
+ checkDestroy(this.#destroyed);
523
552
  const now = Date.now();
524
553
  this.#syncRealTimeState(now);
525
554
  return this.#getEventAtTime(now, now);
@@ -534,6 +563,7 @@ class TinyRadioFm extends EventEmitter {
534
563
  * @throws {RangeError} If the limit exceeds the configured queryLimit or is <= 0.
535
564
  */
536
565
  queryTimeline(targetDate, limit = 10) {
566
+ checkDestroy(this.#destroyed);
537
567
  if (typeof limit !== 'number' || isNaN(limit)) {
538
568
  throw new TypeError(`Invalid query limit value. Ensure it is a number.`);
539
569
  }
@@ -565,6 +595,7 @@ class TinyRadioFm extends EventEmitter {
565
595
  * @returns {CustomPosition[]} Shallow copy of custom positions array.
566
596
  */
567
597
  searchCustomPositions() {
598
+ checkDestroy(this.#destroyed);
568
599
  this.#syncRealTimeState(Date.now());
569
600
  return [...this.#customPositions];
570
601
  }
@@ -578,10 +609,17 @@ class TinyRadioFm extends EventEmitter {
578
609
  return Promise.all(list.map(async (item) => {
579
610
  const newItem = structuredClone(item);
580
611
  if (newItem.picture && Array.isArray(newItem.picture)) {
581
- newItem.picture = await Promise.all(newItem.picture.map(async (pic) => ({
582
- ...pic,
583
- data: await blobUrlToBase64(pic.data),
584
- })));
612
+ newItem.picture = await Promise.all(newItem.picture.map(async (pic) => {
613
+ // Only performs the asynchronous conversion if it really is a Blob URL
614
+ if (typeof pic.data === 'string' && pic.data.startsWith('blob:')) {
615
+ return {
616
+ ...pic,
617
+ data: await blobUrlToBase64(pic.data),
618
+ };
619
+ }
620
+ // If it is a normal URL, skip the process and keep it as it is
621
+ return pic;
622
+ }));
585
623
  }
586
624
  return newItem;
587
625
  }));
@@ -607,6 +645,7 @@ class TinyRadioFm extends EventEmitter {
607
645
  * @returns {Promise<string>} Stringified JSON state.
608
646
  */
609
647
  async exportState() {
648
+ checkDestroy(this.#destroyed);
610
649
  const processedMusic = await this._processListForExport(this.#musicList);
611
650
  const processedVoice = await this._processListForExport(this.#voiceList);
612
651
  const processedCustom = await Promise.all(this.#customPositions.map(async (cp) => {
@@ -641,6 +680,7 @@ class TinyRadioFm extends EventEmitter {
641
680
  * @throws {TypeError} If json is not a valid string or object.
642
681
  */
643
682
  importState(json) {
683
+ checkDestroy(this.#destroyed);
644
684
  /** @type {TinyRadioFmImport} */
645
685
  let data;
646
686
  if (typeof json === 'string') {
@@ -663,7 +703,7 @@ class TinyRadioFm extends EventEmitter {
663
703
  /**
664
704
  * Mulberry32 Pseudo-Random Number Generator.
665
705
  * @param {number} seed - The initialization seed.
666
- * @returns {function(): number} PRNG function returning a float between 0 and 1.
706
+ * @returns {() => number} PRNG function returning a float between 0 and 1.
667
707
  * @private
668
708
  */
669
709
  _prng(seed) {
@@ -1075,10 +1115,19 @@ class TinyRadioFm extends EventEmitter {
1075
1115
  return list.map((item) => {
1076
1116
  const newItem = { ...item };
1077
1117
  if (newItem.picture && Array.isArray(newItem.picture)) {
1078
- newItem.picture = newItem.picture.map((pic) => ({
1079
- ...pic,
1080
- data: convertToBlobUrl(pic.data, pic.format),
1081
- }));
1118
+ newItem.picture = newItem.picture.map((pic) => {
1119
+ // Check whether the data is compatible with the Blob structure (Base64 or Binary)
1120
+ const isBase64 = typeof pic.data === 'string' && pic.data.startsWith('data:');
1121
+ const isUint8Array = pic.data instanceof Uint8Array;
1122
+ if (isBase64 || isUint8Array) {
1123
+ return {
1124
+ ...pic,
1125
+ data: convertToBlobUrl(pic.data, pic.format),
1126
+ };
1127
+ }
1128
+ // If it is a default web URL or local file, use the URL directly
1129
+ return pic;
1130
+ });
1082
1131
  }
1083
1132
  return newItem;
1084
1133
  });
@@ -1111,6 +1160,8 @@ class TinyRadioFm extends EventEmitter {
1111
1160
  * @param {boolean} [destroyThumbs=true]
1112
1161
  */
1113
1162
  destroy(destroyThumbs = true) {
1163
+ if (this.#destroyed)
1164
+ return;
1114
1165
  if (destroyThumbs) {
1115
1166
  this.#musicList.forEach((item) => revokeContentUrls(item));
1116
1167
  this.#voiceList.forEach((item) => revokeContentUrls(item));
@@ -1131,6 +1182,7 @@ class TinyRadioFm extends EventEmitter {
1131
1182
  this.#cycleCache.clear();
1132
1183
  this.emit('destroyed', { timestamp: Date.now() });
1133
1184
  this.removeAllListeners();
1185
+ this.#destroyed = true;
1134
1186
  }
1135
1187
  }
1136
1188
  export default TinyRadioFm;
@@ -1,5 +1,9 @@
1
1
  'use strict';
2
2
 
3
+ var utils = require('./utils.cjs');
4
+
5
+ const checkDestroy = utils.createCheckDestroyed('TinyRateLimiter');
6
+
3
7
  /**
4
8
  * Callback triggered when a group's stored hit history exceeds
5
9
  * the configured memory limit.
@@ -70,6 +74,21 @@
70
74
  * and safe to use in long-running Node.js processes.
71
75
  */
72
76
  class TinyRateLimiter {
77
+ /**
78
+ * Tracks whether the instance has been destroyed.
79
+ * @type {boolean}
80
+ */
81
+ #destroyed = false;
82
+
83
+ /**
84
+ * Gets the current destruction status of the instance.
85
+ *
86
+ * @returns {boolean} True if the instance is destroyed, false otherwise.
87
+ */
88
+ get destroyed() {
89
+ return this.#destroyed;
90
+ }
91
+
73
92
  /**
74
93
  * Maximum number of timestamps stored per group.
75
94
  * When exceeded, older entries are discarded.
@@ -186,6 +205,7 @@ class TinyRateLimiter {
186
205
  * @param {OnMemoryExceeded} callback
187
206
  */
188
207
  setOnMemoryExceeded(callback) {
208
+ checkDestroy(this.#destroyed);
189
209
  if (typeof callback !== 'function') throw new Error('onMemoryExceeded must be a function');
190
210
  this.#onMemoryExceeded = callback;
191
211
  }
@@ -194,6 +214,7 @@ class TinyRateLimiter {
194
214
  * Removes the memory-exceeded callback.
195
215
  */
196
216
  clearOnMemoryExceeded() {
217
+ checkDestroy(this.#destroyed);
197
218
  this.#onMemoryExceeded = null;
198
219
  }
199
220
 
@@ -213,6 +234,7 @@ class TinyRateLimiter {
213
234
  * @param {OnGroupExpired} callback - A function that receives the expired groupId.
214
235
  */
215
236
  setOnGroupExpired(callback) {
237
+ checkDestroy(this.#destroyed);
216
238
  if (typeof callback !== 'function') throw new Error('onGroupExpired must be a function');
217
239
  this.#onGroupExpired = callback;
218
240
  }
@@ -221,6 +243,7 @@ class TinyRateLimiter {
221
243
  * Removes the group-expiration callback.
222
244
  */
223
245
  clearOnGroupExpired() {
246
+ checkDestroy(this.#destroyed);
224
247
  this.#onGroupExpired = null;
225
248
  }
226
249
 
@@ -285,6 +308,7 @@ class TinyRateLimiter {
285
308
  * @returns {boolean}
286
309
  */
287
310
  isGroupId(id) {
311
+ checkDestroy(this.#destroyed);
288
312
  const result = this.groupFlags.get(id);
289
313
  return typeof result === 'boolean' ? result : false;
290
314
  }
@@ -295,6 +319,7 @@ class TinyRateLimiter {
295
319
  * @returns {string[]}
296
320
  */
297
321
  getUsersInGroup(groupId) {
322
+ checkDestroy(this.#destroyed);
298
323
  const users = [];
299
324
  for (const [userId, assignedGroup] of this.userToGroup.entries()) {
300
325
  if (assignedGroup === groupId) {
@@ -311,6 +336,7 @@ class TinyRateLimiter {
311
336
  * @param {number} ttl
312
337
  */
313
338
  setGroupTTL(groupId, ttl) {
339
+ checkDestroy(this.#destroyed);
314
340
  if (typeof ttl !== 'number' || !Number.isFinite(ttl) || ttl <= 0)
315
341
  throw new Error('TTL must be a positive number in milliseconds');
316
342
  this.groupTTL.set(groupId, ttl);
@@ -322,6 +348,7 @@ class TinyRateLimiter {
322
348
  * @returns {number|null}
323
349
  */
324
350
  getGroupTTL(groupId) {
351
+ checkDestroy(this.#destroyed);
325
352
  return this.groupTTL.get(groupId) ?? null;
326
353
  }
327
354
 
@@ -330,6 +357,7 @@ class TinyRateLimiter {
330
357
  * @param {string} groupId
331
358
  */
332
359
  deleteGroupTTL(groupId) {
360
+ checkDestroy(this.#destroyed);
333
361
  this.groupTTL.delete(groupId);
334
362
  }
335
363
 
@@ -344,6 +372,7 @@ class TinyRateLimiter {
344
372
  * @throws {Error} If the user belongs to another group
345
373
  */
346
374
  assignToGroup(userId, groupId) {
375
+ checkDestroy(this.#destroyed);
347
376
  const existingGroup = this.userToGroup.get(userId);
348
377
  if (existingGroup && existingGroup !== groupId)
349
378
  throw new Error(`User ${userId} is already assigned to group ${existingGroup}`);
@@ -391,6 +420,7 @@ class TinyRateLimiter {
391
420
  * @returns {string}
392
421
  */
393
422
  getGroupId(userId) {
423
+ checkDestroy(this.#destroyed);
394
424
  return this.userToGroup.get(userId) || userId; // fallback: use userId as own group
395
425
  }
396
426
 
@@ -417,6 +447,7 @@ class TinyRateLimiter {
417
447
  * @param {string} userId
418
448
  */
419
449
  hit(userId) {
450
+ checkDestroy(this.#destroyed);
420
451
  const groupId = this.getGroupId(userId);
421
452
  const now = Date.now();
422
453
 
@@ -470,6 +501,7 @@ class TinyRateLimiter {
470
501
  * @returns {boolean}
471
502
  */
472
503
  isRateLimited(userId) {
504
+ checkDestroy(this.#destroyed);
473
505
  const groupId = this.getGroupId(userId);
474
506
  if (!this.groupData.has(groupId)) return false;
475
507
 
@@ -501,6 +533,7 @@ class TinyRateLimiter {
501
533
  * @param {string} groupId
502
534
  */
503
535
  resetGroup(groupId) {
536
+ checkDestroy(this.#destroyed);
504
537
  this.groupFlags.delete(groupId);
505
538
  this.groupData.delete(groupId);
506
539
  this.lastSeen.delete(groupId);
@@ -512,6 +545,7 @@ class TinyRateLimiter {
512
545
  * @param {string} userId
513
546
  */
514
547
  resetUserGroup(userId) {
548
+ checkDestroy(this.#destroyed);
515
549
  this.userToGroup.delete(userId);
516
550
  }
517
551
 
@@ -521,6 +555,7 @@ class TinyRateLimiter {
521
555
  * @param {number[]} timestamps
522
556
  */
523
557
  setData(groupId, timestamps) {
558
+ checkDestroy(this.#destroyed);
524
559
  if (!Array.isArray(timestamps)) throw new Error('timestamps must be an array of numbers.');
525
560
  for (const t of timestamps) {
526
561
  if (typeof t !== 'number' || !Number.isFinite(t)) {
@@ -538,6 +573,7 @@ class TinyRateLimiter {
538
573
  * @returns {boolean}
539
574
  */
540
575
  hasData(groupId) {
576
+ checkDestroy(this.#destroyed);
541
577
  return this.groupData.has(groupId);
542
578
  }
543
579
 
@@ -547,6 +583,7 @@ class TinyRateLimiter {
547
583
  * @returns {number[]}
548
584
  */
549
585
  getData(groupId) {
586
+ checkDestroy(this.#destroyed);
550
587
  return this.groupData.get(groupId) || [];
551
588
  }
552
589
 
@@ -555,6 +592,7 @@ class TinyRateLimiter {
555
592
  * @returns {number}
556
593
  */
557
594
  getMaxIdle() {
595
+ checkDestroy(this.#destroyed);
558
596
  if (typeof this.#maxIdle !== 'number' || !Number.isFinite(this.#maxIdle) || this.#maxIdle < 0) {
559
597
  throw new Error("'maxIdle' must be a non-negative finite number.");
560
598
  }
@@ -566,6 +604,7 @@ class TinyRateLimiter {
566
604
  * @param {number} ms
567
605
  */
568
606
  setMaxIdle(ms) {
607
+ checkDestroy(this.#destroyed);
569
608
  if (typeof ms !== 'number' || !Number.isFinite(ms) || ms < 0) {
570
609
  throw new Error("'maxIdle' must be a non-negative finite number.");
571
610
  }
@@ -599,6 +638,7 @@ class TinyRateLimiter {
599
638
  * @returns {string[]}
600
639
  */
601
640
  getActiveGroups() {
641
+ checkDestroy(this.#destroyed);
602
642
  return Array.from(this.groupData.keys());
603
643
  }
604
644
 
@@ -607,6 +647,7 @@ class TinyRateLimiter {
607
647
  * @returns {Record<string, string>}
608
648
  */
609
649
  getAllUserMappings() {
650
+ checkDestroy(this.#destroyed);
610
651
  return Object.fromEntries(this.userToGroup);
611
652
  }
612
653
 
@@ -619,6 +660,7 @@ class TinyRateLimiter {
619
660
  * @returns {number}
620
661
  */
621
662
  getInterval() {
663
+ checkDestroy(this.#destroyed);
622
664
  if (typeof this.#interval !== 'number' || !Number.isFinite(this.#interval)) {
623
665
  throw new Error("'interval' is not a valid finite number.");
624
666
  }
@@ -630,6 +672,7 @@ class TinyRateLimiter {
630
672
  * @returns {number}
631
673
  */
632
674
  getMaxHits() {
675
+ checkDestroy(this.#destroyed);
633
676
  if (typeof this.#maxHits !== 'number' || !Number.isFinite(this.#maxHits)) {
634
677
  throw new Error("'maxHits' is not a valid finite number.");
635
678
  }
@@ -642,6 +685,7 @@ class TinyRateLimiter {
642
685
  * @returns {number}
643
686
  */
644
687
  getTotalHits(groupId) {
688
+ checkDestroy(this.#destroyed);
645
689
  const history = this.groupData.get(groupId);
646
690
  return Array.isArray(history) ? history.length : 0;
647
691
  }
@@ -652,6 +696,7 @@ class TinyRateLimiter {
652
696
  * @returns {number|null}
653
697
  */
654
698
  getLastHit(groupId) {
699
+ checkDestroy(this.#destroyed);
655
700
  const history = this.groupData.get(groupId);
656
701
  return history?.length ? history[history.length - 1] : null;
657
702
  }
@@ -662,6 +707,7 @@ class TinyRateLimiter {
662
707
  * @returns {number|null}
663
708
  */
664
709
  getTimeSinceLastHit(groupId) {
710
+ checkDestroy(this.#destroyed);
665
711
  const last = this.getLastHit(groupId);
666
712
  return last !== null ? Date.now() - last : null;
667
713
  }
@@ -687,6 +733,7 @@ class TinyRateLimiter {
687
733
  * @returns {number|null}
688
734
  */
689
735
  getAverageHitSpacing(groupId) {
736
+ checkDestroy(this.#destroyed);
690
737
  return this._calculateAverageSpacing(this.groupData.get(groupId));
691
738
  }
692
739
 
@@ -701,6 +748,7 @@ class TinyRateLimiter {
701
748
  * }}
702
749
  */
703
750
  getMetrics(groupId) {
751
+ checkDestroy(this.#destroyed);
704
752
  const history = this.groupData.get(groupId);
705
753
 
706
754
  if (!Array.isArray(history) || history.length === 0) {
@@ -729,6 +777,7 @@ class TinyRateLimiter {
729
777
  * Destroy the rate limiter, stopping cleanup and clearing data
730
778
  */
731
779
  destroy() {
780
+ if (this.destroyed) return;
732
781
  if (this.#cleanupTimer) clearInterval(this.#cleanupTimer);
733
782
  this._cleanup();
734
783
  this.groupData.clear();
@@ -736,6 +785,9 @@ class TinyRateLimiter {
736
785
  this.userToGroup.clear();
737
786
  this.groupTTL.clear();
738
787
  this.groupFlags.clear();
788
+
789
+ // Lock the instance
790
+ this.#destroyed = true;
739
791
  }
740
792
  }
741
793
 
@@ -1,18 +1,4 @@
1
- export default TinyRateLimiter;
2
- /**
3
- * Callback triggered when a group's stored hit history exceeds
4
- * the configured memory limit.
5
- *
6
- * This callback is purely informational and does not block execution.
7
- */
8
1
  export type OnMemoryExceeded = (groupId: string) => void;
9
- /**
10
- * Callback triggered when a group is considered expired and removed
11
- * during the cleanup process.
12
- *
13
- * This usually happens when the group remains inactive longer than
14
- * its configured TTL or the global maxIdle value.
15
- */
16
2
  export type OnGroupExpired = (groupId: string) => void;
17
3
  /**
18
4
  * Callback triggered when a group's stored hit history exceeds
@@ -82,30 +68,13 @@ export type OnGroupExpired = (groupId: string) => void;
82
68
  * and safe to use in long-running Node.js processes.
83
69
  */
84
70
  declare class TinyRateLimiter {
71
+ #private;
85
72
  /**
86
- * Creates a new TinyRateLimiter instance.
73
+ * Gets the current destruction status of the instance.
87
74
  *
88
- * At least one of `maxHits` or `interval` must be provided.
89
- *
90
- * @param {Object} options
91
- * @param {number|null} [options.maxMemory=100000]
92
- * Maximum timestamps stored per group (memory cap).
93
- * @param {number} [options.maxHits]
94
- * Maximum number of allowed hits.
95
- * @param {number} [options.interval]
96
- * Sliding time window in milliseconds.
97
- * @param {number} [options.cleanupInterval]
98
- * Interval (ms) for automatic cleanup execution.
99
- * @param {number} [options.maxIdle=300000]
100
- * Maximum inactivity time (ms) before a group expires.
75
+ * @returns {boolean} True if the instance is destroyed, false otherwise.
101
76
  */
102
- constructor({ maxHits, interval, cleanupInterval, maxIdle, maxMemory }: {
103
- maxMemory?: number | null | undefined;
104
- maxHits?: number | undefined;
105
- interval?: number | undefined;
106
- cleanupInterval?: number | undefined;
107
- maxIdle?: number | undefined;
108
- });
77
+ get destroyed(): boolean;
109
78
  /**
110
79
  * Stores hit timestamps per group.
111
80
  *
@@ -170,6 +139,30 @@ declare class TinyRateLimiter {
170
139
  * Removes the group-expiration callback.
171
140
  */
172
141
  clearOnGroupExpired(): void;
142
+ /**
143
+ * Creates a new TinyRateLimiter instance.
144
+ *
145
+ * At least one of `maxHits` or `interval` must be provided.
146
+ *
147
+ * @param {Object} options
148
+ * @param {number|null} [options.maxMemory=100000]
149
+ * Maximum timestamps stored per group (memory cap).
150
+ * @param {number} [options.maxHits]
151
+ * Maximum number of allowed hits.
152
+ * @param {number} [options.interval]
153
+ * Sliding time window in milliseconds.
154
+ * @param {number} [options.cleanupInterval]
155
+ * Interval (ms) for automatic cleanup execution.
156
+ * @param {number} [options.maxIdle=300000]
157
+ * Maximum inactivity time (ms) before a group expires.
158
+ */
159
+ constructor({ maxHits, interval, cleanupInterval, maxIdle, maxMemory }: {
160
+ maxMemory?: number | null;
161
+ maxHits?: number;
162
+ interval?: number;
163
+ cleanupInterval?: number;
164
+ maxIdle?: number;
165
+ });
173
166
  /**
174
167
  * Check if a given ID is a groupId (not a userId)
175
168
  * @param {string} id
@@ -382,6 +375,6 @@ declare class TinyRateLimiter {
382
375
  * Destroy the rate limiter, stopping cleanup and clearing data
383
376
  */
384
377
  destroy(): void;
385
- #private;
386
378
  }
379
+ export default TinyRateLimiter;
387
380
  //# sourceMappingURL=TinyRateLimiter.d.mts.map