tiny-essentials 1.27.1 → 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.
Files changed (188) hide show
  1. package/README.md +1 -0
  2. package/changelog/1/28/0.md +16 -0
  3. package/changelog/1/28/1.md +23 -0
  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 -2
  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 -2
  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 -2
  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 +27 -11
  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 +10 -10
  35. package/dist/v1/basics/clock.mjs +91 -54
  36. package/dist/v1/basics/deprecated/html.cjs +246 -0
  37. package/dist/v1/basics/deprecated/html.d.mts +63 -0
  38. package/dist/v1/basics/deprecated/html.mjs +190 -0
  39. package/dist/v1/basics/extendObjType/Buffer.cjs +13 -0
  40. package/dist/v1/basics/extendObjType/Buffer.d.mts +4 -0
  41. package/dist/v1/basics/extendObjType/Buffer.mjs +8 -0
  42. package/dist/v1/basics/html.cjs +149 -130
  43. package/dist/v1/basics/html.d.mts +26 -61
  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 +3 -1
  47. package/dist/v1/basics/index.mjs +3 -3
  48. package/dist/v1/basics/mediaContent.cjs +51 -9
  49. package/dist/v1/basics/mediaContent.d.mts +0 -87
  50. package/dist/v1/basics/mediaContent.mjs +40 -10
  51. package/dist/v1/basics/objChecker.cjs +7 -5
  52. package/dist/v1/basics/objChecker.d.mts +3 -2
  53. package/dist/v1/basics/objChecker.mjs +6 -6
  54. package/dist/v1/basics/objFilter.cjs +40 -18
  55. package/dist/v1/basics/objFilter.d.mts +6 -6
  56. package/dist/v1/basics/objFilter.mjs +32 -17
  57. package/dist/v1/basics/simpleMath.cjs +81 -25
  58. package/dist/v1/basics/simpleMath.d.mts +2 -2
  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 +69 -7
  62. package/dist/v1/basics/text.mjs +62 -31
  63. package/dist/v1/index.cjs +4 -2
  64. package/dist/v1/index.d.mts +4 -2
  65. package/dist/v1/index.mjs +4 -4
  66. package/dist/v1/libs/TinyAdvancedRaffle.cjs +71 -255
  67. package/dist/v1/libs/TinyAdvancedRaffle.d.mts +6 -134
  68. package/dist/v1/libs/TinyAdvancedRaffle.mjs +69 -228
  69. package/dist/v1/libs/TinyAfterScrollWatcher.cjs +17 -1
  70. package/dist/v1/libs/TinyAfterScrollWatcher.d.mts +4 -1
  71. package/dist/v1/libs/TinyAfterScrollWatcher.mjs +15 -1
  72. package/dist/v1/libs/TinyAnalogClock.cjs +60 -0
  73. package/dist/v1/libs/TinyAnalogClock.d.mts +6 -0
  74. package/dist/v1/libs/TinyAnalogClock.mjs +57 -0
  75. package/dist/v1/libs/TinyClipboard.cjs +2 -0
  76. package/dist/v1/libs/TinyClipboard.d.mts +4 -2
  77. package/dist/v1/libs/TinyClipboard.mjs +2 -0
  78. package/dist/v1/libs/TinyColorConverter.cjs +1 -0
  79. package/dist/v1/libs/TinyColorConverter.d.mts +2 -1
  80. package/dist/v1/libs/TinyColorConverter.mjs +1 -0
  81. package/dist/v1/libs/TinyDayNightCycle.cjs +67 -42
  82. package/dist/v1/libs/TinyDayNightCycle.d.mts +2 -7
  83. package/dist/v1/libs/TinyDayNightCycle.mjs +65 -41
  84. package/dist/v1/libs/TinyDragDropDetector.cjs +25 -0
  85. package/dist/v1/libs/TinyDragDropDetector.d.mts +6 -0
  86. package/dist/v1/libs/TinyDragDropDetector.mjs +22 -0
  87. package/dist/v1/libs/TinyDragger.cjs +46 -19
  88. package/dist/v1/libs/TinyDragger.mjs +45 -18
  89. package/dist/v1/libs/TinyElementObserver.cjs +39 -0
  90. package/dist/v1/libs/TinyElementObserver.d.mts +6 -0
  91. package/dist/v1/libs/TinyElementObserver.mjs +36 -0
  92. package/dist/v1/libs/TinyGamepad.cjs +131 -1
  93. package/dist/v1/libs/TinyGamepad.mjs +129 -1
  94. package/dist/v1/libs/TinyHtml.cjs +1 -1
  95. package/dist/v1/libs/TinyHtml.mjs +2 -2
  96. package/dist/v1/libs/TinyI18.cjs +61 -0
  97. package/dist/v1/libs/TinyI18.d.mts +14 -0
  98. package/dist/v1/libs/TinyI18.mjs +55 -0
  99. package/dist/v1/libs/TinyIframeEvents.cjs +26 -196
  100. package/dist/v1/libs/TinyIframeEvents.d.mts +3 -122
  101. package/dist/v1/libs/TinyIframeEvents.mjs +26 -171
  102. package/dist/v1/libs/TinyLocalStorage.cjs +53 -205
  103. package/dist/v1/libs/TinyLocalStorage.d.mts +6 -127
  104. package/dist/v1/libs/TinyLocalStorage.mjs +50 -178
  105. package/dist/v1/libs/TinyMediaPlayer.cjs +74 -2
  106. package/dist/v1/libs/TinyMediaPlayer.d.mts +12 -2
  107. package/dist/v1/libs/TinyMediaPlayer.mjs +68 -2
  108. package/dist/v1/libs/TinyNewWinEvents.cjs +39 -197
  109. package/dist/v1/libs/TinyNewWinEvents.d.mts +6 -119
  110. package/dist/v1/libs/TinyNewWinEvents.mjs +36 -172
  111. package/dist/v1/libs/TinyNotifyCenter.cjs +36 -0
  112. package/dist/v1/libs/TinyNotifyCenter.d.mts +6 -0
  113. package/dist/v1/libs/TinyNotifyCenter.mjs +32 -0
  114. package/dist/v1/libs/TinyRadioFm.cjs +40 -3
  115. package/dist/v1/libs/TinyRadioFm.d.mts +3 -3
  116. package/dist/v1/libs/TinyRadioFm.mjs +37 -3
  117. package/dist/v1/libs/TinyRateLimiter.cjs +52 -0
  118. package/dist/v1/libs/TinyRateLimiter.d.mts +6 -0
  119. package/dist/v1/libs/TinyRateLimiter.mjs +48 -0
  120. package/dist/v1/libs/TinySmartScroller.cjs +56 -205
  121. package/dist/v1/libs/TinySmartScroller.d.mts +19 -152
  122. package/dist/v1/libs/TinySmartScroller.mjs +55 -181
  123. package/dist/v1/libs/TinyTextDiffer.cjs +19 -18
  124. package/dist/v1/libs/TinyTextDiffer.d.mts +1 -0
  125. package/dist/v1/libs/TinyTextDiffer.mjs +16 -17
  126. package/dist/v1/libs/TinyTextarea.cjs +19 -0
  127. package/dist/v1/libs/TinyTextarea.d.mts +6 -0
  128. package/dist/v1/libs/TinyTextarea.mjs +17 -0
  129. package/dist/v1/libs/TinyTimeout.cjs +11 -1
  130. package/dist/v1/libs/TinyTimeout.mjs +9 -1
  131. package/dist/v1/libs/TinyToastNotify.cjs +35 -0
  132. package/dist/v1/libs/TinyToastNotify.d.mts +6 -0
  133. package/dist/v1/libs/TinyToastNotify.mjs +31 -0
  134. package/dist/v1/libs/TinyUploadClicker.cjs +20 -0
  135. package/dist/v1/libs/TinyUploadClicker.d.mts +6 -0
  136. package/dist/v1/libs/TinyUploadClicker.mjs +17 -0
  137. package/dist/v1/libs/UltraRandomMsgGen.cjs +148 -35
  138. package/dist/v1/libs/UltraRandomMsgGen.d.mts +17 -3
  139. package/dist/v1/libs/UltraRandomMsgGen.mjs +133 -34
  140. package/dist/v1/libs/utils.cjs +21 -0
  141. package/dist/v1/libs/utils.d.mts +2 -0
  142. package/dist/v1/libs/utils.mjs +16 -0
  143. package/docs/v1/Exports.md +0 -1
  144. package/docs/v1/README.md +1 -1
  145. package/docs/v1/basics/array.md +2 -2
  146. package/docs/v1/basics/deprecated/html.md +17 -0
  147. package/docs/v1/basics/fullScreen.md +1 -1
  148. package/docs/v1/basics/html.md +12 -26
  149. package/docs/v1/basics/mediaContent.md +1 -1
  150. package/docs/v1/basics/objChecker.md +1 -1
  151. package/docs/v1/basics/objFilter.md +1 -1
  152. package/docs/v1/basics/text.md +2 -2
  153. package/docs/v1/fileManager/main.md +1 -1
  154. package/docs/v1/libs/ColorSafeStringify.md +1 -1
  155. package/docs/v1/libs/TinyAfterScrollWatcher.md +1 -1
  156. package/docs/v1/libs/TinyAnalogClock.md +1 -1
  157. package/docs/v1/libs/TinyArrayComparator.md +1 -1
  158. package/docs/v1/libs/TinyArrayPaginator.md +1 -1
  159. package/docs/v1/libs/TinyClassManager/TinyPluginInliner.md +2 -2
  160. package/docs/v1/libs/TinyClassManager.md +1 -1
  161. package/docs/v1/libs/TinyClipboard.md +1 -1
  162. package/docs/v1/libs/TinyCookieConsent.md +1 -1
  163. package/docs/v1/libs/TinyDomReadyManager.md +1 -1
  164. package/docs/v1/libs/TinyDragDropDetector.md +1 -1
  165. package/docs/v1/libs/TinyDragger.md +1 -1
  166. package/docs/v1/libs/TinyElementObserver.md +1 -1
  167. package/docs/v1/libs/TinyHtml.md +1 -1
  168. package/docs/v1/libs/TinyIframeEvents.md +10 -10
  169. package/docs/v1/libs/TinyLevelUp.md +1 -1
  170. package/docs/v1/libs/TinyLoadingScreen.md +1 -1
  171. package/docs/v1/libs/TinyLocalStorage.md +3 -3
  172. package/docs/v1/libs/TinyNewWinEvents.md +10 -11
  173. package/docs/v1/libs/TinyNotifications.md +1 -1
  174. package/docs/v1/libs/TinyPromiseQueue.md +2 -2
  175. package/docs/v1/libs/TinyTextDiffer.md +1 -1
  176. package/docs/v1/libs/TinyTextarea.md +1 -1
  177. package/package.json +15 -5
  178. package/dist/v1/TinyBasicsEs.min.js.LICENSE.txt +0 -8
  179. package/dist/v1/TinyEssentials.min.js.LICENSE.txt +0 -8
  180. package/dist/v1/TinyEvents.min.js +0 -1
  181. package/dist/v1/TinyUploadClicker.min.js.LICENSE.txt +0 -8
  182. package/dist/v1/build/TinyEvents.cjs +0 -7
  183. package/dist/v1/build/TinyEvents.d.mts +0 -3
  184. package/dist/v1/build/TinyEvents.mjs +0 -2
  185. package/dist/v1/libs/TinyEvents.cjs +0 -395
  186. package/dist/v1/libs/TinyEvents.d.mts +0 -164
  187. package/dist/v1/libs/TinyEvents.mjs +0 -360
  188. package/docs/v1/libs/TinyEvents.md +0 -187
@@ -1,4 +1,6 @@
1
- import TinyEvents from './TinyEvents.mjs';
1
+ import { EventEmitter } from 'events';
2
+ import { createCheckDestroyed } from './utils.mjs';
3
+ const checkDestroy = createCheckDestroyed('TinyNewWinEvents');
2
4
  /**
3
5
  * Stores polling intervals associated with window references.
4
6
  * Used to detect when the window is closed.
@@ -21,170 +23,7 @@ const pollClosedInterval = new WeakMap();
21
23
  *
22
24
  * @class
23
25
  */
24
- class TinyNewWinEvents {
25
- #events = new TinyEvents();
26
- /**
27
- * Enables or disables throwing an error when the maximum number of listeners is exceeded.
28
- *
29
- * @param {boolean} shouldThrow - If true, an error will be thrown when the max is exceeded.
30
- */
31
- setThrowOnMaxListeners(shouldThrow) {
32
- return this.#events.setThrowOnMaxListeners(shouldThrow);
33
- }
34
- /**
35
- * Checks whether an error will be thrown when the max listener limit is exceeded.
36
- *
37
- * @returns {boolean} True if an error will be thrown, false if only a warning is shown.
38
- */
39
- getThrowOnMaxListeners() {
40
- return this.#events.getThrowOnMaxListeners();
41
- }
42
- /////////////////////////////////////////////////////////////
43
- /**
44
- * Adds a listener to the beginning of the listeners array for the specified event.
45
- *
46
- * @param {string|string[]} event - Event name.
47
- * @param {handler} handler - The callback function.
48
- */
49
- prependListener(event, handler) {
50
- return this.#events.prependListener(event, handler);
51
- }
52
- /**
53
- * Adds a one-time listener to the beginning of the listeners array for the specified event.
54
- *
55
- * @param {string|string[]} event - Event name.
56
- * @param {handler} handler - The callback function.
57
- * @returns {handler[]} - The wrapped handler used internally.
58
- */
59
- prependListenerOnce(event, handler) {
60
- return this.#events.prependListenerOnce(event, handler);
61
- }
62
- //////////////////////////////////////////////////////////////////////
63
- /**
64
- * Adds a event listener.
65
- *
66
- * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
67
- * @param {handler} handler - Callback function to be called when event fires.
68
- */
69
- appendListener(event, handler) {
70
- return this.#events.appendListener(event, handler);
71
- }
72
- /**
73
- * Registers an event listener that runs only once, then is removed.
74
- *
75
- * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
76
- * @param {handler} handler - The callback function to run on event.
77
- * @returns {handler[]} - The wrapped version of the handler.
78
- */
79
- appendListenerOnce(event, handler) {
80
- return this.#events.appendListenerOnce(event, handler);
81
- }
82
- /**
83
- * Adds a event listener.
84
- *
85
- * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
86
- * @param {handler} handler - Callback function to be called when event fires.
87
- */
88
- on(event, handler) {
89
- return this.#events.on(event, handler);
90
- }
91
- /**
92
- * Registers an event listener that runs only once, then is removed.
93
- *
94
- * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
95
- * @param {handler} handler - The callback function to run on event.
96
- * @returns {handler[]} - The wrapped version of the handler.
97
- */
98
- once(event, handler) {
99
- return this.#events.once(event, handler);
100
- }
101
- ////////////////////////////////////////////////////////////////////
102
- /**
103
- * Removes a previously registered event listener.
104
- *
105
- * @param {string|string[]} event - The name of the event to remove the handler from.
106
- * @param {handler} handler - The specific callback function to remove.
107
- */
108
- off(event, handler) {
109
- return this.#events.off(event, handler);
110
- }
111
- /**
112
- * Removes all event listeners of a specific type from the element.
113
- *
114
- * @param {string|string[]} event - The event type to remove (e.g. 'onScrollBoundary').
115
- */
116
- offAll(event) {
117
- return this.#events.offAll(event);
118
- }
119
- /**
120
- * Removes all event listeners of all types from the element.
121
- */
122
- offAllTypes() {
123
- return this.#events.offAllTypes();
124
- }
125
- ////////////////////////////////////////////////////////////
126
- /**
127
- * Returns the number of listeners for a given event.
128
- *
129
- * @param {string} event - The name of the event.
130
- * @returns {number} Number of listeners for the event.
131
- */
132
- listenerCount(event) {
133
- return this.#events.listenerCount(event);
134
- }
135
- /**
136
- * Returns a copy of the array of listeners for the specified event.
137
- *
138
- * @param {string} event - The name of the event.
139
- * @returns {handler[]} Array of listener functions.
140
- */
141
- listeners(event) {
142
- return this.#events.listeners(event);
143
- }
144
- /**
145
- * Returns a copy of the array of listeners for the specified event.
146
- *
147
- * @param {string} event - The name of the event.
148
- * @returns {handler[]} Array of listener functions.
149
- */
150
- onceListeners(event) {
151
- return this.#events.onceListeners(event);
152
- }
153
- /**
154
- * Returns a copy of the internal listeners array for the specified event,
155
- * including wrapper functions like those used by `.once()`.
156
- * @param {string | symbol} event - The event name.
157
- * @returns {handler[]} An array of raw listener functions.
158
- */
159
- allListeners(event) {
160
- return this.#events.allListeners(event);
161
- }
162
- /**
163
- * Returns an array of event names for which there are registered listeners.
164
- *
165
- * @returns {string[]} Array of registered event names.
166
- */
167
- eventNames() {
168
- return this.#events.eventNames();
169
- }
170
- //////////////////////////////////////////////////////
171
- /**
172
- * Sets the maximum number of listeners per event before a warning is shown.
173
- *
174
- * @param {number} n - The maximum number of listeners.
175
- */
176
- setMaxListeners(n) {
177
- return this.#events.setMaxListeners(n);
178
- }
179
- /**
180
- * Gets the maximum number of listeners allowed per event.
181
- *
182
- * @returns {number} The maximum number of listeners.
183
- */
184
- getMaxListeners() {
185
- return this.#events.getMaxListeners();
186
- }
187
- ///////////////////////////////////////////////////
26
+ class TinyNewWinEvents extends EventEmitter {
188
27
  /** @type {Window|null} Reference to the opened or parent window */
189
28
  #windowRef;
190
29
  /** @type {string} Expected origin for postMessage communication */
@@ -201,11 +40,25 @@ class TinyNewWinEvents {
201
40
  #readyEventName = '__TNE_READY__';
202
41
  /** @type {string} Internal message type for routed communication */
203
42
  #routeEventName = '__TNE_ROUTE__';
43
+ /**
44
+ * Tracks whether the instance has been destroyed.
45
+ * @type {boolean}
46
+ */
47
+ #destroyed = false;
48
+ /**
49
+ * Gets the current destruction status of the instance.
50
+ *
51
+ * @returns {boolean} True if the instance is destroyed, false otherwise.
52
+ */
53
+ get destroyed() {
54
+ return this.#destroyed;
55
+ }
204
56
  /**
205
57
  * Gets the internal handshake event name.
206
58
  * @returns {string}
207
59
  */
208
60
  get readyEventName() {
61
+ checkDestroy(this.#destroyed);
209
62
  return this.#readyEventName;
210
63
  }
211
64
  /**
@@ -214,6 +67,7 @@ class TinyNewWinEvents {
214
67
  * @throws {TypeError} If the value is not a string.
215
68
  */
216
69
  set readyEventName(name) {
70
+ checkDestroy(this.#destroyed);
217
71
  if (typeof name !== 'string')
218
72
  throw new TypeError('TinyNewWinEvents: readyEventName must be a string.');
219
73
  this.#readyEventName = name;
@@ -223,6 +77,7 @@ class TinyNewWinEvents {
223
77
  * @returns {string}
224
78
  */
225
79
  get routeEventName() {
80
+ checkDestroy(this.#destroyed);
226
81
  return this.#routeEventName;
227
82
  }
228
83
  /**
@@ -231,6 +86,7 @@ class TinyNewWinEvents {
231
86
  * @throws {TypeError} If the value is not a string.
232
87
  */
233
88
  set routeEventName(name) {
89
+ checkDestroy(this.#destroyed);
234
90
  if (typeof name !== 'string')
235
91
  throw new TypeError('TinyNewWinEvents: routeEventName must be a string.');
236
92
  this.#routeEventName = name;
@@ -249,6 +105,7 @@ class TinyNewWinEvents {
249
105
  * @throws {Error} If the window reference is invalid or already being tracked.
250
106
  */
251
107
  constructor({ targetOrigin, url, name, features } = {}) {
108
+ super();
252
109
  if (typeof name === 'string' && name === '_blank')
253
110
  throw new Error('TinyNewWinEvents: The window name "_blank" is not supported. Please use a custom name to allow tracking.');
254
111
  if (typeof targetOrigin !== 'undefined' && typeof targetOrigin !== 'string')
@@ -282,6 +139,7 @@ class TinyNewWinEvents {
282
139
  * @returns {Window|null}
283
140
  */
284
141
  getWin() {
142
+ checkDestroy(this.#destroyed);
285
143
  return this.#windowRef;
286
144
  }
287
145
  /**
@@ -303,7 +161,7 @@ class TinyNewWinEvents {
303
161
  return;
304
162
  }
305
163
  if (type === this.#routeEventName)
306
- this.#events.emit(route, payload, event);
164
+ this.emit(`win:${route}`, payload, event);
307
165
  }
308
166
  /**
309
167
  * Sends all pending messages queued before handshake completion.
@@ -315,7 +173,7 @@ class TinyNewWinEvents {
315
173
  const data = this.#pendingQueue.shift();
316
174
  if (data) {
317
175
  const { route, payload } = data;
318
- this.emit(route, payload);
176
+ this.winEmit(route, payload);
319
177
  }
320
178
  }
321
179
  }
@@ -338,6 +196,7 @@ class TinyNewWinEvents {
338
196
  * @returns {void}
339
197
  */
340
198
  close() {
199
+ checkDestroy(this.#destroyed);
341
200
  if (!this.#isHost)
342
201
  throw new Error('Only host can close the window.');
343
202
  if (this.#windowRef && !this.#windowRef.closed)
@@ -353,7 +212,8 @@ class TinyNewWinEvents {
353
212
  * @throws {Error} If the instance is already destroyed.
354
213
  * @returns {void}
355
214
  */
356
- emit(route, payload) {
215
+ winEmit(route, payload) {
216
+ checkDestroy(this.#destroyed);
357
217
  if (typeof route !== 'string')
358
218
  throw new TypeError('Event name must be a string.');
359
219
  if (this.isDestroyed())
@@ -370,6 +230,7 @@ class TinyNewWinEvents {
370
230
  * @returns {boolean}
371
231
  */
372
232
  isConnected() {
233
+ checkDestroy(this.#destroyed);
373
234
  return this.#ready && this.#windowRef && !this.#windowRef.closed ? true : false;
374
235
  }
375
236
  /**
@@ -382,7 +243,7 @@ class TinyNewWinEvents {
382
243
  return;
383
244
  this.#pollClosedInterval = setInterval(() => {
384
245
  if (this.#windowRef?.closed) {
385
- this.#events.emit('WINDOW_REF_CLOSED');
246
+ this.emit('WINDOW_REF_CLOSED');
386
247
  this.destroy();
387
248
  }
388
249
  }, 500);
@@ -395,7 +256,8 @@ class TinyNewWinEvents {
395
256
  * @returns {void}
396
257
  */
397
258
  onClose(callback) {
398
- return this.#events.on('WINDOW_REF_CLOSED', callback);
259
+ checkDestroy(this.#destroyed);
260
+ this.on('WINDOW_REF_CLOSED', callback);
399
261
  }
400
262
  /**
401
263
  * Unregisters a previously registered close callback.
@@ -404,7 +266,8 @@ class TinyNewWinEvents {
404
266
  * @returns {void}
405
267
  */
406
268
  offClose(callback) {
407
- return this.#events.off('WINDOW_REF_CLOSED', callback);
269
+ checkDestroy(this.#destroyed);
270
+ this.off('WINDOW_REF_CLOSED', callback);
408
271
  }
409
272
  /**
410
273
  * Checks if the communication instance has been destroyed.
@@ -431,7 +294,8 @@ class TinyNewWinEvents {
431
294
  this.#pendingQueue = [];
432
295
  this.#ready = false;
433
296
  this.#windowRef = null;
434
- this.#events.offAllTypes();
297
+ this.removeAllListeners();
298
+ this.#destroyed = true;
435
299
  }
436
300
  }
437
301
  export default TinyNewWinEvents;
@@ -1,5 +1,9 @@
1
1
  'use strict';
2
2
 
3
+ var utils = require('./utils.cjs');
4
+
5
+ const checkDestroy = utils.createCheckDestroyed('TinyNotifyCenter');
6
+
3
7
  /**
4
8
  * Represents a single notification entry.
5
9
  *
@@ -109,6 +113,21 @@ class TinyNotifyCenter {
109
113
  document.body.insertAdjacentHTML(where, TinyNotifyCenter.getTemplate());
110
114
  }
111
115
 
116
+ /**
117
+ * Tracks whether the instance has been destroyed.
118
+ * @type {boolean}
119
+ */
120
+ #destroyed = false;
121
+
122
+ /**
123
+ * Gets the current destruction status of the instance.
124
+ *
125
+ * @returns {boolean} True if the instance is destroyed, false otherwise.
126
+ */
127
+ get destroyed() {
128
+ return this.#destroyed;
129
+ }
130
+
112
131
  /** @type {HTMLElement} */
113
132
  #center;
114
133
  /** @type {HTMLElement} */
@@ -206,6 +225,7 @@ class TinyNotifyCenter {
206
225
  * @param {boolean} value
207
226
  */
208
227
  setMarkAllAsReadOnClose(value) {
228
+ checkDestroy(this.#destroyed);
209
229
  if (typeof value !== 'boolean')
210
230
  throw new TypeError(`Expected boolean for markAllAsReadOnClose, got ${typeof value}`);
211
231
  this.#markAllAsReadOnClose = value;
@@ -216,6 +236,7 @@ class TinyNotifyCenter {
216
236
  * @param {number} ms
217
237
  */
218
238
  setRemoveDelay(ms) {
239
+ checkDestroy(this.#destroyed);
219
240
  if (typeof ms !== 'number') throw new Error(`NotificationCenter: "ms" must be an number.`);
220
241
  this.#removeDelay = ms;
221
242
  }
@@ -226,6 +247,7 @@ class TinyNotifyCenter {
226
247
  * @returns {'text' | 'html' | null}
227
248
  */
228
249
  getItemMode(index) {
250
+ checkDestroy(this.#destroyed);
229
251
  const item = this.getItem(index);
230
252
  return item ? this.#modes.get(item) : null;
231
253
  }
@@ -236,6 +258,7 @@ class TinyNotifyCenter {
236
258
  * @returns {HTMLElement}
237
259
  */
238
260
  getItem(index) {
261
+ checkDestroy(this.#destroyed);
239
262
  const element = this.#list.children.item(index);
240
263
  if (!(element instanceof HTMLElement))
241
264
  throw new Error(`NotificationCenter: "item" must be an HTMLElement. Got: ${element}`);
@@ -248,6 +271,7 @@ class TinyNotifyCenter {
248
271
  * @returns {boolean}
249
272
  */
250
273
  hasItem(index) {
274
+ checkDestroy(this.#destroyed);
251
275
  return index >= 0 && index < this.#list.children.length;
252
276
  }
253
277
 
@@ -256,6 +280,7 @@ class TinyNotifyCenter {
256
280
  * @param {number|HTMLElement} index
257
281
  */
258
282
  markAsRead(index) {
283
+ checkDestroy(this.#destroyed);
259
284
  const item = index instanceof HTMLElement ? index : this.getItem(index);
260
285
  if (item.classList.contains('unread')) {
261
286
  item.classList.remove('unread');
@@ -270,6 +295,7 @@ class TinyNotifyCenter {
270
295
  * @param {'text'|'html'} [mode='text'] - How to treat the message content.
271
296
  */
272
297
  add(message, mode = 'text') {
298
+ checkDestroy(this.#destroyed);
273
299
  const item = document.createElement('div');
274
300
  item.className = 'item unread';
275
301
 
@@ -351,6 +377,7 @@ class TinyNotifyCenter {
351
377
  * @param {number} index
352
378
  */
353
379
  remove(index) {
380
+ checkDestroy(this.#destroyed);
354
381
  const item = this.getItem(index);
355
382
  this.#removeItem(item);
356
383
  }
@@ -359,6 +386,7 @@ class TinyNotifyCenter {
359
386
  * Clear all notifications safely.
360
387
  */
361
388
  clear() {
389
+ checkDestroy(this.#destroyed);
362
390
  let needAgain = true;
363
391
  while (needAgain) {
364
392
  needAgain = false;
@@ -376,6 +404,7 @@ class TinyNotifyCenter {
376
404
  * Open the notify center.
377
405
  */
378
406
  open() {
407
+ checkDestroy(this.#destroyed);
379
408
  this.#overlay.classList.remove('hidden');
380
409
  this.#center.classList.add('open');
381
410
  }
@@ -384,6 +413,7 @@ class TinyNotifyCenter {
384
413
  * Close the notify center.
385
414
  */
386
415
  close() {
416
+ checkDestroy(this.#destroyed);
387
417
  this.#overlay.classList.add('hidden');
388
418
  this.#center.classList.remove('open');
389
419
  if (this.#markAllAsReadOnClose) {
@@ -398,6 +428,7 @@ class TinyNotifyCenter {
398
428
  * Toggle open/close state.
399
429
  */
400
430
  toggle() {
431
+ checkDestroy(this.#destroyed);
401
432
  if (this.#center.classList.contains('open')) this.close();
402
433
  else this.open();
403
434
  }
@@ -406,6 +437,7 @@ class TinyNotifyCenter {
406
437
  * Recalculate the number of notifications based on the actual DOM list.
407
438
  */
408
439
  recount() {
440
+ checkDestroy(this.#destroyed);
409
441
  const count = this.#list.querySelectorAll('.item.unread').length;
410
442
  this.#updateCount(count);
411
443
  }
@@ -427,6 +459,7 @@ class TinyNotifyCenter {
427
459
  * @returns {void}
428
460
  */
429
461
  destroy() {
462
+ if (this.#destroyed) return;
430
463
  // Remove event listeners
431
464
  this.#button?.removeEventListener('click', this.toggle);
432
465
  this.#center?.querySelector('.close')?.removeEventListener('click', this.close);
@@ -448,6 +481,9 @@ class TinyNotifyCenter {
448
481
  // this.#overlay = null;
449
482
  this.#count = 0;
450
483
  this.#modes = new WeakMap();
484
+
485
+ // Lock the instance
486
+ this.#destroyed = true;
451
487
  }
452
488
  }
453
489
 
@@ -91,6 +91,12 @@ declare class TinyNotifyCenter {
91
91
  button?: HTMLElement | undefined;
92
92
  overlay?: HTMLElement | undefined;
93
93
  });
94
+ /**
95
+ * Gets the current destruction status of the instance.
96
+ *
97
+ * @returns {boolean} True if the instance is destroyed, false otherwise.
98
+ */
99
+ get destroyed(): boolean;
94
100
  /**
95
101
  * Enable or disable automatic mark-as-read on close.
96
102
  * @param {boolean} value
@@ -1,3 +1,5 @@
1
+ import { createCheckDestroyed } from './utils.mjs';
2
+ const checkDestroy = createCheckDestroyed('TinyNotifyCenter');
1
3
  /**
2
4
  * Represents a single notification entry.
3
5
  *
@@ -104,6 +106,19 @@ class TinyNotifyCenter {
104
106
  static insertTemplate(where = 'afterbegin') {
105
107
  document.body.insertAdjacentHTML(where, TinyNotifyCenter.getTemplate());
106
108
  }
109
+ /**
110
+ * Tracks whether the instance has been destroyed.
111
+ * @type {boolean}
112
+ */
113
+ #destroyed = false;
114
+ /**
115
+ * Gets the current destruction status of the instance.
116
+ *
117
+ * @returns {boolean} True if the instance is destroyed, false otherwise.
118
+ */
119
+ get destroyed() {
120
+ return this.#destroyed;
121
+ }
107
122
  /** @type {HTMLElement} */
108
123
  #center;
109
124
  /** @type {HTMLElement} */
@@ -188,6 +203,7 @@ class TinyNotifyCenter {
188
203
  * @param {boolean} value
189
204
  */
190
205
  setMarkAllAsReadOnClose(value) {
206
+ checkDestroy(this.#destroyed);
191
207
  if (typeof value !== 'boolean')
192
208
  throw new TypeError(`Expected boolean for markAllAsReadOnClose, got ${typeof value}`);
193
209
  this.#markAllAsReadOnClose = value;
@@ -197,6 +213,7 @@ class TinyNotifyCenter {
197
213
  * @param {number} ms
198
214
  */
199
215
  setRemoveDelay(ms) {
216
+ checkDestroy(this.#destroyed);
200
217
  if (typeof ms !== 'number')
201
218
  throw new Error(`NotificationCenter: "ms" must be an number.`);
202
219
  this.#removeDelay = ms;
@@ -207,6 +224,7 @@ class TinyNotifyCenter {
207
224
  * @returns {'text' | 'html' | null}
208
225
  */
209
226
  getItemMode(index) {
227
+ checkDestroy(this.#destroyed);
210
228
  const item = this.getItem(index);
211
229
  return item ? this.#modes.get(item) : null;
212
230
  }
@@ -216,6 +234,7 @@ class TinyNotifyCenter {
216
234
  * @returns {HTMLElement}
217
235
  */
218
236
  getItem(index) {
237
+ checkDestroy(this.#destroyed);
219
238
  const element = this.#list.children.item(index);
220
239
  if (!(element instanceof HTMLElement))
221
240
  throw new Error(`NotificationCenter: "item" must be an HTMLElement. Got: ${element}`);
@@ -227,6 +246,7 @@ class TinyNotifyCenter {
227
246
  * @returns {boolean}
228
247
  */
229
248
  hasItem(index) {
249
+ checkDestroy(this.#destroyed);
230
250
  return index >= 0 && index < this.#list.children.length;
231
251
  }
232
252
  /**
@@ -234,6 +254,7 @@ class TinyNotifyCenter {
234
254
  * @param {number|HTMLElement} index
235
255
  */
236
256
  markAsRead(index) {
257
+ checkDestroy(this.#destroyed);
237
258
  const item = index instanceof HTMLElement ? index : this.getItem(index);
238
259
  if (item.classList.contains('unread')) {
239
260
  item.classList.remove('unread');
@@ -247,6 +268,7 @@ class TinyNotifyCenter {
247
268
  * @param {'text'|'html'} [mode='text'] - How to treat the message content.
248
269
  */
249
270
  add(message, mode = 'text') {
271
+ checkDestroy(this.#destroyed);
250
272
  const item = document.createElement('div');
251
273
  item.className = 'item unread';
252
274
  let titleText = null;
@@ -318,6 +340,7 @@ class TinyNotifyCenter {
318
340
  * @param {number} index
319
341
  */
320
342
  remove(index) {
343
+ checkDestroy(this.#destroyed);
321
344
  const item = this.getItem(index);
322
345
  this.#removeItem(item);
323
346
  }
@@ -325,6 +348,7 @@ class TinyNotifyCenter {
325
348
  * Clear all notifications safely.
326
349
  */
327
350
  clear() {
351
+ checkDestroy(this.#destroyed);
328
352
  let needAgain = true;
329
353
  while (needAgain) {
330
354
  needAgain = false;
@@ -341,6 +365,7 @@ class TinyNotifyCenter {
341
365
  * Open the notify center.
342
366
  */
343
367
  open() {
368
+ checkDestroy(this.#destroyed);
344
369
  this.#overlay.classList.remove('hidden');
345
370
  this.#center.classList.add('open');
346
371
  }
@@ -348,6 +373,7 @@ class TinyNotifyCenter {
348
373
  * Close the notify center.
349
374
  */
350
375
  close() {
376
+ checkDestroy(this.#destroyed);
351
377
  this.#overlay.classList.add('hidden');
352
378
  this.#center.classList.remove('open');
353
379
  if (this.#markAllAsReadOnClose) {
@@ -362,6 +388,7 @@ class TinyNotifyCenter {
362
388
  * Toggle open/close state.
363
389
  */
364
390
  toggle() {
391
+ checkDestroy(this.#destroyed);
365
392
  if (this.#center.classList.contains('open'))
366
393
  this.close();
367
394
  else
@@ -371,6 +398,7 @@ class TinyNotifyCenter {
371
398
  * Recalculate the number of notifications based on the actual DOM list.
372
399
  */
373
400
  recount() {
401
+ checkDestroy(this.#destroyed);
374
402
  const count = this.#list.querySelectorAll('.item.unread').length;
375
403
  this.#updateCount(count);
376
404
  }
@@ -390,6 +418,8 @@ class TinyNotifyCenter {
390
418
  * @returns {void}
391
419
  */
392
420
  destroy() {
421
+ if (this.#destroyed)
422
+ return;
393
423
  // Remove event listeners
394
424
  this.#button?.removeEventListener('click', this.toggle);
395
425
  this.#center?.querySelector('.close')?.removeEventListener('click', this.close);
@@ -408,6 +438,8 @@ class TinyNotifyCenter {
408
438
  // this.#overlay = null;
409
439
  this.#count = 0;
410
440
  this.#modes = new WeakMap();
441
+ // Lock the instance
442
+ this.#destroyed = true;
411
443
  }
412
444
  }
413
445
  export default TinyNotifyCenter;