tiny-essentials 1.28.0 → 1.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/changelog/1/28/1.md +23 -0
  2. package/dist/v1/TinyAdvancedRaffle.min.js +1 -1
  3. package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
  4. package/dist/v1/TinyAnalogClock.min.js +1 -1
  5. package/dist/v1/TinyBasicsEs.min.js +1 -1
  6. package/dist/v1/TinyDayNightCycle.min.js +1 -1
  7. package/dist/v1/TinyDragDropDetector.min.js +1 -1
  8. package/dist/v1/TinyDragger.min.js +1 -1
  9. package/dist/v1/TinyElementObserver.min.js +1 -1
  10. package/dist/v1/TinyEssentials.min.js +1 -1
  11. package/dist/v1/TinyGamepad.min.js +1 -1
  12. package/dist/v1/TinyHtml.min.js +1 -1
  13. package/dist/v1/TinyI18.min.js +1 -1
  14. package/dist/v1/TinyIframeEvents.min.js +1 -1
  15. package/dist/v1/TinyLocalStorage.min.js +1 -1
  16. package/dist/v1/TinyMediaPlayer.min.js +1 -1
  17. package/dist/v1/TinyNewWinEvents.min.js +1 -1
  18. package/dist/v1/TinyNotifyCenter.min.js +1 -1
  19. package/dist/v1/TinyRadioFm.min.js +1 -1
  20. package/dist/v1/TinyRateLimiter.min.js +1 -1
  21. package/dist/v1/TinySmartScroller.min.js +1 -1
  22. package/dist/v1/TinyTextDiffer.min.js +1 -1
  23. package/dist/v1/TinyTextarea.min.js +1 -1
  24. package/dist/v1/TinyTimeout.min.js +1 -1
  25. package/dist/v1/TinyToastNotify.min.js +1 -1
  26. package/dist/v1/TinyUploadClicker.min.js +1 -1
  27. package/dist/v1/UltraRandomMsgGen.min.js +1 -1
  28. package/dist/v1/basics/array.cjs +57 -9
  29. package/dist/v1/basics/array.d.mts +27 -11
  30. package/dist/v1/basics/array.mjs +51 -9
  31. package/dist/v1/basics/clock.cjs +94 -42
  32. package/dist/v1/basics/clock.d.mts +10 -10
  33. package/dist/v1/basics/clock.mjs +91 -54
  34. package/dist/v1/basics/deprecated/html.cjs +246 -0
  35. package/dist/v1/basics/deprecated/html.d.mts +63 -0
  36. package/dist/v1/basics/deprecated/html.mjs +190 -0
  37. package/dist/v1/basics/html.cjs +149 -130
  38. package/dist/v1/basics/html.d.mts +26 -61
  39. package/dist/v1/basics/html.mjs +113 -105
  40. package/dist/v1/basics/index.cjs +2 -0
  41. package/dist/v1/basics/index.d.mts +3 -1
  42. package/dist/v1/basics/index.mjs +3 -3
  43. package/dist/v1/basics/mediaContent.cjs +51 -9
  44. package/dist/v1/basics/mediaContent.d.mts +0 -87
  45. package/dist/v1/basics/mediaContent.mjs +40 -10
  46. package/dist/v1/basics/objChecker.cjs +7 -5
  47. package/dist/v1/basics/objChecker.d.mts +3 -2
  48. package/dist/v1/basics/objChecker.mjs +6 -6
  49. package/dist/v1/basics/objFilter.cjs +40 -7
  50. package/dist/v1/basics/objFilter.d.mts +6 -6
  51. package/dist/v1/basics/objFilter.mjs +32 -7
  52. package/dist/v1/basics/simpleMath.cjs +81 -25
  53. package/dist/v1/basics/simpleMath.d.mts +2 -2
  54. package/dist/v1/basics/simpleMath.mjs +70 -27
  55. package/dist/v1/basics/text.cjs +76 -31
  56. package/dist/v1/basics/text.d.mts +69 -7
  57. package/dist/v1/basics/text.mjs +62 -31
  58. package/dist/v1/index.cjs +4 -0
  59. package/dist/v1/index.d.mts +4 -1
  60. package/dist/v1/index.mjs +4 -3
  61. package/dist/v1/libs/TinyAdvancedRaffle.cjs +64 -50
  62. package/dist/v1/libs/TinyAdvancedRaffle.d.mts +4 -13
  63. package/dist/v1/libs/TinyAdvancedRaffle.mjs +62 -49
  64. package/dist/v1/libs/TinyAfterScrollWatcher.cjs +17 -1
  65. package/dist/v1/libs/TinyAfterScrollWatcher.d.mts +4 -1
  66. package/dist/v1/libs/TinyAfterScrollWatcher.mjs +15 -1
  67. package/dist/v1/libs/TinyAnalogClock.cjs +60 -0
  68. package/dist/v1/libs/TinyAnalogClock.d.mts +6 -0
  69. package/dist/v1/libs/TinyAnalogClock.mjs +57 -0
  70. package/dist/v1/libs/TinyClipboard.cjs +2 -0
  71. package/dist/v1/libs/TinyClipboard.d.mts +4 -2
  72. package/dist/v1/libs/TinyClipboard.mjs +2 -0
  73. package/dist/v1/libs/TinyColorConverter.cjs +1 -0
  74. package/dist/v1/libs/TinyColorConverter.d.mts +2 -1
  75. package/dist/v1/libs/TinyColorConverter.mjs +1 -0
  76. package/dist/v1/libs/TinyDayNightCycle.cjs +67 -42
  77. package/dist/v1/libs/TinyDayNightCycle.d.mts +2 -7
  78. package/dist/v1/libs/TinyDayNightCycle.mjs +65 -41
  79. package/dist/v1/libs/TinyDragDropDetector.cjs +25 -0
  80. package/dist/v1/libs/TinyDragDropDetector.d.mts +6 -0
  81. package/dist/v1/libs/TinyDragDropDetector.mjs +22 -0
  82. package/dist/v1/libs/TinyDragger.cjs +46 -19
  83. package/dist/v1/libs/TinyDragger.mjs +45 -18
  84. package/dist/v1/libs/TinyElementObserver.cjs +39 -0
  85. package/dist/v1/libs/TinyElementObserver.d.mts +6 -0
  86. package/dist/v1/libs/TinyElementObserver.mjs +36 -0
  87. package/dist/v1/libs/TinyGamepad.cjs +131 -1
  88. package/dist/v1/libs/TinyGamepad.mjs +129 -1
  89. package/dist/v1/libs/TinyHtml.cjs +1 -1
  90. package/dist/v1/libs/TinyHtml.mjs +2 -2
  91. package/dist/v1/libs/TinyI18.cjs +61 -0
  92. package/dist/v1/libs/TinyI18.d.mts +14 -0
  93. package/dist/v1/libs/TinyI18.mjs +55 -0
  94. package/dist/v1/libs/TinyIframeEvents.cjs +18 -1
  95. package/dist/v1/libs/TinyIframeEvents.mjs +18 -1
  96. package/dist/v1/libs/TinyLocalStorage.cjs +48 -0
  97. package/dist/v1/libs/TinyLocalStorage.d.mts +6 -0
  98. package/dist/v1/libs/TinyLocalStorage.mjs +45 -0
  99. package/dist/v1/libs/TinyMediaPlayer.cjs +72 -0
  100. package/dist/v1/libs/TinyMediaPlayer.d.mts +10 -0
  101. package/dist/v1/libs/TinyMediaPlayer.mjs +66 -0
  102. package/dist/v1/libs/TinyNewWinEvents.cjs +29 -0
  103. package/dist/v1/libs/TinyNewWinEvents.d.mts +6 -0
  104. package/dist/v1/libs/TinyNewWinEvents.mjs +26 -0
  105. package/dist/v1/libs/TinyNotifyCenter.cjs +36 -0
  106. package/dist/v1/libs/TinyNotifyCenter.d.mts +6 -0
  107. package/dist/v1/libs/TinyNotifyCenter.mjs +32 -0
  108. package/dist/v1/libs/TinyRadioFm.cjs +38 -0
  109. package/dist/v1/libs/TinyRadioFm.d.mts +1 -0
  110. package/dist/v1/libs/TinyRadioFm.mjs +35 -0
  111. package/dist/v1/libs/TinyRateLimiter.cjs +52 -0
  112. package/dist/v1/libs/TinyRateLimiter.d.mts +6 -0
  113. package/dist/v1/libs/TinyRateLimiter.mjs +48 -0
  114. package/dist/v1/libs/TinySmartScroller.cjs +52 -3
  115. package/dist/v1/libs/TinySmartScroller.d.mts +17 -15
  116. package/dist/v1/libs/TinySmartScroller.mjs +51 -5
  117. package/dist/v1/libs/TinyTextDiffer.cjs +19 -18
  118. package/dist/v1/libs/TinyTextDiffer.d.mts +1 -0
  119. package/dist/v1/libs/TinyTextDiffer.mjs +16 -17
  120. package/dist/v1/libs/TinyTextarea.cjs +19 -0
  121. package/dist/v1/libs/TinyTextarea.d.mts +6 -0
  122. package/dist/v1/libs/TinyTextarea.mjs +17 -0
  123. package/dist/v1/libs/TinyTimeout.cjs +11 -1
  124. package/dist/v1/libs/TinyTimeout.mjs +9 -1
  125. package/dist/v1/libs/TinyToastNotify.cjs +35 -0
  126. package/dist/v1/libs/TinyToastNotify.d.mts +6 -0
  127. package/dist/v1/libs/TinyToastNotify.mjs +31 -0
  128. package/dist/v1/libs/TinyUploadClicker.cjs +19 -0
  129. package/dist/v1/libs/TinyUploadClicker.d.mts +6 -0
  130. package/dist/v1/libs/TinyUploadClicker.mjs +17 -0
  131. package/dist/v1/libs/UltraRandomMsgGen.cjs +148 -35
  132. package/dist/v1/libs/UltraRandomMsgGen.d.mts +17 -3
  133. package/dist/v1/libs/UltraRandomMsgGen.mjs +133 -34
  134. package/dist/v1/libs/utils.cjs +21 -0
  135. package/dist/v1/libs/utils.d.mts +2 -0
  136. package/dist/v1/libs/utils.mjs +16 -0
  137. package/docs/v1/README.md +1 -0
  138. package/docs/v1/basics/array.md +2 -2
  139. package/docs/v1/basics/deprecated/html.md +17 -0
  140. package/docs/v1/basics/fullScreen.md +1 -1
  141. package/docs/v1/basics/html.md +12 -26
  142. package/docs/v1/basics/mediaContent.md +1 -1
  143. package/docs/v1/basics/objChecker.md +1 -1
  144. package/docs/v1/basics/text.md +2 -2
  145. package/docs/v1/fileManager/main.md +1 -1
  146. package/docs/v1/libs/ColorSafeStringify.md +1 -1
  147. package/docs/v1/libs/TinyAfterScrollWatcher.md +1 -1
  148. package/docs/v1/libs/TinyAnalogClock.md +1 -1
  149. package/docs/v1/libs/TinyArrayComparator.md +1 -1
  150. package/docs/v1/libs/TinyArrayPaginator.md +1 -1
  151. package/docs/v1/libs/TinyClassManager/TinyPluginInliner.md +2 -2
  152. package/docs/v1/libs/TinyClassManager.md +1 -1
  153. package/docs/v1/libs/TinyClipboard.md +1 -1
  154. package/docs/v1/libs/TinyCookieConsent.md +1 -1
  155. package/docs/v1/libs/TinyDomReadyManager.md +1 -1
  156. package/docs/v1/libs/TinyDragDropDetector.md +1 -1
  157. package/docs/v1/libs/TinyDragger.md +1 -1
  158. package/docs/v1/libs/TinyElementObserver.md +1 -1
  159. package/docs/v1/libs/TinyHtml.md +1 -1
  160. package/docs/v1/libs/TinyIframeEvents.md +2 -2
  161. package/docs/v1/libs/TinyLevelUp.md +1 -1
  162. package/docs/v1/libs/TinyLoadingScreen.md +1 -1
  163. package/docs/v1/libs/TinyNewWinEvents.md +2 -2
  164. package/docs/v1/libs/TinyNotifications.md +1 -1
  165. package/docs/v1/libs/TinyPromiseQueue.md +2 -2
  166. package/docs/v1/libs/TinyTextDiffer.md +1 -1
  167. package/docs/v1/libs/TinyTextarea.md +1 -1
  168. package/package.json +10 -1
@@ -1,5 +1,7 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import { isJsonObject } from '../basics/objChecker.mjs';
3
+ import { createCheckDestroyed } from './utils.mjs';
4
+ const checkDestroy = createCheckDestroyed('TinyIframeEvents');
3
5
  /** @type {WeakMap<Window, TinyIframeEvents>} */
4
6
  const instances = new WeakMap();
5
7
  /**
@@ -43,21 +45,25 @@ class TinyIframeEvents extends EventEmitter {
43
45
  /** @type {Window} */
44
46
  #targetWindow;
45
47
  get targetWindow() {
48
+ checkDestroy(this.#isDestroyed);
46
49
  return this.#targetWindow;
47
50
  }
48
51
  /** @type {HTMLIFrameElement | undefined} */
49
52
  #targetIframeElement;
50
53
  get targetIframeElement() {
54
+ checkDestroy(this.#isDestroyed);
51
55
  return this.#targetIframeElement;
52
56
  }
53
57
  /** @type {string} */
54
58
  #targetOrigin;
55
59
  get targetOrigin() {
60
+ checkDestroy(this.#isDestroyed);
56
61
  return this.#targetOrigin;
57
62
  }
58
63
  /** @type {'iframe' | 'parent'} */
59
64
  #selfType;
60
65
  get selfType() {
66
+ checkDestroy(this.#isDestroyed);
61
67
  return this.#selfType;
62
68
  }
63
69
  /** @type {boolean} */
@@ -65,6 +71,7 @@ class TinyIframeEvents extends EventEmitter {
65
71
  /** @type {boolean} */
66
72
  #ready = false;
67
73
  get ready() {
74
+ checkDestroy(this.#isDestroyed);
68
75
  return this.#ready;
69
76
  }
70
77
  /**
@@ -74,6 +81,7 @@ class TinyIframeEvents extends EventEmitter {
74
81
  * @param {function(): void} handler - The callback function to execute.
75
82
  */
76
83
  onReady(handler) {
84
+ checkDestroy(this.#isDestroyed);
77
85
  if (this.#ready) {
78
86
  handler();
79
87
  }
@@ -127,6 +135,7 @@ class TinyIframeEvents extends EventEmitter {
127
135
  * @returns {string}
128
136
  */
129
137
  get secretEventName() {
138
+ checkDestroy(this.#isDestroyed);
130
139
  return this.#secretEventName;
131
140
  }
132
141
  /**
@@ -135,6 +144,7 @@ class TinyIframeEvents extends EventEmitter {
135
144
  * @throws {TypeError} If the value is not a string.
136
145
  */
137
146
  set secretEventName(name) {
147
+ checkDestroy(this.#isDestroyed);
138
148
  if (typeof name !== 'string')
139
149
  throw new TypeError('TinyIframeEvents: secretEventName must be a string.');
140
150
  this.#secretEventName = name;
@@ -144,6 +154,7 @@ class TinyIframeEvents extends EventEmitter {
144
154
  * @returns {string}
145
155
  */
146
156
  get handshakeEventName() {
157
+ checkDestroy(this.#isDestroyed);
147
158
  return this.#handshakeEventName;
148
159
  }
149
160
  /**
@@ -152,6 +163,7 @@ class TinyIframeEvents extends EventEmitter {
152
163
  * @throws {TypeError} If the value is not a string.
153
164
  */
154
165
  set handshakeEventName(name) {
166
+ checkDestroy(this.#isDestroyed);
155
167
  if (typeof name !== 'string')
156
168
  throw new TypeError('TinyIframeEvents: handshakeEventName must be a string.');
157
169
  this.#handshakeEventName = name;
@@ -161,6 +173,7 @@ class TinyIframeEvents extends EventEmitter {
161
173
  * @returns {string}
162
174
  */
163
175
  get readyEventName() {
176
+ checkDestroy(this.#isDestroyed);
164
177
  return this.#readyEventName;
165
178
  }
166
179
  /**
@@ -169,6 +182,7 @@ class TinyIframeEvents extends EventEmitter {
169
182
  * @throws {TypeError} If the value is not a string.
170
183
  */
171
184
  set readyEventName(name) {
185
+ checkDestroy(this.#isDestroyed);
172
186
  if (typeof name !== 'string')
173
187
  throw new TypeError('TinyIframeEvents: readyEventName must be a string.');
174
188
  this.#readyEventName = name;
@@ -276,6 +290,7 @@ class TinyIframeEvents extends EventEmitter {
276
290
  * @throws {Error} If instance has been destroyed.
277
291
  */
278
292
  winEmit(eventName, payload) {
293
+ checkDestroy(this.#isDestroyed);
279
294
  if (typeof eventName !== 'string')
280
295
  throw new TypeError('Event name must be a string.');
281
296
  if (this.#isDestroyed)
@@ -306,7 +321,8 @@ class TinyIframeEvents extends EventEmitter {
306
321
  * Call this when the instance is no longer needed to prevent memory leaks.
307
322
  */
308
323
  destroy() {
309
- this.#isDestroyed = true;
324
+ if (this.#isDestroyed)
325
+ return;
310
326
  this.#ready = false;
311
327
  window.removeEventListener('message', this._boundWindowMessage);
312
328
  if (this.#targetIframeElement && this.#boundSendPort) {
@@ -319,6 +335,7 @@ class TinyIframeEvents extends EventEmitter {
319
335
  this.removeAllListeners();
320
336
  this.#pendingQueue = [];
321
337
  instances.delete(this.#targetWindow);
338
+ this.#isDestroyed = true;
322
339
  }
323
340
  }
324
341
  export default TinyIframeEvents;
@@ -2,6 +2,9 @@
2
2
 
3
3
  var events = require('events');
4
4
  var objChecker = require('../basics/objChecker.cjs');
5
+ var utils = require('./utils.cjs');
6
+
7
+ const checkDestroy = utils.createCheckDestroyed('TinyLocalStorage');
5
8
 
6
9
  /** @type {Map<any, EncodeFn>} */
7
10
  const customEncoders = new Map();
@@ -216,6 +219,21 @@ class TinyLocalStorage extends events.EventEmitter {
216
219
 
217
220
  //////////////////////////////////////////////////////
218
221
 
222
+ /**
223
+ * Tracks whether the instance has been destroyed.
224
+ * @type {boolean}
225
+ */
226
+ #destroyed = false;
227
+
228
+ /**
229
+ * Gets the current destruction status of the instance.
230
+ *
231
+ * @returns {boolean} True if the instance is destroyed, false otherwise.
232
+ */
233
+ get destroyed() {
234
+ return this.#destroyed;
235
+ }
236
+
219
237
  /** @type {Storage} */
220
238
  #localStorage = window.localStorage;
221
239
 
@@ -267,6 +285,7 @@ class TinyLocalStorage extends events.EventEmitter {
267
285
  * @throws {TypeError} If `onUpgrade` is not a function.
268
286
  */
269
287
  updateStorageVersion(version, onUpgrade) {
288
+ checkDestroy(this.#destroyed);
270
289
  if (typeof this.#dbKey !== 'string')
271
290
  throw new Error(
272
291
  'TinyLocalStorage: Database key is not initialized. Set a valid dbName in the constructor.',
@@ -299,6 +318,7 @@ class TinyLocalStorage extends events.EventEmitter {
299
318
  * @returns {string|null} The database key, or null if not set.
300
319
  */
301
320
  getDbKey() {
321
+ checkDestroy(this.#destroyed);
302
322
  return this.#dbKey;
303
323
  }
304
324
 
@@ -308,6 +328,7 @@ class TinyLocalStorage extends events.EventEmitter {
308
328
  * @returns {number} The current version number.
309
329
  */
310
330
  getVersion() {
331
+ checkDestroy(this.#destroyed);
311
332
  return this.#version;
312
333
  }
313
334
 
@@ -317,6 +338,7 @@ class TinyLocalStorage extends events.EventEmitter {
317
338
  * @param {Storage} localstorage - A valid Storage object (localStorage or sessionStorage).
318
339
  */
319
340
  setLocalStorage(localstorage) {
341
+ checkDestroy(this.#destroyed);
320
342
  if (!(localstorage instanceof Storage))
321
343
  throw new TypeError('Argument must be a valid instance of Storage.');
322
344
  this.#localStorage = localstorage;
@@ -328,6 +350,7 @@ class TinyLocalStorage extends events.EventEmitter {
328
350
  * @returns {boolean} True if `localStorage` exists, false otherwise.
329
351
  */
330
352
  localStorageExists() {
353
+ checkDestroy(this.#destroyed);
331
354
  return this.#localStorage instanceof Storage;
332
355
  }
333
356
 
@@ -353,6 +376,7 @@ class TinyLocalStorage extends events.EventEmitter {
353
376
  * @param {LocalStorageJsonValue} data - The data to be serialized and stored.
354
377
  */
355
378
  setJson(name, data) {
379
+ checkDestroy(this.#destroyed);
356
380
  this.#isProtectedDbKey(name);
357
381
  if (
358
382
  !objChecker.isJsonObject(data) &&
@@ -415,6 +439,7 @@ class TinyLocalStorage extends events.EventEmitter {
415
439
  * @returns {LocalStorageJsonValue|null} The parsed object or fallback.
416
440
  */
417
441
  getJson(name, defaultData) {
442
+ checkDestroy(this.#destroyed);
418
443
  const { decoded, fallback } = this.#getJson(name, defaultData);
419
444
  if (
420
445
  decoded instanceof Map ||
@@ -432,6 +457,7 @@ class TinyLocalStorage extends events.EventEmitter {
432
457
  * @param {Date} data
433
458
  */
434
459
  setDate(name, data) {
460
+ checkDestroy(this.#destroyed);
435
461
  this.#isProtectedDbKey(name);
436
462
  if (!(data instanceof Date)) throw new TypeError('Value must be a Date.');
437
463
  const encoded = this.#setJson(name, data);
@@ -445,6 +471,7 @@ class TinyLocalStorage extends events.EventEmitter {
445
471
  * @returns {Date|null}
446
472
  */
447
473
  getDate(name) {
474
+ checkDestroy(this.#destroyed);
448
475
  const value = this.#getJson(name).decoded;
449
476
  return value instanceof Date ? value : null;
450
477
  }
@@ -455,6 +482,7 @@ class TinyLocalStorage extends events.EventEmitter {
455
482
  * @param {RegExp} data
456
483
  */
457
484
  setRegExp(name, data) {
485
+ checkDestroy(this.#destroyed);
458
486
  this.#isProtectedDbKey(name);
459
487
  if (!(data instanceof RegExp)) throw new TypeError('Value must be a RegExp.');
460
488
  const encoded = this.#setJson(name, data);
@@ -468,6 +496,7 @@ class TinyLocalStorage extends events.EventEmitter {
468
496
  * @returns {RegExp|null}
469
497
  */
470
498
  getRegExp(name) {
499
+ checkDestroy(this.#destroyed);
471
500
  const value = this.#getJson(name).decoded;
472
501
  return value instanceof RegExp ? value : null;
473
502
  }
@@ -478,6 +507,7 @@ class TinyLocalStorage extends events.EventEmitter {
478
507
  * @param {bigint} data
479
508
  */
480
509
  setBigInt(name, data) {
510
+ checkDestroy(this.#destroyed);
481
511
  this.#isProtectedDbKey(name);
482
512
  if (typeof data !== 'bigint') throw new TypeError('Value must be a BigInt.');
483
513
  const encoded = this.#setJson(name, data);
@@ -491,6 +521,7 @@ class TinyLocalStorage extends events.EventEmitter {
491
521
  * @returns {bigint|null}
492
522
  */
493
523
  getBigInt(name) {
524
+ checkDestroy(this.#destroyed);
494
525
  const value = this.#getJson(name).decoded;
495
526
  return typeof value === 'bigint' ? value : null;
496
527
  }
@@ -502,6 +533,7 @@ class TinyLocalStorage extends events.EventEmitter {
502
533
  * @param {symbol} data
503
534
  */
504
535
  setSymbol(name, data) {
536
+ checkDestroy(this.#destroyed);
505
537
  this.#isProtectedDbKey(name);
506
538
  if (typeof data !== 'symbol') throw new TypeError('Value must be a Symbol.');
507
539
  const encoded = this.#setJson(name, data);
@@ -515,6 +547,7 @@ class TinyLocalStorage extends events.EventEmitter {
515
547
  * @returns {symbol|null}
516
548
  */
517
549
  getSymbol(name) {
550
+ checkDestroy(this.#destroyed);
518
551
  const value = this.#getJson(name).decoded;
519
552
  return typeof value === 'symbol' ? value : null;
520
553
  }
@@ -526,6 +559,7 @@ class TinyLocalStorage extends events.EventEmitter {
526
559
  * @returns {any} The stored value or null if not found.
527
560
  */
528
561
  getValue(name) {
562
+ checkDestroy(this.#destroyed);
529
563
  return this.#getJson(name).decoded ?? null;
530
564
  }
531
565
 
@@ -536,6 +570,7 @@ class TinyLocalStorage extends events.EventEmitter {
536
570
  * @param {any} data - The data to store.
537
571
  */
538
572
  setItem(name, data) {
573
+ checkDestroy(this.#destroyed);
539
574
  this.#isProtectedDbKey(name);
540
575
  if (typeof name !== 'string' || !name.length)
541
576
  throw new TypeError('Key must be a non-empty string.');
@@ -550,6 +585,7 @@ class TinyLocalStorage extends events.EventEmitter {
550
585
  * @returns {string|null} The stored value or null if not found.
551
586
  */
552
587
  getItem(name) {
588
+ checkDestroy(this.#destroyed);
553
589
  if (typeof name !== 'string' || !name.length)
554
590
  throw new TypeError('Key must be a non-empty string.');
555
591
  return this.#localStorage.getItem(name);
@@ -562,6 +598,7 @@ class TinyLocalStorage extends events.EventEmitter {
562
598
  * @param {string} data - The string to store.
563
599
  */
564
600
  setString(name, data) {
601
+ checkDestroy(this.#destroyed);
565
602
  this.#isProtectedDbKey(name);
566
603
  if (typeof name !== 'string' || !name.length)
567
604
  throw new TypeError('Key must be a non-empty string.');
@@ -584,6 +621,7 @@ class TinyLocalStorage extends events.EventEmitter {
584
621
  * @returns {string|null} The string if valid, or null.
585
622
  */
586
623
  getString(name) {
624
+ checkDestroy(this.#destroyed);
587
625
  if (typeof name !== 'string' || !name.length)
588
626
  throw new TypeError('Key must be a non-empty string.');
589
627
  let value = this.#localStorage.getItem(name);
@@ -607,6 +645,7 @@ class TinyLocalStorage extends events.EventEmitter {
607
645
  * @param {number} data - The number to store.
608
646
  */
609
647
  setNumber(name, data) {
648
+ checkDestroy(this.#destroyed);
610
649
  this.#isProtectedDbKey(name);
611
650
  if (typeof name !== 'string' || !name.length)
612
651
  throw new TypeError('Key must be a non-empty string.');
@@ -622,6 +661,7 @@ class TinyLocalStorage extends events.EventEmitter {
622
661
  * @returns {number|null} The number or null if invalid.
623
662
  */
624
663
  getNumber(name) {
664
+ checkDestroy(this.#destroyed);
625
665
  if (typeof name !== 'string' || !name.length)
626
666
  throw new TypeError('Key must be a non-empty string.');
627
667
 
@@ -642,6 +682,7 @@ class TinyLocalStorage extends events.EventEmitter {
642
682
  * @param {boolean} data - The boolean value to store.
643
683
  */
644
684
  setBool(name, data) {
685
+ checkDestroy(this.#destroyed);
645
686
  this.#isProtectedDbKey(name);
646
687
  if (typeof name !== 'string' || !name.length)
647
688
  throw new TypeError('Key must be a non-empty string.');
@@ -657,6 +698,7 @@ class TinyLocalStorage extends events.EventEmitter {
657
698
  * @returns {boolean|null} The boolean or null if invalid.
658
699
  */
659
700
  getBool(name) {
701
+ checkDestroy(this.#destroyed);
660
702
  if (typeof name !== 'string' || !name.length)
661
703
  throw new TypeError('Key must be a non-empty string.');
662
704
 
@@ -676,6 +718,7 @@ class TinyLocalStorage extends events.EventEmitter {
676
718
  * @param {string} name - The key to remove.
677
719
  */
678
720
  removeItem(name) {
721
+ checkDestroy(this.#destroyed);
679
722
  if (typeof name !== 'string' || !name.length)
680
723
  throw new TypeError('Key must be a non-empty string.');
681
724
 
@@ -687,6 +730,7 @@ class TinyLocalStorage extends events.EventEmitter {
687
730
  * Clears all data from `localStorage`.
688
731
  */
689
732
  clearLocalStorage() {
733
+ checkDestroy(this.#destroyed);
690
734
  return this.#localStorage.clear();
691
735
  }
692
736
 
@@ -694,8 +738,12 @@ class TinyLocalStorage extends events.EventEmitter {
694
738
  * Destroys the storage instance by removing the storage event listener.
695
739
  */
696
740
  destroy() {
741
+ if (this.#destroyed) return;
697
742
  window.removeEventListener('storage', this.#storageEvent);
698
743
  this.removeAllListeners();
744
+
745
+ // Lock the instance
746
+ this.#destroyed = true;
699
747
  }
700
748
  }
701
749
 
@@ -137,6 +137,12 @@ declare class TinyLocalStorage extends EventEmitter<any> {
137
137
  * @param {string} [dbName] - Unique database name.
138
138
  */
139
139
  constructor(dbName?: string);
140
+ /**
141
+ * Gets the current destruction status of the instance.
142
+ *
143
+ * @returns {boolean} True if the instance is destroyed, false otherwise.
144
+ */
145
+ get destroyed(): boolean;
140
146
  /**
141
147
  * Updates the version of the storage and triggers migration if needed.
142
148
  *
@@ -1,5 +1,7 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import { isJsonObject } from '../basics/objChecker.mjs';
3
+ import { createCheckDestroyed } from './utils.mjs';
4
+ const checkDestroy = createCheckDestroyed('TinyLocalStorage');
3
5
  /** @type {Map<any, EncodeFn>} */
4
6
  const customEncoders = new Map();
5
7
  /** @type {Map<any, DecodeFn>} */
@@ -198,6 +200,19 @@ class TinyLocalStorage extends EventEmitter {
198
200
  return value;
199
201
  }
200
202
  //////////////////////////////////////////////////////
203
+ /**
204
+ * Tracks whether the instance has been destroyed.
205
+ * @type {boolean}
206
+ */
207
+ #destroyed = false;
208
+ /**
209
+ * Gets the current destruction status of the instance.
210
+ *
211
+ * @returns {boolean} True if the instance is destroyed, false otherwise.
212
+ */
213
+ get destroyed() {
214
+ return this.#destroyed;
215
+ }
201
216
  /** @type {Storage} */
202
217
  #localStorage = window.localStorage;
203
218
  /** @type {string|null} */
@@ -244,6 +259,7 @@ class TinyLocalStorage extends EventEmitter {
244
259
  * @throws {TypeError} If `onUpgrade` is not a function.
245
260
  */
246
261
  updateStorageVersion(version, onUpgrade) {
262
+ checkDestroy(this.#destroyed);
247
263
  if (typeof this.#dbKey !== 'string')
248
264
  throw new Error('TinyLocalStorage: Database key is not initialized. Set a valid dbName in the constructor.');
249
265
  if (typeof version !== 'number' || Number.isNaN(version) || version < 1)
@@ -268,6 +284,7 @@ class TinyLocalStorage extends EventEmitter {
268
284
  * @returns {string|null} The database key, or null if not set.
269
285
  */
270
286
  getDbKey() {
287
+ checkDestroy(this.#destroyed);
271
288
  return this.#dbKey;
272
289
  }
273
290
  /**
@@ -276,6 +293,7 @@ class TinyLocalStorage extends EventEmitter {
276
293
  * @returns {number} The current version number.
277
294
  */
278
295
  getVersion() {
296
+ checkDestroy(this.#destroyed);
279
297
  return this.#version;
280
298
  }
281
299
  /**
@@ -284,6 +302,7 @@ class TinyLocalStorage extends EventEmitter {
284
302
  * @param {Storage} localstorage - A valid Storage object (localStorage or sessionStorage).
285
303
  */
286
304
  setLocalStorage(localstorage) {
305
+ checkDestroy(this.#destroyed);
287
306
  if (!(localstorage instanceof Storage))
288
307
  throw new TypeError('Argument must be a valid instance of Storage.');
289
308
  this.#localStorage = localstorage;
@@ -294,6 +313,7 @@ class TinyLocalStorage extends EventEmitter {
294
313
  * @returns {boolean} True if `localStorage` exists, false otherwise.
295
314
  */
296
315
  localStorageExists() {
316
+ checkDestroy(this.#destroyed);
297
317
  return this.#localStorage instanceof Storage;
298
318
  }
299
319
  /**
@@ -317,6 +337,7 @@ class TinyLocalStorage extends EventEmitter {
317
337
  * @param {LocalStorageJsonValue} data - The data to be serialized and stored.
318
338
  */
319
339
  setJson(name, data) {
340
+ checkDestroy(this.#destroyed);
320
341
  this.#isProtectedDbKey(name);
321
342
  if (!isJsonObject(data) &&
322
343
  !Array.isArray(data) &&
@@ -371,6 +392,7 @@ class TinyLocalStorage extends EventEmitter {
371
392
  * @returns {LocalStorageJsonValue|null} The parsed object or fallback.
372
393
  */
373
394
  getJson(name, defaultData) {
395
+ checkDestroy(this.#destroyed);
374
396
  const { decoded, fallback } = this.#getJson(name, defaultData);
375
397
  if (decoded instanceof Map ||
376
398
  decoded instanceof Set ||
@@ -385,6 +407,7 @@ class TinyLocalStorage extends EventEmitter {
385
407
  * @param {Date} data
386
408
  */
387
409
  setDate(name, data) {
410
+ checkDestroy(this.#destroyed);
388
411
  this.#isProtectedDbKey(name);
389
412
  if (!(data instanceof Date))
390
413
  throw new TypeError('Value must be a Date.');
@@ -398,6 +421,7 @@ class TinyLocalStorage extends EventEmitter {
398
421
  * @returns {Date|null}
399
422
  */
400
423
  getDate(name) {
424
+ checkDestroy(this.#destroyed);
401
425
  const value = this.#getJson(name).decoded;
402
426
  return value instanceof Date ? value : null;
403
427
  }
@@ -407,6 +431,7 @@ class TinyLocalStorage extends EventEmitter {
407
431
  * @param {RegExp} data
408
432
  */
409
433
  setRegExp(name, data) {
434
+ checkDestroy(this.#destroyed);
410
435
  this.#isProtectedDbKey(name);
411
436
  if (!(data instanceof RegExp))
412
437
  throw new TypeError('Value must be a RegExp.');
@@ -420,6 +445,7 @@ class TinyLocalStorage extends EventEmitter {
420
445
  * @returns {RegExp|null}
421
446
  */
422
447
  getRegExp(name) {
448
+ checkDestroy(this.#destroyed);
423
449
  const value = this.#getJson(name).decoded;
424
450
  return value instanceof RegExp ? value : null;
425
451
  }
@@ -429,6 +455,7 @@ class TinyLocalStorage extends EventEmitter {
429
455
  * @param {bigint} data
430
456
  */
431
457
  setBigInt(name, data) {
458
+ checkDestroy(this.#destroyed);
432
459
  this.#isProtectedDbKey(name);
433
460
  if (typeof data !== 'bigint')
434
461
  throw new TypeError('Value must be a BigInt.');
@@ -442,6 +469,7 @@ class TinyLocalStorage extends EventEmitter {
442
469
  * @returns {bigint|null}
443
470
  */
444
471
  getBigInt(name) {
472
+ checkDestroy(this.#destroyed);
445
473
  const value = this.#getJson(name).decoded;
446
474
  return typeof value === 'bigint' ? value : null;
447
475
  }
@@ -452,6 +480,7 @@ class TinyLocalStorage extends EventEmitter {
452
480
  * @param {symbol} data
453
481
  */
454
482
  setSymbol(name, data) {
483
+ checkDestroy(this.#destroyed);
455
484
  this.#isProtectedDbKey(name);
456
485
  if (typeof data !== 'symbol')
457
486
  throw new TypeError('Value must be a Symbol.');
@@ -465,6 +494,7 @@ class TinyLocalStorage extends EventEmitter {
465
494
  * @returns {symbol|null}
466
495
  */
467
496
  getSymbol(name) {
497
+ checkDestroy(this.#destroyed);
468
498
  const value = this.#getJson(name).decoded;
469
499
  return typeof value === 'symbol' ? value : null;
470
500
  }
@@ -475,6 +505,7 @@ class TinyLocalStorage extends EventEmitter {
475
505
  * @returns {any} The stored value or null if not found.
476
506
  */
477
507
  getValue(name) {
508
+ checkDestroy(this.#destroyed);
478
509
  return this.#getJson(name).decoded ?? null;
479
510
  }
480
511
  /**
@@ -484,6 +515,7 @@ class TinyLocalStorage extends EventEmitter {
484
515
  * @param {any} data - The data to store.
485
516
  */
486
517
  setItem(name, data) {
518
+ checkDestroy(this.#destroyed);
487
519
  this.#isProtectedDbKey(name);
488
520
  if (typeof name !== 'string' || !name.length)
489
521
  throw new TypeError('Key must be a non-empty string.');
@@ -497,6 +529,7 @@ class TinyLocalStorage extends EventEmitter {
497
529
  * @returns {string|null} The stored value or null if not found.
498
530
  */
499
531
  getItem(name) {
532
+ checkDestroy(this.#destroyed);
500
533
  if (typeof name !== 'string' || !name.length)
501
534
  throw new TypeError('Key must be a non-empty string.');
502
535
  return this.#localStorage.getItem(name);
@@ -508,6 +541,7 @@ class TinyLocalStorage extends EventEmitter {
508
541
  * @param {string} data - The string to store.
509
542
  */
510
543
  setString(name, data) {
544
+ checkDestroy(this.#destroyed);
511
545
  this.#isProtectedDbKey(name);
512
546
  if (typeof name !== 'string' || !name.length)
513
547
  throw new TypeError('Key must be a non-empty string.');
@@ -526,6 +560,7 @@ class TinyLocalStorage extends EventEmitter {
526
560
  * @returns {string|null} The string if valid, or null.
527
561
  */
528
562
  getString(name) {
563
+ checkDestroy(this.#destroyed);
529
564
  if (typeof name !== 'string' || !name.length)
530
565
  throw new TypeError('Key must be a non-empty string.');
531
566
  let value = this.#localStorage.getItem(name);
@@ -551,6 +586,7 @@ class TinyLocalStorage extends EventEmitter {
551
586
  * @param {number} data - The number to store.
552
587
  */
553
588
  setNumber(name, data) {
589
+ checkDestroy(this.#destroyed);
554
590
  this.#isProtectedDbKey(name);
555
591
  if (typeof name !== 'string' || !name.length)
556
592
  throw new TypeError('Key must be a non-empty string.');
@@ -566,6 +602,7 @@ class TinyLocalStorage extends EventEmitter {
566
602
  * @returns {number|null} The number or null if invalid.
567
603
  */
568
604
  getNumber(name) {
605
+ checkDestroy(this.#destroyed);
569
606
  if (typeof name !== 'string' || !name.length)
570
607
  throw new TypeError('Key must be a non-empty string.');
571
608
  /** @type {number|string|null} */
@@ -586,6 +623,7 @@ class TinyLocalStorage extends EventEmitter {
586
623
  * @param {boolean} data - The boolean value to store.
587
624
  */
588
625
  setBool(name, data) {
626
+ checkDestroy(this.#destroyed);
589
627
  this.#isProtectedDbKey(name);
590
628
  if (typeof name !== 'string' || !name.length)
591
629
  throw new TypeError('Key must be a non-empty string.');
@@ -601,6 +639,7 @@ class TinyLocalStorage extends EventEmitter {
601
639
  * @returns {boolean|null} The boolean or null if invalid.
602
640
  */
603
641
  getBool(name) {
642
+ checkDestroy(this.#destroyed);
604
643
  if (typeof name !== 'string' || !name.length)
605
644
  throw new TypeError('Key must be a non-empty string.');
606
645
  const value = this.#localStorage.getItem(name);
@@ -620,6 +659,7 @@ class TinyLocalStorage extends EventEmitter {
620
659
  * @param {string} name - The key to remove.
621
660
  */
622
661
  removeItem(name) {
662
+ checkDestroy(this.#destroyed);
623
663
  if (typeof name !== 'string' || !name.length)
624
664
  throw new TypeError('Key must be a non-empty string.');
625
665
  this.emit('removeItem', name);
@@ -629,14 +669,19 @@ class TinyLocalStorage extends EventEmitter {
629
669
  * Clears all data from `localStorage`.
630
670
  */
631
671
  clearLocalStorage() {
672
+ checkDestroy(this.#destroyed);
632
673
  return this.#localStorage.clear();
633
674
  }
634
675
  /**
635
676
  * Destroys the storage instance by removing the storage event listener.
636
677
  */
637
678
  destroy() {
679
+ if (this.#destroyed)
680
+ return;
638
681
  window.removeEventListener('storage', this.#storageEvent);
639
682
  this.removeAllListeners();
683
+ // Lock the instance
684
+ this.#destroyed = true;
640
685
  }
641
686
  }
642
687
  // First registers