tiny-essentials 1.28.6 → 1.28.8

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 (54) hide show
  1. package/changelog/1/28/6.md +3 -0
  2. package/changelog/1/28/7.md +7 -0
  3. package/changelog/1/28/8.md +17 -0
  4. package/dist/v1/TinyBasicsEs.min.js +1 -1
  5. package/dist/v1/TinyDebugger.min.js +1 -0
  6. package/dist/v1/TinyEssentials.min.js +1 -1
  7. package/dist/v1/TinyMediaPlayer.min.js +1 -1
  8. package/dist/v1/TinyRadioFm.min.js +1 -1
  9. package/dist/v1/TinyUploadClicker.min.js +1 -1
  10. package/dist/v1/basics/browserDetector.cjs +228 -0
  11. package/dist/v1/basics/browserDetector.d.mts +66 -0
  12. package/dist/v1/basics/browserDetector.mjs +207 -0
  13. package/dist/v1/basics/index.cjs +6 -0
  14. package/dist/v1/basics/index.d.mts +2 -1
  15. package/dist/v1/basics/index.mjs +2 -1
  16. package/dist/v1/build/TinyDebugger.cjs +7 -0
  17. package/dist/v1/build/TinyDebugger.d.mts +3 -0
  18. package/dist/v1/build/TinyDebugger.mjs +2 -0
  19. package/dist/v1/index.cjs +8 -0
  20. package/dist/v1/index.d.mts +3 -1
  21. package/dist/v1/index.mjs +4 -2
  22. package/dist/v1/libs/TinyDebugger.cjs +380 -0
  23. package/dist/v1/libs/TinyDebugger.d.mts +132 -0
  24. package/dist/v1/libs/TinyDebugger.mjs +351 -0
  25. package/dist/v1/libs/TinyMediaPlayer/HtmlAudio.cjs +66 -3
  26. package/dist/v1/libs/TinyMediaPlayer/HtmlAudio.d.mts +25 -0
  27. package/dist/v1/libs/TinyMediaPlayer/HtmlAudio.mjs +59 -3
  28. package/dist/v1/libs/TinyMediaPlayer/HtmlVideo.cjs +66 -3
  29. package/dist/v1/libs/TinyMediaPlayer/HtmlVideo.d.mts +25 -0
  30. package/dist/v1/libs/TinyMediaPlayer/HtmlVideo.mjs +59 -3
  31. package/dist/v1/libs/TinyMediaPlayer/Mock.cjs +333 -0
  32. package/dist/v1/libs/TinyMediaPlayer/Mock.d.mts +154 -0
  33. package/dist/v1/libs/TinyMediaPlayer/Mock.mjs +296 -0
  34. package/dist/v1/libs/TinyMediaPlayer/SoundCloud.cjs +85 -1
  35. package/dist/v1/libs/TinyMediaPlayer/SoundCloud.d.mts +25 -0
  36. package/dist/v1/libs/TinyMediaPlayer/SoundCloud.mjs +75 -1
  37. package/dist/v1/libs/TinyMediaPlayer/Youtube.cjs +66 -3
  38. package/dist/v1/libs/TinyMediaPlayer/Youtube.d.mts +25 -0
  39. package/dist/v1/libs/TinyMediaPlayer/Youtube.mjs +56 -3
  40. package/dist/v1/libs/TinyMediaPlayer/index.cjs +45 -0
  41. package/dist/v1/libs/TinyMediaPlayer/index.d.mts +25 -0
  42. package/dist/v1/libs/TinyMediaPlayer/index.mjs +40 -0
  43. package/dist/v1/libs/TinyMediaPlayer.cjs +172 -10
  44. package/dist/v1/libs/TinyMediaPlayer.d.mts +47 -2
  45. package/dist/v1/libs/TinyMediaPlayer.mjs +160 -10
  46. package/dist/v1/libs/TinyPromiseQueue.cjs +6 -4
  47. package/dist/v1/libs/TinyPromiseQueue.d.mts +8 -6
  48. package/dist/v1/libs/TinyPromiseQueue.mjs +6 -4
  49. package/dist/v1/libs/TinyRadioFm.cjs +271 -138
  50. package/dist/v1/libs/TinyRadioFm.d.mts +67 -3
  51. package/dist/v1/libs/TinyRadioFm.mjs +239 -123
  52. package/docs/v1/libs/TinyMediaPlayer.md +52 -54
  53. package/docs/v1/libs/TinyRadioFm.md +25 -3
  54. package/package.json +13 -1
@@ -1,6 +1,6 @@
1
1
  # 🎧 TinyMediaPlayer Documentation
2
2
 
3
- `TinyMediaPlayer` is a robust, universal media player manager designed to orchestrate playback across multiple different media providers (such as YouTube, Spotify, etc.) using an **Adapter Pattern**.
3
+ `TinyMediaPlayer` is a robust, universal media player manager designed to orchestrate playback across multiple different media providers (such as YouTube, Spotify, etc.) using an **Adapter Pattern**. It inherits debugging capabilities from `TinyDebugger`.
4
4
 
5
5
  ---
6
6
 
@@ -11,27 +11,31 @@ To support different media platforms, `TinyMediaPlayer` relies on **Adapters**.
11
11
  ### 🛠️ `BaseMediaAdapter` (Abstract Class)
12
12
  *This class cannot be instantiated directly. It serves as an interface that all specific API wrappers must extend and implement.*
13
13
 
14
- #### Properties
15
- | Property | Type | Description |
16
- | :--- | :--- | :--- |
17
- | `destroyed` | `boolean` | Indicates if the adapter instance has been destroyed. |
18
-
19
14
  #### Methods
20
15
  | Method | Description | Parameters | Returns |
21
16
  | :--- | :--- | :--- | :--- |
17
+ | `static canHandle` | Determines if the adapter can play the provided content. | `content: MediaContent` | `boolean` |
22
18
  | `canHandle` | Determines if the adapter can play the provided content. | `content: MediaContent` | `boolean` |
19
+ | `isReady` | Synchronously checks if the adapter is ready. | None | `boolean` |
20
+ | `isPaused` | Checks whether the media adapter is paused. | None | `boolean` |
21
+ | `isEnded` | Checks whether the media adapter is ended. | None | `boolean` |
22
+ | `waitIsReady` | Asynchronously waits until the adapter is ready. | None | `Promise<void>` |
23
23
  | `play` | Starts or resumes playback of the provided content. | `content: MediaContent` | `Promise<void>` |
24
24
  | `pause` | Pauses the current playback. | None | `Promise<void>` |
25
- | `stop` | Stops the playback completely and resets the platform state. | None | `Promise<void>` |
25
+ | `stop` | Stops the playback completely and resets the internal platform state. | None | `Promise<void>` |
26
26
  | `seek` | Seeks to a specific time in the media timeline. | `timeMs: number` | `Promise<void>` |
27
- | `getCurrentTime` | Retrieves the current playback position. | None | `number` (ms) |
27
+ | `isMuted` | Checks whether the player is currently muted. | None | `boolean \| null` |
28
+ | `mute` | Mutes the current playback. | None | `Promise<void>` |
29
+ | `unMute` | Unmutes the current playback. | None | `Promise<void>` |
30
+ | `getCurrentTime` | Retrieves the current playback time from the underlying API. | None | `number` (ms) |
28
31
  | `getTotalDuration` | Gets the total duration of the content. | None | `number` (ms) |
29
32
  | `getRemainingTime` | Gets the remaining time until the content ends. | None | `number` (ms) |
30
33
  | `getPlaybackPercentage` | Gets the percentage of the content that has been played. | None | `number` (0 to 100) |
31
34
  | `getTimeData` | Retrieves a consolidated object containing all time-related metrics. | None | `ContentTimeData` |
32
35
  | `setVolume` | Sets the playback volume for the underlying API. | `volume: number` (0.0 to 1.0) | `void` |
33
- | `getVolume` | Gets the current playback volume. | None | `number` (0.0 to 1.0) |
34
- | `destroy` | Cleans up the instance, removes listeners, and marks it as destroyed. | None | `void` |
36
+ | `getVolume` | Gets the playback volume from the underlying API. | None | `number` (0.0 to 1.0) |
37
+ | `getContentData` | Retrieves the metadata of the currently loaded content. | None | `Promise<ContentData>` |
38
+ | `destroy` | Cleans up the instance. | None | `void` |
35
39
 
36
40
  ---
37
41
 
@@ -59,9 +63,9 @@ const player = new TinyMediaPlayer({
59
63
  });
60
64
 
61
65
  YoutubeMediaAdapter.defaultContainer = YoutubeMediaAdapter.createIframeContainer({
62
- videoId: 'fzKvGbQ9SgY',
63
- hidden: true,
64
- autoplay: false,
66
+ videoId: 'fzKvGbQ9SgY',
67
+ hidden: true,
68
+ autoplay: false,
65
69
  });
66
70
 
67
71
  // Register the ready-made adapters
@@ -84,55 +88,37 @@ import { BaseMediaAdapter } from 'tiny-essentials/libs/TinyMediaPlayer/Base';
84
88
  * @extends BaseMediaAdapter
85
89
  */
86
90
  class MyCustomServiceAdapter extends BaseMediaAdapter {
87
- /**
88
- * Determines if this adapter can play the given content.
89
- * @param {MediaContent} content - The media content to check.
90
- * @returns {boolean} - True if the URL matches the service.
91
- */
92
91
  static canHandle(content) {
93
92
  return content.url.startsWith('https://example.com/');
94
93
  }
95
94
 
96
- /**
97
- * Determines if this adapter can play the given content.
98
- * @param {MediaContent} content - The media content to check.
99
- * @returns {boolean} - True if the URL matches the service.
100
- */
101
95
  canHandle(content) {
102
96
  return MyCustomServiceAdapter.canHandle(content);
103
97
  }
104
98
 
105
- /**
106
- * Starts playback for the provided content.
107
- * @param {MediaContent} content - The content to play.
108
- * @returns {Promise<void>}
109
- */
110
99
  async play(content) {
111
100
  console.log(`Starting playback for: ${content.title}`);
112
- // Logic to interface with the custom service API goes here
113
101
  }
114
102
 
115
- async pause() {
116
- // Logic to pause custom service playback
117
- }
118
-
119
- async stop() {
120
- // Logic to stop custom service playback
121
- }
122
-
123
- async seek(timeMs) {
124
- // Logic to seek in custom service playback
125
- }
126
-
127
- getCurrentTime() {
128
- // Logic to return current time from custom service
129
- return 0;
130
- }
131
-
132
- setVolume(volume) {
133
- // Logic to set volume on custom service
134
- console.log(`Volume set to: ${volume}`);
135
- }
103
+ async pause() {}
104
+ async stop() {}
105
+ async seek(timeMs) {}
106
+ getCurrentTime() { return 0; }
107
+ setVolume(volume) {}
108
+ getVolume() { return 1.0; }
109
+ async getContentData() { return {}; }
110
+ async waitIsReady() {}
111
+ isReady() { return true; }
112
+ isPaused() { return false; }
113
+ isEnded() { return false; }
114
+ isMuted() { return false; }
115
+ async mute() {}
116
+ async unMute() {}
117
+ getTotalDuration() { return 0; }
118
+ getRemainingTime() { return 0; }
119
+ getPlaybackPercentage() { return 0; }
120
+ getTimeData() { return {}; }
121
+ destroy() {}
136
122
  }
137
123
 
138
124
  // Registering the custom adapter
@@ -176,6 +162,9 @@ When initializing `new TinyMediaPlayer(options)`, you can pass the following `Ti
176
162
  * **`repeatCurrentOnPrev`** (`boolean`): If `true`, clicking 'previous' repeats the current track on the first click. (Default: `false`).
177
163
  * **`smoothPlayPauseVolume`** (`boolean`): If `true`, volume fades smoothly during play/pause transitions. (Default: `false`).
178
164
  * **`smoothStopVolume`** (`boolean`): If `true`, volume fades smoothly to zero when stopping. (Default: `false`).
165
+ * **`debugMode`** (`boolean`): Whether to enable internal debug logging.
166
+ * **`useLogColors`** (`boolean`): Whether to enable log color support.
167
+ * **`logger`** (`Console`): A custom logger object.
179
168
 
180
169
  ---
181
170
 
@@ -214,6 +203,7 @@ When initializing `new TinyMediaPlayer(options)`, you can pass the following `Ti
214
203
  | `isRandom` | `boolean` | Enables or disables shuffle mode. |
215
204
  | `isPlaying` | `boolean` | Indicates if media is currently playing. |
216
205
  | `volume` | `number` | The current volume level (strictly between `0.0` and `1.0`). |
206
+ | `isMuted` | `boolean` | Indicates if the player is currently muted. |
217
207
 
218
208
  #### 🎨 UX & Customization
219
209
  | Property | Type | Description |
@@ -270,20 +260,27 @@ When initializing `new TinyMediaPlayer(options)`, you can pass the following `Ti
270
260
  #### ⏯️ Playback Controls
271
261
  * **`play()`**: **(Async)** Starts playback of the current track.
272
262
  * **`pause()`**: **(Async)** Pauses the current track.
263
+ * **`mute()`**: **(Async)** Mutes the playback.
264
+ * **`unMute()`**: **(Async)** Unmutes the playback.
273
265
  * **`stop()`**: **(Async)** Stops the current track completely.
274
266
  * **`next()`**: **(Async)** Advances to the next track (respects `loopMode` and `isRandom`).
275
267
  * **`prev()`**: **(Async)** Returns to the previous track (respects `loopMode` and `isRandom`).
268
+ * **`skipTo(index)`**: **(Async)** Jumps to a specific index in the playlist.
276
269
  * **`seek(timeMs)`**: **(Async)** Jumps to a specific millisecond in the current track.
277
- * **`step(stepMs)`**: **(Async)** Moves the timeline forward (positive) or backward (negative) by a specified amount.
270
+ * **`step(stepMs)`**: **(Async)** Moves the timeline forward (+) or backward (-) by `stepMs`.
278
271
 
279
272
  #### ⏳ Time Utilities
280
273
  * **`getCurrentTime()`**: Gets the current playback time in milliseconds.
281
274
  * **`getTotalDuration()`**: Gets the total duration of the current track in milliseconds.
282
275
  * **`getRemainingTime()`**: Gets the remaining time until the current track ends in milliseconds.
283
276
  * **`getPlaybackPercentage()`**: Gets the percentage of the current track that has been played (0-100).
277
+ * **`isPaused` (Getter)**: Checks if the adapter is paused.
278
+ * **`isEnded` (Getter)**: Checks if the adapter has ended.
279
+ * **`getContentData()`**: **(Async)** Retrieves structured metadata for the current content.
280
+ * **`waitIsReady()`**: **(Async)** Waits until the active adapter is fully initialized.
284
281
 
285
282
  #### ♻️ Lifecycle
286
- * **`destroy()`**: **(Async)** Safely stops playback, clears state, removes adapters, and detaches all listeners to prevent memory leaks.
283
+ * **`destroy()`**: **(Async)** Safely stops playback, clears state, removes adapters, and detaches all listeners.
287
284
 
288
285
  ---
289
286
 
@@ -313,6 +310,7 @@ When initializing `new TinyMediaPlayer(options)`, you can pass the following `Ti
313
310
  | `smoothStopVolumeChange` | `boolean` | Emitted when the smooth stop volume setting is toggled. |
314
311
  | `fadeVolumeSpeedChange` | `number` | Emitted when the volume fade speed is updated. |
315
312
  | `prevClickTimeoutDurationChange` | `number` | Emitted when the "repeat on prev" timeout duration is updated. |
313
+ | `muteChange` | `boolean` | Emitted when the mute state is toggled. |
316
314
 
317
315
  ### 💀 Lifecycle Events
318
316
  | Event | Data Type | Description |
@@ -324,6 +322,6 @@ When initializing `new TinyMediaPlayer(options)`, you can pass the following `Ti
324
322
  ## ⚠️ Error Handling
325
323
 
326
324
  The class uses strict validation. The following errors may be thrown:
327
- * **`TypeError`**: Thrown when an argument is of the wrong type (e.g., invalid index type, non-boolean options, invalid adapter instance, or empty storage key).
328
- * **`RangeError`**: Thrown when a number is out of allowed bounds (e.g., negative time, volume outside `0.0`-`1.0`, negative durations, or index out of playlist bounds).
325
+ * **`TypeError`**: Thrown when an argument is of the wrong type.
326
+ * **`RangeError`**: Thrown when a number is out of allowed bounds.
329
327
  * **`Error`**: Thrown if no compatible adapter is found for the current content.
@@ -31,7 +31,9 @@ The behavior of the engine is controlled via the `RadioConfig` object.
31
31
  | `voiceAfterMusic` | `boolean` | `true` | If `true`, voice messages play after music tracks. |
32
32
  | `voiceMin` | `number` | `0` | Minimum number of voice messages to play in a cycle. |
33
33
  | `voiceMax` | `number` | `1` | Maximum number of voice messages to play in a cycle. |
34
+ | `musicMinConsecutive`| `number` | `0` | Min times a music track must repeat consecutively. |
34
35
  | `musicMaxConsecutive`| `number` | `0` | Max consecutive music repeats (`-1` = unlimited, `0` = no repeats). |
36
+ | `voiceMinConsecutive`| `number` | `0` | Min times a voice track must repeat consecutively. |
35
37
  | `voiceMaxConsecutive`| `number` | `0` | Max consecutive voice repeats (`-1` = unlimited, `0` = no repeats). |
36
38
 
37
39
  ---
@@ -60,7 +62,7 @@ Adds new content to the engine immediately.
60
62
  * **Parameters:**
61
63
  * `type`: `'music' | 'voice' | 'custom'`.
62
64
  * `data`: The `MediaContent` object (must include `id` and `duration`).
63
- * `smartQueue`: If `true`, delays insertion until the current content ends (primarily for `custom`).
65
+ * `smartQueue`: If `true`, delays insertion until the end of the content playing at that timestamp (primarily for `custom`).
64
66
  * **Emits:** `contentAdded`
65
67
 
66
68
  #### `remove(id)`
@@ -108,7 +110,7 @@ Predicts upcoming events from a specific date forward using a virtual sandbox to
108
110
  ### 💾 Persistence & Lifecycle
109
111
 
110
112
  #### `async exportState()`
111
- Exports the entire radio state (playlists, tasks, seed, config) as a JSON string. Automatically converts all image Blob URLs to **Base64** for portability.
113
+ Exports the entire radio state (playlists, tasks, seed, config) as a JSON string. Automatically converts all image Blob URLs to **Base64** for easy storage.
112
114
  * **Returns:** `Promise<string>`
113
115
 
114
116
  #### `importState(json)`
@@ -138,4 +140,24 @@ An instruction to change the radio state.
138
140
  * `timestamp`: Execution time.
139
141
  * `action`: `'add' | 'remove' | 'move'`.
140
142
  * `type`: `'music' | 'voice'`.
141
- * `payload`: Action-specific data.
143
+ * `payload`: Action-specific data (`MediaContent`, `string`, or `ScheduledMovePayload`).
144
+
145
+ ### `CustomPosition` 📍
146
+ Represents content injected at a specific absolute timestamp.
147
+ * `content`: The `MediaContent` object.
148
+ * `intendedTimestamp`: The target absolute timestamp.
149
+ * `originalTimestamp`: The timestamp preserved for intelligent repositioning.
150
+
151
+ ### `ScheduledMovePayload` 🚚
152
+ Data required to relocate an existing item within a playlist.
153
+ * `id`: Content ID to move.
154
+ * `newIndex`: The target index in the playlist.
155
+
156
+ ### `CycleBlock` 🔄
157
+ A structural block representing a single full iteration of the radio sequence.
158
+ * `items`: Items belonging to this cycle.
159
+ * `duration`: Total duration of the cycle block in ms.
160
+ * `lastMusicId`: ID of the last music played in this block.
161
+ * `musicConsecutiveCount`: Current consecutive count for music.
162
+ * `lastVoiceId`: ID of the last voice played in this block.
163
+ * `voiceConsecutiveCount`: Current consecutive count for voice.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiny-essentials",
3
- "version": "1.28.6",
3
+ "version": "1.28.8",
4
4
  "description": "Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.",
5
5
  "bin": {
6
6
  "tiny-essentials-fork": "./TinyFork.mjs"
@@ -156,14 +156,26 @@
156
156
  "require": "./dist/v1/libs/TinyMediaPlayer/HtmlVideo.cjs",
157
157
  "import": "./dist/v1/libs/TinyMediaPlayer/HtmlVideo.mjs"
158
158
  },
159
+ "./libs/TinyMediaPlayer/Mock": {
160
+ "require": "./dist/v1/libs/TinyMediaPlayer/Mock.cjs",
161
+ "import": "./dist/v1/libs/TinyMediaPlayer/Mock.mjs"
162
+ },
159
163
  "./libs/TinyMediaPlayer/docs/YouTubePlayer": {
160
164
  "require": "./dist/v1/libs/TinyMediaPlayer/docs/YouTubePlayer.cjs",
161
165
  "import": "./dist/v1/libs/TinyMediaPlayer/docs/YouTubePlayer.mjs"
162
166
  },
167
+ "./libs/TinyMediaPlayer/docs/SoundCloudWidget": {
168
+ "require": "./dist/v1/libs/TinyMediaPlayer/docs/SoundCloudWidget.cjs",
169
+ "import": "./dist/v1/libs/TinyMediaPlayer/docs/SoundCloudWidget.mjs"
170
+ },
163
171
  "./libs/TinyRadioFm": {
164
172
  "require": "./dist/v1/libs/TinyRadioFm.cjs",
165
173
  "import": "./dist/v1/libs/TinyRadioFm.mjs"
166
174
  },
175
+ "./libs/TinyDebugger": {
176
+ "require": "./dist/v1/libs/TinyDebugger.cjs",
177
+ "import": "./dist/v1/libs/TinyDebugger.mjs"
178
+ },
167
179
  "./libs/UltraRandomMsgGen": {
168
180
  "require": "./dist/v1/libs/UltraRandomMsgGen.cjs",
169
181
  "import": "./dist/v1/libs/UltraRandomMsgGen.mjs"