tiny-essentials 1.28.0 → 1.28.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog/1/28/1.md +23 -0
- package/dist/v1/TinyAdvancedRaffle.min.js +1 -1
- package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
- package/dist/v1/TinyAnalogClock.min.js +1 -1
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyDayNightCycle.min.js +1 -1
- package/dist/v1/TinyDragDropDetector.min.js +1 -1
- package/dist/v1/TinyDragger.min.js +1 -1
- package/dist/v1/TinyElementObserver.min.js +1 -1
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyGamepad.min.js +1 -1
- package/dist/v1/TinyHtml.min.js +1 -1
- package/dist/v1/TinyI18.min.js +1 -1
- package/dist/v1/TinyIframeEvents.min.js +1 -1
- package/dist/v1/TinyLocalStorage.min.js +1 -1
- package/dist/v1/TinyMediaPlayer.min.js +1 -1
- package/dist/v1/TinyNewWinEvents.min.js +1 -1
- package/dist/v1/TinyNotifyCenter.min.js +1 -1
- package/dist/v1/TinyRadioFm.min.js +1 -1
- package/dist/v1/TinyRateLimiter.min.js +1 -1
- package/dist/v1/TinySmartScroller.min.js +1 -1
- package/dist/v1/TinyTextDiffer.min.js +1 -1
- package/dist/v1/TinyTextarea.min.js +1 -1
- package/dist/v1/TinyTimeout.min.js +1 -1
- package/dist/v1/TinyToastNotify.min.js +1 -1
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/UltraRandomMsgGen.min.js +1 -1
- package/dist/v1/basics/array.cjs +57 -9
- package/dist/v1/basics/array.d.mts +27 -11
- package/dist/v1/basics/array.mjs +51 -9
- package/dist/v1/basics/clock.cjs +94 -42
- package/dist/v1/basics/clock.d.mts +10 -10
- package/dist/v1/basics/clock.mjs +91 -54
- package/dist/v1/basics/deprecated/html.cjs +246 -0
- package/dist/v1/basics/deprecated/html.d.mts +63 -0
- package/dist/v1/basics/deprecated/html.mjs +190 -0
- package/dist/v1/basics/html.cjs +149 -130
- package/dist/v1/basics/html.d.mts +26 -61
- package/dist/v1/basics/html.mjs +113 -105
- package/dist/v1/basics/index.cjs +2 -0
- package/dist/v1/basics/index.d.mts +3 -1
- package/dist/v1/basics/index.mjs +3 -3
- package/dist/v1/basics/mediaContent.cjs +51 -9
- package/dist/v1/basics/mediaContent.d.mts +0 -87
- package/dist/v1/basics/mediaContent.mjs +40 -10
- package/dist/v1/basics/objChecker.cjs +7 -5
- package/dist/v1/basics/objChecker.d.mts +3 -2
- package/dist/v1/basics/objChecker.mjs +6 -6
- package/dist/v1/basics/objFilter.cjs +40 -7
- package/dist/v1/basics/objFilter.d.mts +6 -6
- package/dist/v1/basics/objFilter.mjs +32 -7
- package/dist/v1/basics/simpleMath.cjs +81 -25
- package/dist/v1/basics/simpleMath.d.mts +2 -2
- package/dist/v1/basics/simpleMath.mjs +70 -27
- package/dist/v1/basics/text.cjs +76 -31
- package/dist/v1/basics/text.d.mts +69 -7
- package/dist/v1/basics/text.mjs +62 -31
- package/dist/v1/index.cjs +4 -0
- package/dist/v1/index.d.mts +4 -1
- package/dist/v1/index.mjs +4 -3
- package/dist/v1/libs/TinyAdvancedRaffle.cjs +64 -50
- package/dist/v1/libs/TinyAdvancedRaffle.d.mts +4 -13
- package/dist/v1/libs/TinyAdvancedRaffle.mjs +62 -49
- package/dist/v1/libs/TinyAfterScrollWatcher.cjs +17 -1
- package/dist/v1/libs/TinyAfterScrollWatcher.d.mts +4 -1
- package/dist/v1/libs/TinyAfterScrollWatcher.mjs +15 -1
- package/dist/v1/libs/TinyAnalogClock.cjs +60 -0
- package/dist/v1/libs/TinyAnalogClock.d.mts +6 -0
- package/dist/v1/libs/TinyAnalogClock.mjs +57 -0
- package/dist/v1/libs/TinyClipboard.cjs +2 -0
- package/dist/v1/libs/TinyClipboard.d.mts +4 -2
- package/dist/v1/libs/TinyClipboard.mjs +2 -0
- package/dist/v1/libs/TinyColorConverter.cjs +1 -0
- package/dist/v1/libs/TinyColorConverter.d.mts +2 -1
- package/dist/v1/libs/TinyColorConverter.mjs +1 -0
- package/dist/v1/libs/TinyDayNightCycle.cjs +67 -42
- package/dist/v1/libs/TinyDayNightCycle.d.mts +2 -7
- package/dist/v1/libs/TinyDayNightCycle.mjs +65 -41
- package/dist/v1/libs/TinyDragDropDetector.cjs +25 -0
- package/dist/v1/libs/TinyDragDropDetector.d.mts +6 -0
- package/dist/v1/libs/TinyDragDropDetector.mjs +22 -0
- package/dist/v1/libs/TinyDragger.cjs +46 -19
- package/dist/v1/libs/TinyDragger.mjs +45 -18
- package/dist/v1/libs/TinyElementObserver.cjs +39 -0
- package/dist/v1/libs/TinyElementObserver.d.mts +6 -0
- package/dist/v1/libs/TinyElementObserver.mjs +36 -0
- package/dist/v1/libs/TinyGamepad.cjs +131 -1
- package/dist/v1/libs/TinyGamepad.mjs +129 -1
- package/dist/v1/libs/TinyHtml.cjs +1 -1
- package/dist/v1/libs/TinyHtml.mjs +2 -2
- package/dist/v1/libs/TinyI18.cjs +61 -0
- package/dist/v1/libs/TinyI18.d.mts +14 -0
- package/dist/v1/libs/TinyI18.mjs +55 -0
- package/dist/v1/libs/TinyIframeEvents.cjs +18 -1
- package/dist/v1/libs/TinyIframeEvents.mjs +18 -1
- package/dist/v1/libs/TinyLocalStorage.cjs +48 -0
- package/dist/v1/libs/TinyLocalStorage.d.mts +6 -0
- package/dist/v1/libs/TinyLocalStorage.mjs +45 -0
- package/dist/v1/libs/TinyMediaPlayer.cjs +72 -0
- package/dist/v1/libs/TinyMediaPlayer.d.mts +10 -0
- package/dist/v1/libs/TinyMediaPlayer.mjs +66 -0
- package/dist/v1/libs/TinyNewWinEvents.cjs +29 -0
- package/dist/v1/libs/TinyNewWinEvents.d.mts +6 -0
- package/dist/v1/libs/TinyNewWinEvents.mjs +26 -0
- package/dist/v1/libs/TinyNotifyCenter.cjs +36 -0
- package/dist/v1/libs/TinyNotifyCenter.d.mts +6 -0
- package/dist/v1/libs/TinyNotifyCenter.mjs +32 -0
- package/dist/v1/libs/TinyRadioFm.cjs +38 -0
- package/dist/v1/libs/TinyRadioFm.d.mts +1 -0
- package/dist/v1/libs/TinyRadioFm.mjs +35 -0
- package/dist/v1/libs/TinyRateLimiter.cjs +52 -0
- package/dist/v1/libs/TinyRateLimiter.d.mts +6 -0
- package/dist/v1/libs/TinyRateLimiter.mjs +48 -0
- package/dist/v1/libs/TinySmartScroller.cjs +52 -3
- package/dist/v1/libs/TinySmartScroller.d.mts +17 -15
- package/dist/v1/libs/TinySmartScroller.mjs +51 -5
- package/dist/v1/libs/TinyTextDiffer.cjs +19 -18
- package/dist/v1/libs/TinyTextDiffer.d.mts +1 -0
- package/dist/v1/libs/TinyTextDiffer.mjs +16 -17
- package/dist/v1/libs/TinyTextarea.cjs +19 -0
- package/dist/v1/libs/TinyTextarea.d.mts +6 -0
- package/dist/v1/libs/TinyTextarea.mjs +17 -0
- package/dist/v1/libs/TinyTimeout.cjs +11 -1
- package/dist/v1/libs/TinyTimeout.mjs +9 -1
- package/dist/v1/libs/TinyToastNotify.cjs +35 -0
- package/dist/v1/libs/TinyToastNotify.d.mts +6 -0
- package/dist/v1/libs/TinyToastNotify.mjs +31 -0
- package/dist/v1/libs/TinyUploadClicker.cjs +19 -0
- package/dist/v1/libs/TinyUploadClicker.d.mts +6 -0
- package/dist/v1/libs/TinyUploadClicker.mjs +17 -0
- package/dist/v1/libs/UltraRandomMsgGen.cjs +148 -35
- package/dist/v1/libs/UltraRandomMsgGen.d.mts +17 -3
- package/dist/v1/libs/UltraRandomMsgGen.mjs +133 -34
- package/dist/v1/libs/utils.cjs +21 -0
- package/dist/v1/libs/utils.d.mts +2 -0
- package/dist/v1/libs/utils.mjs +16 -0
- package/docs/v1/README.md +1 -0
- package/docs/v1/basics/array.md +2 -2
- package/docs/v1/basics/deprecated/html.md +17 -0
- package/docs/v1/basics/fullScreen.md +1 -1
- package/docs/v1/basics/html.md +12 -26
- package/docs/v1/basics/mediaContent.md +1 -1
- package/docs/v1/basics/objChecker.md +1 -1
- package/docs/v1/basics/text.md +2 -2
- package/docs/v1/fileManager/main.md +1 -1
- package/docs/v1/libs/ColorSafeStringify.md +1 -1
- package/docs/v1/libs/TinyAfterScrollWatcher.md +1 -1
- package/docs/v1/libs/TinyAnalogClock.md +1 -1
- package/docs/v1/libs/TinyArrayComparator.md +1 -1
- package/docs/v1/libs/TinyArrayPaginator.md +1 -1
- package/docs/v1/libs/TinyClassManager/TinyPluginInliner.md +2 -2
- package/docs/v1/libs/TinyClassManager.md +1 -1
- package/docs/v1/libs/TinyClipboard.md +1 -1
- package/docs/v1/libs/TinyCookieConsent.md +1 -1
- package/docs/v1/libs/TinyDomReadyManager.md +1 -1
- package/docs/v1/libs/TinyDragDropDetector.md +1 -1
- package/docs/v1/libs/TinyDragger.md +1 -1
- package/docs/v1/libs/TinyElementObserver.md +1 -1
- package/docs/v1/libs/TinyHtml.md +1 -1
- package/docs/v1/libs/TinyIframeEvents.md +2 -2
- package/docs/v1/libs/TinyLevelUp.md +1 -1
- package/docs/v1/libs/TinyLoadingScreen.md +1 -1
- package/docs/v1/libs/TinyNewWinEvents.md +2 -2
- package/docs/v1/libs/TinyNotifications.md +1 -1
- package/docs/v1/libs/TinyPromiseQueue.md +2 -2
- package/docs/v1/libs/TinyTextDiffer.md +1 -1
- package/docs/v1/libs/TinyTextarea.md +1 -1
- package/package.json +10 -1
|
@@ -38,6 +38,12 @@ declare class TinyNewWinEvents extends EventEmitter<any> {
|
|
|
38
38
|
name?: string | undefined;
|
|
39
39
|
features?: string | undefined;
|
|
40
40
|
});
|
|
41
|
+
/**
|
|
42
|
+
* Gets the current destruction status of the instance.
|
|
43
|
+
*
|
|
44
|
+
* @returns {boolean} True if the instance is destroyed, false otherwise.
|
|
45
|
+
*/
|
|
46
|
+
get destroyed(): boolean;
|
|
41
47
|
/**
|
|
42
48
|
* Sets the internal handshake event name.
|
|
43
49
|
* @param {string} name
|
|
@@ -1,4 +1,6 @@
|
|
|
1
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.
|
|
@@ -38,11 +40,25 @@ class TinyNewWinEvents extends EventEmitter {
|
|
|
38
40
|
#readyEventName = '__TNE_READY__';
|
|
39
41
|
/** @type {string} Internal message type for routed communication */
|
|
40
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
|
+
}
|
|
41
56
|
/**
|
|
42
57
|
* Gets the internal handshake event name.
|
|
43
58
|
* @returns {string}
|
|
44
59
|
*/
|
|
45
60
|
get readyEventName() {
|
|
61
|
+
checkDestroy(this.#destroyed);
|
|
46
62
|
return this.#readyEventName;
|
|
47
63
|
}
|
|
48
64
|
/**
|
|
@@ -51,6 +67,7 @@ class TinyNewWinEvents extends EventEmitter {
|
|
|
51
67
|
* @throws {TypeError} If the value is not a string.
|
|
52
68
|
*/
|
|
53
69
|
set readyEventName(name) {
|
|
70
|
+
checkDestroy(this.#destroyed);
|
|
54
71
|
if (typeof name !== 'string')
|
|
55
72
|
throw new TypeError('TinyNewWinEvents: readyEventName must be a string.');
|
|
56
73
|
this.#readyEventName = name;
|
|
@@ -60,6 +77,7 @@ class TinyNewWinEvents extends EventEmitter {
|
|
|
60
77
|
* @returns {string}
|
|
61
78
|
*/
|
|
62
79
|
get routeEventName() {
|
|
80
|
+
checkDestroy(this.#destroyed);
|
|
63
81
|
return this.#routeEventName;
|
|
64
82
|
}
|
|
65
83
|
/**
|
|
@@ -68,6 +86,7 @@ class TinyNewWinEvents extends EventEmitter {
|
|
|
68
86
|
* @throws {TypeError} If the value is not a string.
|
|
69
87
|
*/
|
|
70
88
|
set routeEventName(name) {
|
|
89
|
+
checkDestroy(this.#destroyed);
|
|
71
90
|
if (typeof name !== 'string')
|
|
72
91
|
throw new TypeError('TinyNewWinEvents: routeEventName must be a string.');
|
|
73
92
|
this.#routeEventName = name;
|
|
@@ -120,6 +139,7 @@ class TinyNewWinEvents extends EventEmitter {
|
|
|
120
139
|
* @returns {Window|null}
|
|
121
140
|
*/
|
|
122
141
|
getWin() {
|
|
142
|
+
checkDestroy(this.#destroyed);
|
|
123
143
|
return this.#windowRef;
|
|
124
144
|
}
|
|
125
145
|
/**
|
|
@@ -176,6 +196,7 @@ class TinyNewWinEvents extends EventEmitter {
|
|
|
176
196
|
* @returns {void}
|
|
177
197
|
*/
|
|
178
198
|
close() {
|
|
199
|
+
checkDestroy(this.#destroyed);
|
|
179
200
|
if (!this.#isHost)
|
|
180
201
|
throw new Error('Only host can close the window.');
|
|
181
202
|
if (this.#windowRef && !this.#windowRef.closed)
|
|
@@ -192,6 +213,7 @@ class TinyNewWinEvents extends EventEmitter {
|
|
|
192
213
|
* @returns {void}
|
|
193
214
|
*/
|
|
194
215
|
winEmit(route, payload) {
|
|
216
|
+
checkDestroy(this.#destroyed);
|
|
195
217
|
if (typeof route !== 'string')
|
|
196
218
|
throw new TypeError('Event name must be a string.');
|
|
197
219
|
if (this.isDestroyed())
|
|
@@ -208,6 +230,7 @@ class TinyNewWinEvents extends EventEmitter {
|
|
|
208
230
|
* @returns {boolean}
|
|
209
231
|
*/
|
|
210
232
|
isConnected() {
|
|
233
|
+
checkDestroy(this.#destroyed);
|
|
211
234
|
return this.#ready && this.#windowRef && !this.#windowRef.closed ? true : false;
|
|
212
235
|
}
|
|
213
236
|
/**
|
|
@@ -233,6 +256,7 @@ class TinyNewWinEvents extends EventEmitter {
|
|
|
233
256
|
* @returns {void}
|
|
234
257
|
*/
|
|
235
258
|
onClose(callback) {
|
|
259
|
+
checkDestroy(this.#destroyed);
|
|
236
260
|
this.on('WINDOW_REF_CLOSED', callback);
|
|
237
261
|
}
|
|
238
262
|
/**
|
|
@@ -242,6 +266,7 @@ class TinyNewWinEvents extends EventEmitter {
|
|
|
242
266
|
* @returns {void}
|
|
243
267
|
*/
|
|
244
268
|
offClose(callback) {
|
|
269
|
+
checkDestroy(this.#destroyed);
|
|
245
270
|
this.off('WINDOW_REF_CLOSED', callback);
|
|
246
271
|
}
|
|
247
272
|
/**
|
|
@@ -270,6 +295,7 @@ class TinyNewWinEvents extends EventEmitter {
|
|
|
270
295
|
this.#ready = false;
|
|
271
296
|
this.#windowRef = null;
|
|
272
297
|
this.removeAllListeners();
|
|
298
|
+
this.#destroyed = true;
|
|
273
299
|
}
|
|
274
300
|
}
|
|
275
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;
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
var events = require('events');
|
|
4
4
|
var mediaContent = require('../basics/mediaContent.cjs');
|
|
5
|
+
var utils = require('./utils.cjs');
|
|
6
|
+
|
|
7
|
+
const checkDestroy = utils.createCheckDestroyed('TinyRadioFm');
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* @typedef {import('../basics/mediaContent.mjs').MediaContentBase} MediaContentBase
|
|
@@ -179,11 +182,19 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
179
182
|
TinyRadioFm.#unknownArtist = value;
|
|
180
183
|
}
|
|
181
184
|
|
|
185
|
+
/** @type {boolean} */
|
|
186
|
+
#destroyed = false;
|
|
187
|
+
|
|
188
|
+
get destroyed() {
|
|
189
|
+
return this.#destroyed;
|
|
190
|
+
}
|
|
191
|
+
|
|
182
192
|
/**
|
|
183
193
|
* Gets the total count of all content items (music and voice) in the system.
|
|
184
194
|
* @returns {number}
|
|
185
195
|
*/
|
|
186
196
|
get size() {
|
|
197
|
+
checkDestroy(this.#destroyed);
|
|
187
198
|
return this.#musicList.length + this.#voiceList.length;
|
|
188
199
|
}
|
|
189
200
|
|
|
@@ -192,6 +203,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
192
203
|
* @returns {number}
|
|
193
204
|
*/
|
|
194
205
|
get musicSize() {
|
|
206
|
+
checkDestroy(this.#destroyed);
|
|
195
207
|
return this.#musicList.length;
|
|
196
208
|
}
|
|
197
209
|
|
|
@@ -200,6 +212,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
200
212
|
* @returns {number}
|
|
201
213
|
*/
|
|
202
214
|
get voiceSize() {
|
|
215
|
+
checkDestroy(this.#destroyed);
|
|
203
216
|
return this.#voiceList.length;
|
|
204
217
|
}
|
|
205
218
|
|
|
@@ -208,6 +221,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
208
221
|
* @returns {number}
|
|
209
222
|
*/
|
|
210
223
|
get customPosSize() {
|
|
224
|
+
checkDestroy(this.#destroyed);
|
|
211
225
|
return this.#customPositions.length;
|
|
212
226
|
}
|
|
213
227
|
|
|
@@ -216,6 +230,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
216
230
|
* @returns {number}
|
|
217
231
|
*/
|
|
218
232
|
get tasksSize() {
|
|
233
|
+
checkDestroy(this.#destroyed);
|
|
219
234
|
return this.#scheduledTasks.length;
|
|
220
235
|
}
|
|
221
236
|
|
|
@@ -224,6 +239,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
224
239
|
* @returns {number}
|
|
225
240
|
*/
|
|
226
241
|
get cycleCacheSize() {
|
|
242
|
+
checkDestroy(this.#destroyed);
|
|
227
243
|
return this.#cycleCache.size;
|
|
228
244
|
}
|
|
229
245
|
|
|
@@ -234,6 +250,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
234
250
|
* @returns {MediaContent[]}
|
|
235
251
|
*/
|
|
236
252
|
get musicList() {
|
|
253
|
+
checkDestroy(this.#destroyed);
|
|
237
254
|
return structuredClone(this.#musicList);
|
|
238
255
|
}
|
|
239
256
|
|
|
@@ -244,6 +261,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
244
261
|
* @returns {MediaContent[]}
|
|
245
262
|
*/
|
|
246
263
|
get voiceList() {
|
|
264
|
+
checkDestroy(this.#destroyed);
|
|
247
265
|
return structuredClone(this.#voiceList);
|
|
248
266
|
}
|
|
249
267
|
|
|
@@ -254,6 +272,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
254
272
|
* @returns {CustomPosition[]}
|
|
255
273
|
*/
|
|
256
274
|
get customPositions() {
|
|
275
|
+
checkDestroy(this.#destroyed);
|
|
257
276
|
return structuredClone(this.#customPositions);
|
|
258
277
|
}
|
|
259
278
|
|
|
@@ -264,6 +283,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
264
283
|
* @returns {ScheduledTask[]}
|
|
265
284
|
*/
|
|
266
285
|
get scheduledTasks() {
|
|
286
|
+
checkDestroy(this.#destroyed);
|
|
267
287
|
return structuredClone(this.#scheduledTasks);
|
|
268
288
|
}
|
|
269
289
|
|
|
@@ -272,6 +292,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
272
292
|
* @returns {MediaContent[]} A cloned object of the cache.
|
|
273
293
|
*/
|
|
274
294
|
get allList() {
|
|
295
|
+
checkDestroy(this.#destroyed);
|
|
275
296
|
return [...this.musicList, ...this.voiceList];
|
|
276
297
|
}
|
|
277
298
|
|
|
@@ -282,6 +303,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
282
303
|
* @returns {number}
|
|
283
304
|
*/
|
|
284
305
|
get seed() {
|
|
306
|
+
checkDestroy(this.#destroyed);
|
|
285
307
|
return this.#seed;
|
|
286
308
|
}
|
|
287
309
|
/**
|
|
@@ -289,6 +311,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
289
311
|
* @param {number} seed - The new seed.
|
|
290
312
|
*/
|
|
291
313
|
set seed(seed) {
|
|
314
|
+
checkDestroy(this.#destroyed);
|
|
292
315
|
if (typeof seed !== 'number') throw new TypeError('Seed must be a number.');
|
|
293
316
|
this.#seed = seed;
|
|
294
317
|
this.#cycleCache.clear();
|
|
@@ -302,6 +325,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
302
325
|
* @returns {number}
|
|
303
326
|
*/
|
|
304
327
|
get anchorDate() {
|
|
328
|
+
checkDestroy(this.#destroyed);
|
|
305
329
|
return this.#anchorDate;
|
|
306
330
|
}
|
|
307
331
|
|
|
@@ -325,6 +349,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
325
349
|
* @returns {RadioConfig}
|
|
326
350
|
*/
|
|
327
351
|
get config() {
|
|
352
|
+
checkDestroy(this.#destroyed);
|
|
328
353
|
return structuredClone(this.#config);
|
|
329
354
|
}
|
|
330
355
|
/**
|
|
@@ -333,6 +358,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
333
358
|
* @throws {TypeError|RangeError} If the new configuration is invalid.
|
|
334
359
|
*/
|
|
335
360
|
set config(config) {
|
|
361
|
+
checkDestroy(this.#destroyed);
|
|
336
362
|
// Validate the entire object before applying it
|
|
337
363
|
this.#validateConfig(config);
|
|
338
364
|
|
|
@@ -455,6 +481,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
455
481
|
* @throws {TypeError} If the type is invalid or the data lacks a valid ID and numerical duration.
|
|
456
482
|
*/
|
|
457
483
|
add(type, data, smartQueue = true) {
|
|
484
|
+
checkDestroy(this.#destroyed);
|
|
458
485
|
if (!['music', 'voice', 'custom'].includes(type)) {
|
|
459
486
|
throw new TypeError('Type must be "music", "voice", or "custom".');
|
|
460
487
|
}
|
|
@@ -491,6 +518,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
491
518
|
* @throws {TypeError} If arguments do not match the required types or action/type constraints.
|
|
492
519
|
*/
|
|
493
520
|
scheduleTask(timestamp, action, type, payload, smartQueue = true) {
|
|
521
|
+
checkDestroy(this.#destroyed);
|
|
494
522
|
if (typeof timestamp !== 'number' || isNaN(timestamp))
|
|
495
523
|
throw new TypeError('timestamp must be a valid number.');
|
|
496
524
|
if (!['add', 'remove', 'move'].includes(action))
|
|
@@ -560,6 +588,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
560
588
|
* @throws {TypeError} If the id is not a string.
|
|
561
589
|
*/
|
|
562
590
|
remove(id) {
|
|
591
|
+
checkDestroy(this.#destroyed);
|
|
563
592
|
if (typeof id !== 'string') throw new TypeError('id must be a string.');
|
|
564
593
|
|
|
565
594
|
// Revoke Blob URLs of items being removed to free memory
|
|
@@ -605,6 +634,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
605
634
|
* @throws {TypeError|RangeError} If the provided values or the resulting state is invalid.
|
|
606
635
|
*/
|
|
607
636
|
setConfig(config) {
|
|
637
|
+
checkDestroy(this.#destroyed);
|
|
608
638
|
// First, validate the incoming partial object for basic type correctness
|
|
609
639
|
this.#validateConfig(config);
|
|
610
640
|
|
|
@@ -624,6 +654,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
624
654
|
* @returns {RadioEvent|null} The current active event, or null if empty.
|
|
625
655
|
*/
|
|
626
656
|
getCurrentEvent() {
|
|
657
|
+
checkDestroy(this.#destroyed);
|
|
627
658
|
const now = Date.now();
|
|
628
659
|
this.#syncRealTimeState(now);
|
|
629
660
|
return this.#getEventAtTime(now, now);
|
|
@@ -639,6 +670,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
639
670
|
* @throws {RangeError} If the limit exceeds the configured queryLimit or is <= 0.
|
|
640
671
|
*/
|
|
641
672
|
queryTimeline(targetDate, limit = 10) {
|
|
673
|
+
checkDestroy(this.#destroyed);
|
|
642
674
|
if (typeof limit !== 'number' || isNaN(limit)) {
|
|
643
675
|
throw new TypeError(`Invalid query limit value. Ensure it is a number.`);
|
|
644
676
|
}
|
|
@@ -677,6 +709,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
677
709
|
* @returns {CustomPosition[]} Shallow copy of custom positions array.
|
|
678
710
|
*/
|
|
679
711
|
searchCustomPositions() {
|
|
712
|
+
checkDestroy(this.#destroyed);
|
|
680
713
|
this.#syncRealTimeState(Date.now());
|
|
681
714
|
return [...this.#customPositions];
|
|
682
715
|
}
|
|
@@ -726,6 +759,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
726
759
|
* @returns {Promise<string>} Stringified JSON state.
|
|
727
760
|
*/
|
|
728
761
|
async exportState() {
|
|
762
|
+
checkDestroy(this.#destroyed);
|
|
729
763
|
const processedMusic = await this._processListForExport(this.#musicList);
|
|
730
764
|
const processedVoice = await this._processListForExport(this.#voiceList);
|
|
731
765
|
|
|
@@ -770,6 +804,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
770
804
|
* @throws {TypeError} If json is not a valid string or object.
|
|
771
805
|
*/
|
|
772
806
|
importState(json) {
|
|
807
|
+
checkDestroy(this.#destroyed);
|
|
773
808
|
/** @type {TinyRadioFmImport} */
|
|
774
809
|
let data;
|
|
775
810
|
if (typeof json === 'string') {
|
|
@@ -1347,6 +1382,8 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
1347
1382
|
* @param {boolean} [destroyThumbs=true]
|
|
1348
1383
|
*/
|
|
1349
1384
|
destroy(destroyThumbs = true) {
|
|
1385
|
+
if (this.#destroyed) return;
|
|
1386
|
+
|
|
1350
1387
|
if (destroyThumbs) {
|
|
1351
1388
|
this.#musicList.forEach((item) => mediaContent.revokeContentUrls(item));
|
|
1352
1389
|
this.#voiceList.forEach((item) => mediaContent.revokeContentUrls(item));
|
|
@@ -1371,6 +1408,7 @@ class TinyRadioFm extends events.EventEmitter {
|
|
|
1371
1408
|
this.#cycleCache.clear();
|
|
1372
1409
|
this.emit('destroyed', { timestamp: Date.now() });
|
|
1373
1410
|
this.removeAllListeners();
|
|
1411
|
+
this.#destroyed = true;
|
|
1374
1412
|
}
|
|
1375
1413
|
}
|
|
1376
1414
|
|
|
@@ -377,6 +377,7 @@ declare class TinyRadioFm extends EventEmitter<any> {
|
|
|
377
377
|
* @throws {TypeError} If initialData is not an object or null, or if seed is not a number.
|
|
378
378
|
*/
|
|
379
379
|
constructor(initialData?: TinyRadioFmImport | null, seed?: number);
|
|
380
|
+
get destroyed(): boolean;
|
|
380
381
|
/**
|
|
381
382
|
* Gets the total count of all content items (music and voice) in the system.
|
|
382
383
|
* @returns {number}
|