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.
- package/README.md +1 -0
- package/changelog/1/28/0.md +16 -0
- 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 -2
- 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 -2
- 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 -2
- 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/extendObjType/Buffer.cjs +13 -0
- package/dist/v1/basics/extendObjType/Buffer.d.mts +4 -0
- package/dist/v1/basics/extendObjType/Buffer.mjs +8 -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 -18
- package/dist/v1/basics/objFilter.d.mts +6 -6
- package/dist/v1/basics/objFilter.mjs +32 -17
- 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 -2
- package/dist/v1/index.d.mts +4 -2
- package/dist/v1/index.mjs +4 -4
- package/dist/v1/libs/TinyAdvancedRaffle.cjs +71 -255
- package/dist/v1/libs/TinyAdvancedRaffle.d.mts +6 -134
- package/dist/v1/libs/TinyAdvancedRaffle.mjs +69 -228
- 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 +26 -196
- package/dist/v1/libs/TinyIframeEvents.d.mts +3 -122
- package/dist/v1/libs/TinyIframeEvents.mjs +26 -171
- package/dist/v1/libs/TinyLocalStorage.cjs +53 -205
- package/dist/v1/libs/TinyLocalStorage.d.mts +6 -127
- package/dist/v1/libs/TinyLocalStorage.mjs +50 -178
- package/dist/v1/libs/TinyMediaPlayer.cjs +74 -2
- package/dist/v1/libs/TinyMediaPlayer.d.mts +12 -2
- package/dist/v1/libs/TinyMediaPlayer.mjs +68 -2
- package/dist/v1/libs/TinyNewWinEvents.cjs +39 -197
- package/dist/v1/libs/TinyNewWinEvents.d.mts +6 -119
- package/dist/v1/libs/TinyNewWinEvents.mjs +36 -172
- 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 +40 -3
- package/dist/v1/libs/TinyRadioFm.d.mts +3 -3
- package/dist/v1/libs/TinyRadioFm.mjs +37 -3
- 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 +56 -205
- package/dist/v1/libs/TinySmartScroller.d.mts +19 -152
- package/dist/v1/libs/TinySmartScroller.mjs +55 -181
- 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 +20 -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/Exports.md +0 -1
- package/docs/v1/README.md +1 -1
- 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/objFilter.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 +10 -10
- package/docs/v1/libs/TinyLevelUp.md +1 -1
- package/docs/v1/libs/TinyLoadingScreen.md +1 -1
- package/docs/v1/libs/TinyLocalStorage.md +3 -3
- package/docs/v1/libs/TinyNewWinEvents.md +10 -11
- 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 +15 -5
- package/dist/v1/TinyBasicsEs.min.js.LICENSE.txt +0 -8
- package/dist/v1/TinyEssentials.min.js.LICENSE.txt +0 -8
- package/dist/v1/TinyEvents.min.js +0 -1
- package/dist/v1/TinyUploadClicker.min.js.LICENSE.txt +0 -8
- package/dist/v1/build/TinyEvents.cjs +0 -7
- package/dist/v1/build/TinyEvents.d.mts +0 -3
- package/dist/v1/build/TinyEvents.mjs +0 -2
- package/dist/v1/libs/TinyEvents.cjs +0 -395
- package/dist/v1/libs/TinyEvents.d.mts +0 -164
- package/dist/v1/libs/TinyEvents.mjs +0 -360
- package/docs/v1/libs/TinyEvents.md +0 -187
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
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('TinyMediaPlayer');
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* @typedef {import('../basics/mediaContent.mjs').MediaContent} MediaContent
|
|
@@ -107,7 +110,7 @@ class BaseMediaAdapter {
|
|
|
107
110
|
/**
|
|
108
111
|
* A universal media player manager capable of orchestrating multiple API adapters.
|
|
109
112
|
*/
|
|
110
|
-
class TinyMediaPlayer extends
|
|
113
|
+
class TinyMediaPlayer extends events.EventEmitter {
|
|
111
114
|
static BaseMediaAdapter = BaseMediaAdapter;
|
|
112
115
|
|
|
113
116
|
/**
|
|
@@ -160,6 +163,13 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
160
163
|
);
|
|
161
164
|
}
|
|
162
165
|
|
|
166
|
+
/** @type {boolean} */
|
|
167
|
+
#destroyed = false;
|
|
168
|
+
|
|
169
|
+
get destroyed() {
|
|
170
|
+
return this.#destroyed;
|
|
171
|
+
}
|
|
172
|
+
|
|
163
173
|
/** @type {Map<string, BaseMediaAdapter>} */
|
|
164
174
|
#adapters = new Map();
|
|
165
175
|
|
|
@@ -289,6 +299,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
289
299
|
|
|
290
300
|
/** @returns {MediaContent[]} A shallow copy of the current playlist. */
|
|
291
301
|
get playlist() {
|
|
302
|
+
checkDestroy(this.#destroyed);
|
|
292
303
|
return [...this.#playlist];
|
|
293
304
|
}
|
|
294
305
|
|
|
@@ -297,6 +308,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
297
308
|
* @throws {TypeError} If the value is not an array.
|
|
298
309
|
*/
|
|
299
310
|
set playlist(value) {
|
|
311
|
+
checkDestroy(this.#destroyed);
|
|
300
312
|
if (!Array.isArray(value)) {
|
|
301
313
|
throw new TypeError('Playlist must be an array of MediaContent objects.');
|
|
302
314
|
}
|
|
@@ -343,6 +355,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
343
355
|
|
|
344
356
|
/** @returns {number} The current active index in the playlist. */
|
|
345
357
|
get currentIndex() {
|
|
358
|
+
checkDestroy(this.#destroyed);
|
|
346
359
|
return this.#currentIndex;
|
|
347
360
|
}
|
|
348
361
|
|
|
@@ -352,6 +365,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
352
365
|
* @throws {RangeError} If the index is out of the playlist bounds (unless -1 for empty).
|
|
353
366
|
*/
|
|
354
367
|
set currentIndex(value) {
|
|
368
|
+
checkDestroy(this.#destroyed);
|
|
355
369
|
if (typeof value !== 'number') {
|
|
356
370
|
throw new TypeError('Current index must be a number.');
|
|
357
371
|
}
|
|
@@ -390,6 +404,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
390
404
|
|
|
391
405
|
/** @returns {LoopModeType} The current loop configuration. */
|
|
392
406
|
get loopMode() {
|
|
407
|
+
checkDestroy(this.#destroyed);
|
|
393
408
|
return this.#loopMode;
|
|
394
409
|
}
|
|
395
410
|
|
|
@@ -398,6 +413,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
398
413
|
* @throws {TypeError} If the value is not a valid LoopModeType.
|
|
399
414
|
*/
|
|
400
415
|
set loopMode(value) {
|
|
416
|
+
checkDestroy(this.#destroyed);
|
|
401
417
|
const validModes = ['NONE', 'TRACK', 'PLAYLIST'];
|
|
402
418
|
if (!validModes.includes(value)) {
|
|
403
419
|
throw new TypeError(`Loop mode must be one of: ${validModes.join(', ')}.`);
|
|
@@ -408,6 +424,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
408
424
|
|
|
409
425
|
/** @returns {boolean} The current random mode status. */
|
|
410
426
|
get isRandom() {
|
|
427
|
+
checkDestroy(this.#destroyed);
|
|
411
428
|
return this.#isRandom;
|
|
412
429
|
}
|
|
413
430
|
|
|
@@ -416,6 +433,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
416
433
|
* @throws {TypeError} If the value is not a boolean.
|
|
417
434
|
*/
|
|
418
435
|
set isRandom(value) {
|
|
436
|
+
checkDestroy(this.#destroyed);
|
|
419
437
|
if (typeof value !== 'boolean') {
|
|
420
438
|
throw new TypeError('Random mode state must be a boolean.');
|
|
421
439
|
}
|
|
@@ -425,11 +443,13 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
425
443
|
|
|
426
444
|
/** @returns {boolean} True if media is actively playing. */
|
|
427
445
|
get isPlaying() {
|
|
446
|
+
checkDestroy(this.#destroyed);
|
|
428
447
|
return this.#isPlaying;
|
|
429
448
|
}
|
|
430
449
|
|
|
431
450
|
/** @returns {number} The current volume level (0.0 to 1.0). */
|
|
432
451
|
get volume() {
|
|
452
|
+
checkDestroy(this.#destroyed);
|
|
433
453
|
return this.#volume;
|
|
434
454
|
}
|
|
435
455
|
|
|
@@ -439,6 +459,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
439
459
|
* @throws {RangeError} If the value is outside the 0.0 to 1.0 range.
|
|
440
460
|
*/
|
|
441
461
|
set volume(value) {
|
|
462
|
+
checkDestroy(this.#destroyed);
|
|
442
463
|
if (typeof value !== 'number') throw new TypeError('Volume must be a number.');
|
|
443
464
|
if (value < 0 || value > 1)
|
|
444
465
|
throw new RangeError('Volume must be tightly constrained between 0.0 and 1.0.');
|
|
@@ -460,6 +481,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
460
481
|
|
|
461
482
|
/** @returns {boolean} Whether the volume cache is currently enabled. */
|
|
462
483
|
get persistVolume() {
|
|
484
|
+
checkDestroy(this.#destroyed);
|
|
463
485
|
return this.#persistVolume;
|
|
464
486
|
}
|
|
465
487
|
|
|
@@ -468,6 +490,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
468
490
|
* @throws {TypeError} If the value is not a boolean.
|
|
469
491
|
*/
|
|
470
492
|
set persistVolume(value) {
|
|
493
|
+
checkDestroy(this.#destroyed);
|
|
471
494
|
if (typeof value !== 'boolean') {
|
|
472
495
|
throw new TypeError('Persist volume parameter must be a boolean.');
|
|
473
496
|
}
|
|
@@ -479,6 +502,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
479
502
|
|
|
480
503
|
/** @returns {string} The localStorage key used for volume caching. */
|
|
481
504
|
get volumeStorageKey() {
|
|
505
|
+
checkDestroy(this.#destroyed);
|
|
482
506
|
return this.#volumeStorageKey;
|
|
483
507
|
}
|
|
484
508
|
|
|
@@ -487,6 +511,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
487
511
|
* @throws {TypeError} If the value is not a string or is empty.
|
|
488
512
|
*/
|
|
489
513
|
set volumeStorageKey(value) {
|
|
514
|
+
checkDestroy(this.#destroyed);
|
|
490
515
|
if (typeof value !== 'string') {
|
|
491
516
|
throw new TypeError('Volume storage key must be a string.');
|
|
492
517
|
}
|
|
@@ -519,6 +544,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
519
544
|
* @throws {TypeError} If id is not a string or adapter is invalid.
|
|
520
545
|
*/
|
|
521
546
|
registerAdapter(id, adapter) {
|
|
547
|
+
checkDestroy(this.#destroyed);
|
|
522
548
|
if (typeof id !== 'string') {
|
|
523
549
|
throw new TypeError('Adapter ID must be a string.');
|
|
524
550
|
}
|
|
@@ -556,6 +582,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
556
582
|
* @throws {TypeError} If content is invalid or missing required base properties.
|
|
557
583
|
*/
|
|
558
584
|
addTrack(content) {
|
|
585
|
+
checkDestroy(this.#destroyed);
|
|
559
586
|
if (!content || typeof content !== 'object' || typeof content.url !== 'string')
|
|
560
587
|
throw new TypeError('Track content must be a valid MediaContent object containing a URL.');
|
|
561
588
|
|
|
@@ -579,6 +606,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
579
606
|
* @throws {TypeError} If the index is not a number.
|
|
580
607
|
*/
|
|
581
608
|
existsTrack(index) {
|
|
609
|
+
checkDestroy(this.#destroyed);
|
|
582
610
|
if (typeof index !== 'number') {
|
|
583
611
|
throw new TypeError('Index must be a number.');
|
|
584
612
|
}
|
|
@@ -593,6 +621,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
593
621
|
* @throws {RangeError} If the index is out of bounds.
|
|
594
622
|
*/
|
|
595
623
|
getTrack(index) {
|
|
624
|
+
checkDestroy(this.#destroyed);
|
|
596
625
|
if (typeof index !== 'number') {
|
|
597
626
|
throw new TypeError('Index must be a number.');
|
|
598
627
|
}
|
|
@@ -610,6 +639,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
610
639
|
* @throws {RangeError} If the index is out of bounds.
|
|
611
640
|
*/
|
|
612
641
|
async removeTrack(index) {
|
|
642
|
+
checkDestroy(this.#destroyed);
|
|
613
643
|
if (typeof index !== 'number') {
|
|
614
644
|
throw new TypeError('Index must be a number.');
|
|
615
645
|
}
|
|
@@ -648,6 +678,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
648
678
|
* @throws {TypeError} If the query is neither a string nor a function.
|
|
649
679
|
*/
|
|
650
680
|
searchTrack(query) {
|
|
681
|
+
checkDestroy(this.#destroyed);
|
|
651
682
|
if (typeof query !== 'string' && typeof query !== 'function') {
|
|
652
683
|
throw new TypeError('Search query must be a string or a boolean evaluation function.');
|
|
653
684
|
}
|
|
@@ -681,6 +712,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
681
712
|
* Clears the entire playlist and stops playback.
|
|
682
713
|
*/
|
|
683
714
|
async clearPlaylist() {
|
|
715
|
+
checkDestroy(this.#destroyed);
|
|
684
716
|
await this.stop();
|
|
685
717
|
this.#playlist = [];
|
|
686
718
|
this.#currentIndex = -1;
|
|
@@ -697,6 +729,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
697
729
|
* @returns {Promise<void>}
|
|
698
730
|
*/
|
|
699
731
|
async play() {
|
|
732
|
+
checkDestroy(this.#destroyed);
|
|
700
733
|
const adapter = this.#getActiveAdapter();
|
|
701
734
|
if (!adapter) return;
|
|
702
735
|
|
|
@@ -712,6 +745,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
712
745
|
* @returns {Promise<void>}
|
|
713
746
|
*/
|
|
714
747
|
async pause() {
|
|
748
|
+
checkDestroy(this.#destroyed);
|
|
715
749
|
const adapter = this.#getActiveAdapter();
|
|
716
750
|
if (!adapter) return;
|
|
717
751
|
|
|
@@ -725,6 +759,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
725
759
|
* @returns {Promise<void>}
|
|
726
760
|
*/
|
|
727
761
|
async stop() {
|
|
762
|
+
checkDestroy(this.#destroyed);
|
|
728
763
|
const adapter = this.#getActiveAdapter();
|
|
729
764
|
if (!adapter) return;
|
|
730
765
|
|
|
@@ -738,6 +773,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
738
773
|
* @returns {Promise<void>}
|
|
739
774
|
*/
|
|
740
775
|
async next() {
|
|
776
|
+
checkDestroy(this.#destroyed);
|
|
741
777
|
if (this.#playlist.length === 0) return;
|
|
742
778
|
|
|
743
779
|
await this.stop();
|
|
@@ -772,6 +808,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
772
808
|
* @returns {Promise<void>}
|
|
773
809
|
*/
|
|
774
810
|
async prev() {
|
|
811
|
+
checkDestroy(this.#destroyed);
|
|
775
812
|
if (this.#playlist.length === 0) return;
|
|
776
813
|
|
|
777
814
|
await this.stop();
|
|
@@ -803,6 +840,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
803
840
|
* @returns {Promise<void>}
|
|
804
841
|
*/
|
|
805
842
|
async seek(timeMs) {
|
|
843
|
+
checkDestroy(this.#destroyed);
|
|
806
844
|
if (typeof timeMs !== 'number') {
|
|
807
845
|
throw new TypeError('Seek time must be a number in milliseconds.');
|
|
808
846
|
}
|
|
@@ -824,6 +862,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
824
862
|
* @returns {Promise<void>}
|
|
825
863
|
*/
|
|
826
864
|
async step(stepMs) {
|
|
865
|
+
checkDestroy(this.#destroyed);
|
|
827
866
|
if (typeof stepMs !== 'number') {
|
|
828
867
|
throw new TypeError('Step amount must be a number in milliseconds.');
|
|
829
868
|
}
|
|
@@ -839,6 +878,39 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
839
878
|
|
|
840
879
|
await this.seek(targetTime);
|
|
841
880
|
}
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Safely destroys the TinyMediaPlayer instance.
|
|
884
|
+
* This method stops active playback, clears the internal playlist,
|
|
885
|
+
* removes all registered media adapters, and detaches all event listeners
|
|
886
|
+
* to ensure proper garbage collection and prevent memory leaks.
|
|
887
|
+
*
|
|
888
|
+
* @returns {Promise<void>} A promise that resolves when the destruction sequence is complete.
|
|
889
|
+
*/
|
|
890
|
+
async destroy() {
|
|
891
|
+
if (this.#destroyed) return;
|
|
892
|
+
|
|
893
|
+
// 1. Stop current playback if active to halt media processes
|
|
894
|
+
try {
|
|
895
|
+
if (this.#isPlaying) {
|
|
896
|
+
await this.stop();
|
|
897
|
+
}
|
|
898
|
+
} catch (error) {
|
|
899
|
+
console.warn('[TinyMediaPlayer] Non-fatal error during playback termination:', error);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// 2. Clear internal state variables
|
|
903
|
+
this.#playlist = [];
|
|
904
|
+
this.#currentIndex = -1;
|
|
905
|
+
this.#isPlaying = false;
|
|
906
|
+
|
|
907
|
+
// 3. Clear all registered API adapters
|
|
908
|
+
this.#adapters.clear();
|
|
909
|
+
|
|
910
|
+
// 4. Remove all event listeners inherited from EventEmitter
|
|
911
|
+
this.removeAllListeners();
|
|
912
|
+
this.#destroyed = true;
|
|
913
|
+
}
|
|
842
914
|
}
|
|
843
915
|
|
|
844
916
|
module.exports = TinyMediaPlayer;
|
|
@@ -42,7 +42,7 @@ export type SearchResult = {
|
|
|
42
42
|
/**
|
|
43
43
|
* A universal media player manager capable of orchestrating multiple API adapters.
|
|
44
44
|
*/
|
|
45
|
-
declare class TinyMediaPlayer extends
|
|
45
|
+
declare class TinyMediaPlayer extends EventEmitter<any> {
|
|
46
46
|
static BaseMediaAdapter: typeof BaseMediaAdapter;
|
|
47
47
|
/**
|
|
48
48
|
* @type {UnknownArtistGetter}
|
|
@@ -88,6 +88,7 @@ declare class TinyMediaPlayer extends TinyEvents {
|
|
|
88
88
|
* @param {TinyMediaPlayerOptions} [options={}] - Configuration parameters for the player.
|
|
89
89
|
*/
|
|
90
90
|
constructor(options?: TinyMediaPlayerOptions);
|
|
91
|
+
get destroyed(): boolean;
|
|
91
92
|
/**
|
|
92
93
|
* Calculates a random index based on the weighted probability of each track,
|
|
93
94
|
* strictly excluding the currently active track to prevent immediate repetition.
|
|
@@ -236,9 +237,18 @@ declare class TinyMediaPlayer extends TinyEvents {
|
|
|
236
237
|
* @returns {Promise<void>}
|
|
237
238
|
*/
|
|
238
239
|
step(stepMs: number): Promise<void>;
|
|
240
|
+
/**
|
|
241
|
+
* Safely destroys the TinyMediaPlayer instance.
|
|
242
|
+
* This method stops active playback, clears the internal playlist,
|
|
243
|
+
* removes all registered media adapters, and detaches all event listeners
|
|
244
|
+
* to ensure proper garbage collection and prevent memory leaks.
|
|
245
|
+
*
|
|
246
|
+
* @returns {Promise<void>} A promise that resolves when the destruction sequence is complete.
|
|
247
|
+
*/
|
|
248
|
+
destroy(): Promise<void>;
|
|
239
249
|
#private;
|
|
240
250
|
}
|
|
241
|
-
import
|
|
251
|
+
import { EventEmitter } from 'events';
|
|
242
252
|
/**
|
|
243
253
|
* @typedef {import('../basics/mediaContent.mjs').MediaContent} MediaContent
|
|
244
254
|
* @typedef {import('../basics/mediaContent.mjs').MediaContentBase} MediaContentBase
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
2
|
import { getMediaContentBase, getMediaContentMetadata, parseMediaMetadata, valMediaContentMetadata, } from '../basics/mediaContent.mjs';
|
|
3
|
+
import { createCheckDestroyed } from './utils.mjs';
|
|
4
|
+
const checkDestroy = createCheckDestroyed('TinyMediaPlayer');
|
|
3
5
|
/**
|
|
4
6
|
* @typedef {import('../basics/mediaContent.mjs').MediaContent} MediaContent
|
|
5
7
|
* @typedef {import('../basics/mediaContent.mjs').MediaContentBase} MediaContentBase
|
|
@@ -92,7 +94,7 @@ class BaseMediaAdapter {
|
|
|
92
94
|
/**
|
|
93
95
|
* A universal media player manager capable of orchestrating multiple API adapters.
|
|
94
96
|
*/
|
|
95
|
-
class TinyMediaPlayer extends
|
|
97
|
+
class TinyMediaPlayer extends EventEmitter {
|
|
96
98
|
static BaseMediaAdapter = BaseMediaAdapter;
|
|
97
99
|
/**
|
|
98
100
|
* @type {UnknownArtistGetter}
|
|
@@ -133,6 +135,11 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
133
135
|
static async parseContent(source, defaultMetadata, metadata, parseFile, callbacks) {
|
|
134
136
|
return parseMediaMetadata(source, defaultMetadata, metadata, parseFile, callbacks, TinyMediaPlayer.#unknownArtist);
|
|
135
137
|
}
|
|
138
|
+
/** @type {boolean} */
|
|
139
|
+
#destroyed = false;
|
|
140
|
+
get destroyed() {
|
|
141
|
+
return this.#destroyed;
|
|
142
|
+
}
|
|
136
143
|
/** @type {Map<string, BaseMediaAdapter>} */
|
|
137
144
|
#adapters = new Map();
|
|
138
145
|
/** @type {MediaContent[]} */
|
|
@@ -244,6 +251,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
244
251
|
// ==========================================
|
|
245
252
|
/** @returns {MediaContent[]} A shallow copy of the current playlist. */
|
|
246
253
|
get playlist() {
|
|
254
|
+
checkDestroy(this.#destroyed);
|
|
247
255
|
return [...this.#playlist];
|
|
248
256
|
}
|
|
249
257
|
/**
|
|
@@ -251,6 +259,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
251
259
|
* @throws {TypeError} If the value is not an array.
|
|
252
260
|
*/
|
|
253
261
|
set playlist(value) {
|
|
262
|
+
checkDestroy(this.#destroyed);
|
|
254
263
|
if (!Array.isArray(value)) {
|
|
255
264
|
throw new TypeError('Playlist must be an array of MediaContent objects.');
|
|
256
265
|
}
|
|
@@ -296,6 +305,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
296
305
|
}
|
|
297
306
|
/** @returns {number} The current active index in the playlist. */
|
|
298
307
|
get currentIndex() {
|
|
308
|
+
checkDestroy(this.#destroyed);
|
|
299
309
|
return this.#currentIndex;
|
|
300
310
|
}
|
|
301
311
|
/**
|
|
@@ -304,6 +314,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
304
314
|
* @throws {RangeError} If the index is out of the playlist bounds (unless -1 for empty).
|
|
305
315
|
*/
|
|
306
316
|
set currentIndex(value) {
|
|
317
|
+
checkDestroy(this.#destroyed);
|
|
307
318
|
if (typeof value !== 'number') {
|
|
308
319
|
throw new TypeError('Current index must be a number.');
|
|
309
320
|
}
|
|
@@ -341,6 +352,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
341
352
|
}
|
|
342
353
|
/** @returns {LoopModeType} The current loop configuration. */
|
|
343
354
|
get loopMode() {
|
|
355
|
+
checkDestroy(this.#destroyed);
|
|
344
356
|
return this.#loopMode;
|
|
345
357
|
}
|
|
346
358
|
/**
|
|
@@ -348,6 +360,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
348
360
|
* @throws {TypeError} If the value is not a valid LoopModeType.
|
|
349
361
|
*/
|
|
350
362
|
set loopMode(value) {
|
|
363
|
+
checkDestroy(this.#destroyed);
|
|
351
364
|
const validModes = ['NONE', 'TRACK', 'PLAYLIST'];
|
|
352
365
|
if (!validModes.includes(value)) {
|
|
353
366
|
throw new TypeError(`Loop mode must be one of: ${validModes.join(', ')}.`);
|
|
@@ -357,6 +370,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
357
370
|
}
|
|
358
371
|
/** @returns {boolean} The current random mode status. */
|
|
359
372
|
get isRandom() {
|
|
373
|
+
checkDestroy(this.#destroyed);
|
|
360
374
|
return this.#isRandom;
|
|
361
375
|
}
|
|
362
376
|
/**
|
|
@@ -364,6 +378,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
364
378
|
* @throws {TypeError} If the value is not a boolean.
|
|
365
379
|
*/
|
|
366
380
|
set isRandom(value) {
|
|
381
|
+
checkDestroy(this.#destroyed);
|
|
367
382
|
if (typeof value !== 'boolean') {
|
|
368
383
|
throw new TypeError('Random mode state must be a boolean.');
|
|
369
384
|
}
|
|
@@ -372,10 +387,12 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
372
387
|
}
|
|
373
388
|
/** @returns {boolean} True if media is actively playing. */
|
|
374
389
|
get isPlaying() {
|
|
390
|
+
checkDestroy(this.#destroyed);
|
|
375
391
|
return this.#isPlaying;
|
|
376
392
|
}
|
|
377
393
|
/** @returns {number} The current volume level (0.0 to 1.0). */
|
|
378
394
|
get volume() {
|
|
395
|
+
checkDestroy(this.#destroyed);
|
|
379
396
|
return this.#volume;
|
|
380
397
|
}
|
|
381
398
|
/**
|
|
@@ -384,6 +401,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
384
401
|
* @throws {RangeError} If the value is outside the 0.0 to 1.0 range.
|
|
385
402
|
*/
|
|
386
403
|
set volume(value) {
|
|
404
|
+
checkDestroy(this.#destroyed);
|
|
387
405
|
if (typeof value !== 'number')
|
|
388
406
|
throw new TypeError('Volume must be a number.');
|
|
389
407
|
if (value < 0 || value > 1)
|
|
@@ -405,6 +423,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
405
423
|
}
|
|
406
424
|
/** @returns {boolean} Whether the volume cache is currently enabled. */
|
|
407
425
|
get persistVolume() {
|
|
426
|
+
checkDestroy(this.#destroyed);
|
|
408
427
|
return this.#persistVolume;
|
|
409
428
|
}
|
|
410
429
|
/**
|
|
@@ -412,6 +431,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
412
431
|
* @throws {TypeError} If the value is not a boolean.
|
|
413
432
|
*/
|
|
414
433
|
set persistVolume(value) {
|
|
434
|
+
checkDestroy(this.#destroyed);
|
|
415
435
|
if (typeof value !== 'boolean') {
|
|
416
436
|
throw new TypeError('Persist volume parameter must be a boolean.');
|
|
417
437
|
}
|
|
@@ -422,6 +442,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
422
442
|
}
|
|
423
443
|
/** @returns {string} The localStorage key used for volume caching. */
|
|
424
444
|
get volumeStorageKey() {
|
|
445
|
+
checkDestroy(this.#destroyed);
|
|
425
446
|
return this.#volumeStorageKey;
|
|
426
447
|
}
|
|
427
448
|
/**
|
|
@@ -429,6 +450,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
429
450
|
* @throws {TypeError} If the value is not a string or is empty.
|
|
430
451
|
*/
|
|
431
452
|
set volumeStorageKey(value) {
|
|
453
|
+
checkDestroy(this.#destroyed);
|
|
432
454
|
if (typeof value !== 'string') {
|
|
433
455
|
throw new TypeError('Volume storage key must be a string.');
|
|
434
456
|
}
|
|
@@ -458,6 +480,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
458
480
|
* @throws {TypeError} If id is not a string or adapter is invalid.
|
|
459
481
|
*/
|
|
460
482
|
registerAdapter(id, adapter) {
|
|
483
|
+
checkDestroy(this.#destroyed);
|
|
461
484
|
if (typeof id !== 'string') {
|
|
462
485
|
throw new TypeError('Adapter ID must be a string.');
|
|
463
486
|
}
|
|
@@ -492,6 +515,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
492
515
|
* @throws {TypeError} If content is invalid or missing required base properties.
|
|
493
516
|
*/
|
|
494
517
|
addTrack(content) {
|
|
518
|
+
checkDestroy(this.#destroyed);
|
|
495
519
|
if (!content || typeof content !== 'object' || typeof content.url !== 'string')
|
|
496
520
|
throw new TypeError('Track content must be a valid MediaContent object containing a URL.');
|
|
497
521
|
/** @type {MediaContent} */
|
|
@@ -512,6 +536,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
512
536
|
* @throws {TypeError} If the index is not a number.
|
|
513
537
|
*/
|
|
514
538
|
existsTrack(index) {
|
|
539
|
+
checkDestroy(this.#destroyed);
|
|
515
540
|
if (typeof index !== 'number') {
|
|
516
541
|
throw new TypeError('Index must be a number.');
|
|
517
542
|
}
|
|
@@ -525,6 +550,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
525
550
|
* @throws {RangeError} If the index is out of bounds.
|
|
526
551
|
*/
|
|
527
552
|
getTrack(index) {
|
|
553
|
+
checkDestroy(this.#destroyed);
|
|
528
554
|
if (typeof index !== 'number') {
|
|
529
555
|
throw new TypeError('Index must be a number.');
|
|
530
556
|
}
|
|
@@ -541,6 +567,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
541
567
|
* @throws {RangeError} If the index is out of bounds.
|
|
542
568
|
*/
|
|
543
569
|
async removeTrack(index) {
|
|
570
|
+
checkDestroy(this.#destroyed);
|
|
544
571
|
if (typeof index !== 'number') {
|
|
545
572
|
throw new TypeError('Index must be a number.');
|
|
546
573
|
}
|
|
@@ -578,6 +605,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
578
605
|
* @throws {TypeError} If the query is neither a string nor a function.
|
|
579
606
|
*/
|
|
580
607
|
searchTrack(query) {
|
|
608
|
+
checkDestroy(this.#destroyed);
|
|
581
609
|
if (typeof query !== 'string' && typeof query !== 'function') {
|
|
582
610
|
throw new TypeError('Search query must be a string or a boolean evaluation function.');
|
|
583
611
|
}
|
|
@@ -605,6 +633,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
605
633
|
* Clears the entire playlist and stops playback.
|
|
606
634
|
*/
|
|
607
635
|
async clearPlaylist() {
|
|
636
|
+
checkDestroy(this.#destroyed);
|
|
608
637
|
await this.stop();
|
|
609
638
|
this.#playlist = [];
|
|
610
639
|
this.#currentIndex = -1;
|
|
@@ -619,6 +648,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
619
648
|
* @returns {Promise<void>}
|
|
620
649
|
*/
|
|
621
650
|
async play() {
|
|
651
|
+
checkDestroy(this.#destroyed);
|
|
622
652
|
const adapter = this.#getActiveAdapter();
|
|
623
653
|
if (!adapter)
|
|
624
654
|
return;
|
|
@@ -633,6 +663,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
633
663
|
* @returns {Promise<void>}
|
|
634
664
|
*/
|
|
635
665
|
async pause() {
|
|
666
|
+
checkDestroy(this.#destroyed);
|
|
636
667
|
const adapter = this.#getActiveAdapter();
|
|
637
668
|
if (!adapter)
|
|
638
669
|
return;
|
|
@@ -645,6 +676,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
645
676
|
* @returns {Promise<void>}
|
|
646
677
|
*/
|
|
647
678
|
async stop() {
|
|
679
|
+
checkDestroy(this.#destroyed);
|
|
648
680
|
const adapter = this.#getActiveAdapter();
|
|
649
681
|
if (!adapter)
|
|
650
682
|
return;
|
|
@@ -657,6 +689,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
657
689
|
* @returns {Promise<void>}
|
|
658
690
|
*/
|
|
659
691
|
async next() {
|
|
692
|
+
checkDestroy(this.#destroyed);
|
|
660
693
|
if (this.#playlist.length === 0)
|
|
661
694
|
return;
|
|
662
695
|
await this.stop();
|
|
@@ -689,6 +722,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
689
722
|
* @returns {Promise<void>}
|
|
690
723
|
*/
|
|
691
724
|
async prev() {
|
|
725
|
+
checkDestroy(this.#destroyed);
|
|
692
726
|
if (this.#playlist.length === 0)
|
|
693
727
|
return;
|
|
694
728
|
await this.stop();
|
|
@@ -719,6 +753,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
719
753
|
* @returns {Promise<void>}
|
|
720
754
|
*/
|
|
721
755
|
async seek(timeMs) {
|
|
756
|
+
checkDestroy(this.#destroyed);
|
|
722
757
|
if (typeof timeMs !== 'number') {
|
|
723
758
|
throw new TypeError('Seek time must be a number in milliseconds.');
|
|
724
759
|
}
|
|
@@ -738,6 +773,7 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
738
773
|
* @returns {Promise<void>}
|
|
739
774
|
*/
|
|
740
775
|
async step(stepMs) {
|
|
776
|
+
checkDestroy(this.#destroyed);
|
|
741
777
|
if (typeof stepMs !== 'number') {
|
|
742
778
|
throw new TypeError('Step amount must be a number in milliseconds.');
|
|
743
779
|
}
|
|
@@ -751,5 +787,35 @@ class TinyMediaPlayer extends TinyEvents {
|
|
|
751
787
|
targetTime = 0;
|
|
752
788
|
await this.seek(targetTime);
|
|
753
789
|
}
|
|
790
|
+
/**
|
|
791
|
+
* Safely destroys the TinyMediaPlayer instance.
|
|
792
|
+
* This method stops active playback, clears the internal playlist,
|
|
793
|
+
* removes all registered media adapters, and detaches all event listeners
|
|
794
|
+
* to ensure proper garbage collection and prevent memory leaks.
|
|
795
|
+
*
|
|
796
|
+
* @returns {Promise<void>} A promise that resolves when the destruction sequence is complete.
|
|
797
|
+
*/
|
|
798
|
+
async destroy() {
|
|
799
|
+
if (this.#destroyed)
|
|
800
|
+
return;
|
|
801
|
+
// 1. Stop current playback if active to halt media processes
|
|
802
|
+
try {
|
|
803
|
+
if (this.#isPlaying) {
|
|
804
|
+
await this.stop();
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
catch (error) {
|
|
808
|
+
console.warn('[TinyMediaPlayer] Non-fatal error during playback termination:', error);
|
|
809
|
+
}
|
|
810
|
+
// 2. Clear internal state variables
|
|
811
|
+
this.#playlist = [];
|
|
812
|
+
this.#currentIndex = -1;
|
|
813
|
+
this.#isPlaying = false;
|
|
814
|
+
// 3. Clear all registered API adapters
|
|
815
|
+
this.#adapters.clear();
|
|
816
|
+
// 4. Remove all event listeners inherited from EventEmitter
|
|
817
|
+
this.removeAllListeners();
|
|
818
|
+
this.#destroyed = true;
|
|
819
|
+
}
|
|
754
820
|
}
|
|
755
821
|
export default TinyMediaPlayer;
|