tiny-essentials 1.28.10 โ†’ 1.28.12

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.
@@ -364,11 +364,12 @@ export const valMediaContentMetadataPartial = (common) => {
364
364
  *
365
365
  * @param {string} url - The full URL of the audio file to be downloaded.
366
366
  * @param {ParseMediaContentMetadata} parseFile - The function used to parse the file data.
367
- * @returns {Promise<MediaContentMetadata<string>>} A promise that resolves to an object containing the extracted metadata.
367
+ * @param {boolean} [convertBase64toBlob=true] - If the image content needs to be converted directly into a high-performance Blob URL, use this method.
368
+ * @returns {Promise<MediaContentMetadata<PictureDataType>>} A promise that resolves to an object containing the extracted metadata.
368
369
  * @throws {TypeError} If the provided `url` is not a string or `parseFile` is not a function.
369
370
  * @throws {Error} If the network request fails or the parsing process encounters an error.
370
371
  */
371
- export const extractMediaId3Tags = async (url, parseFile) => {
372
+ export const extractMediaId3Tags = async (url, parseFile, convertBase64toBlob = true) => {
372
373
  // Argument Validation
373
374
  checkString(url, 'url');
374
375
  checkFunction(parseFile, 'parseFile');
@@ -403,7 +404,7 @@ export const extractMediaId3Tags = async (url, parseFile) => {
403
404
  track: common?.track ? { no: common.track.no, of: common.track.of } : { no: null, of: null },
404
405
  picture: common?.picture?.map((value) => ({
405
406
  ...value,
406
- data: convertToBlobUrl(value.data, value.format),
407
+ data: convertBase64toBlob ? convertToBlobUrl(value.data, value.format) : value.data,
407
408
  })) ?? [],
408
409
  };
409
410
  }
@@ -424,6 +425,7 @@ export const extractMediaId3Tags = async (url, parseFile) => {
424
425
  * @param {Object} [callbacks={}] - Callbacks for monitoring the loading process.
425
426
  * @param {(progress: LoadingMediaProgress) => void} [callbacks.onProgress] - Callback triggered on stage changes.
426
427
  * @param {(error: MediaLoadingErrorData) => void} [callbacks.onError] - Callback triggered when a non-fatal or fatal error occurs.
428
+ * @param {boolean} [convertBase64toBlob=true] - If the image content needs to be converted directly into a high-performance Blob URL, use this method.
427
429
  * @param {UnknownArtistGetter} unknownArtist
428
430
  * @returns {Promise<MediaContent<PictureData>>} A promise that resolves to a valid MediaContent object.
429
431
  * @throws {MediaLoadingError} If the preparation process fails at any stage.
@@ -459,7 +461,7 @@ export const parseMediaMetadata = async (source, defaultMetadata = {}, metadata
459
461
  if (!(data instanceof Blob))
460
462
  throw new TypeError('Expected "data" to be a Blob.');
461
463
  return new Promise((resolve, reject) => reject(new TypeError('parseFile library not found.')));
462
- }, callbacks = {}, unknownArtist = 'null') => {
464
+ }, callbacks = {}, convertBase64toBlob = true, unknownArtist = 'null') => {
463
465
  // Argument Validation
464
466
  if (typeof source !== 'string' && !(source instanceof HTMLMediaElement))
465
467
  throw new TypeError('Source must be a string or an HTMLMediaElement.');
@@ -564,11 +566,11 @@ export const parseMediaMetadata = async (source, defaultMetadata = {}, metadata
564
566
  weight: metadata.weight ?? 1,
565
567
  };
566
568
  // 4. Automatic Metadata Extraction (ID3 Tags)
567
- /** @type {Partial<MediaContentMetadata<string>>} */
569
+ /** @type {Partial<MediaContentMetadata<PictureDataType>>} */
568
570
  let extractedMetadata = {};
569
571
  notifyProgress('EXTRACTING_ID3');
570
572
  try {
571
- extractedMetadata = await extractMediaId3Tags(url, parseFile);
573
+ extractedMetadata = await extractMediaId3Tags(url, parseFile, convertBase64toBlob);
572
574
  }
573
575
  catch (err) {
574
576
  // We treat ID3 failure as a non-fatal error for the whole process,
package/dist/v1/index.cjs CHANGED
@@ -71,6 +71,7 @@ exports.formatCustomTimer = clock.formatCustomTimer;
71
71
  exports.formatDayTimer = clock.formatDayTimer;
72
72
  exports.formatTimer = clock.formatTimer;
73
73
  exports.getTimeDuration = clock.getTimeDuration;
74
+ exports.getUserTimeFormat = clock.getUserTimeFormat;
74
75
  exports.checkObj = objFilter.checkObj;
75
76
  exports.cloneObjTypeOrder = objFilter.cloneObjTypeOrder;
76
77
  exports.extendObjType = objFilter.extendObjType;
@@ -1,6 +1,6 @@
1
1
  import TinyLevelUp from './libs/TinyLevelUp.mjs';
2
2
  import { diffArrayList, shuffleArray, arraySortPositions, multiplyArrayBlocks } from './basics/array.mjs';
3
- import { breakdownDuration, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration } from './basics/clock.mjs';
3
+ import { breakdownDuration, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, getUserTimeFormat } from './basics/clock.mjs';
4
4
  import { extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, objType, checkObj, objTypeName, isObjType } from './basics/objFilter.mjs';
5
5
  import { countObj, isJsonObject, isValidObj } from './basics/objChecker.mjs';
6
6
  import { documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange } from './basics/fullScreen.mjs';
@@ -56,5 +56,5 @@ import { createCheckDestroyed } from './libs/utils.mjs';
56
56
  import { createSingletonTask, waitForTrue } from './basics/promiseUtils.mjs';
57
57
  import TinyDebugger from './libs/TinyDebugger.mjs';
58
58
  import { browserIs, getBrowserCssPrefix, getBrowserPings, getDuckTyping, isBrowserAgent } from './basics/browserDetector.mjs';
59
- export { TinyDebugger, TinyMediaPlayer, TinyRadioFm, TinyClassManager, FuzzySet, MamdaniInferenceSystem, TinyArrayComparator, TinyTextDiffer, TinyAnalogClock, TinyColorValidator, TinyLoadingScreen, TinyElementObserver, TinySimpleDice, TinyNeedBar, TinyI18, TinyCookieConsent, TinyInventory, TinyInventoryTrader, TinyArrayPaginator, TinyAdvancedRaffle, TinyDayNightCycle, TinyGamepad, TinyTextarea, TinyNewWinEvents, TinyIframeEvents, TinyLocalStorage, TinyTimeout, TinyColorConverter, TinyClipboard, TinyTextRangeEditor, TinySmartScroller, UltraRandomMsgGen, TinyAfterScrollWatcher, TinyHtml, TinyNotifications, TinyDomReadyManager, TinyDragger, TinyDragDropDetector, TinyToastNotify, TinyNotifyCenter, TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, getBrowserPings, isBrowserAgent, getBrowserCssPrefix, getDuckTyping, browserIs, isValidObj, createSingletonTask, waitForTrue, multiplyArrayBlocks, createCheckDestroyed, valMediaContentMetadata, valMediaContentMetadataPartial, parseMediaMetadata, extractMediaId3Tags, defuzzifyCentroid, trapezoid, diffArrayList, diffStrings, diffObjList, breakdownDuration, calculateMarketcap, compareMarketcap, getPercentage, areElsCollTop, areElsCollBottom, areElsCollLeft, areElsCollRight, areElsCollPerfTop, areElsCollPerfBottom, areElsCollPerfLeft, areElsCollPerfRight, areElsColliding, areElsPerfColliding, getElsColliding, getElsPerfColliding, getElsCollOverlap, getElsCollOverlapPos, getRectCenter, getElsRelativeCenterOffset, getElsCollDirDepth, getElsCollDetails, safeTextTrim, installWindowHiddenScript, genFibonacciSeq, isDirEmptyAsync, fileSizeAsync, dirSizeAsync, listFilesAsync, listDirsAsync, getLatestBackupPath, fetchJson, fetchText, readJsonBlob, readFileBlob, readBase64Blob, saveJsonFile, readJsonFile, writeJsonFile, ensureDirectory, clearDirectoryAsync, clearDirectory, fileExists, dirExists, isDirEmpty, ensureCopyFile, tryDeleteFile, writeTextFile, listFiles, listDirs, fileSize, dirSize, backupFile, restoreLatestBackup, renameFileBatch, renameFileRegex, renameFileAddPrefixSuffix, renameFileNormalizeCase, renameFilePadNumbers, documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, isJsonObject, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objTypeName, isObjType, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
59
+ export { TinyDebugger, TinyMediaPlayer, TinyRadioFm, TinyClassManager, FuzzySet, MamdaniInferenceSystem, TinyArrayComparator, TinyTextDiffer, TinyAnalogClock, TinyColorValidator, TinyLoadingScreen, TinyElementObserver, TinySimpleDice, TinyNeedBar, TinyI18, TinyCookieConsent, TinyInventory, TinyInventoryTrader, TinyArrayPaginator, TinyAdvancedRaffle, TinyDayNightCycle, TinyGamepad, TinyTextarea, TinyNewWinEvents, TinyIframeEvents, TinyLocalStorage, TinyTimeout, TinyColorConverter, TinyClipboard, TinyTextRangeEditor, TinySmartScroller, UltraRandomMsgGen, TinyAfterScrollWatcher, TinyHtml, TinyNotifications, TinyDomReadyManager, TinyDragger, TinyDragDropDetector, TinyToastNotify, TinyNotifyCenter, TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, getUserTimeFormat, getBrowserPings, isBrowserAgent, getBrowserCssPrefix, getDuckTyping, browserIs, isValidObj, createSingletonTask, waitForTrue, multiplyArrayBlocks, createCheckDestroyed, valMediaContentMetadata, valMediaContentMetadataPartial, parseMediaMetadata, extractMediaId3Tags, defuzzifyCentroid, trapezoid, diffArrayList, diffStrings, diffObjList, breakdownDuration, calculateMarketcap, compareMarketcap, getPercentage, areElsCollTop, areElsCollBottom, areElsCollLeft, areElsCollRight, areElsCollPerfTop, areElsCollPerfBottom, areElsCollPerfLeft, areElsCollPerfRight, areElsColliding, areElsPerfColliding, getElsColliding, getElsPerfColliding, getElsCollOverlap, getElsCollOverlapPos, getRectCenter, getElsRelativeCenterOffset, getElsCollDirDepth, getElsCollDetails, safeTextTrim, installWindowHiddenScript, genFibonacciSeq, isDirEmptyAsync, fileSizeAsync, dirSizeAsync, listFilesAsync, listDirsAsync, getLatestBackupPath, fetchJson, fetchText, readJsonBlob, readFileBlob, readBase64Blob, saveJsonFile, readJsonFile, writeJsonFile, ensureDirectory, clearDirectoryAsync, clearDirectory, fileExists, dirExists, isDirEmpty, ensureCopyFile, tryDeleteFile, writeTextFile, listFiles, listDirs, fileSize, dirSize, backupFile, restoreLatestBackup, renameFileBatch, renameFileRegex, renameFileAddPrefixSuffix, renameFileNormalizeCase, renameFilePadNumbers, documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, isJsonObject, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objTypeName, isObjType, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
60
60
  //# sourceMappingURL=index.d.mts.map
package/dist/v1/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import TinyLevelUp from './libs/TinyLevelUp.mjs';
2
2
  import { diffArrayList, shuffleArray, arraySortPositions, multiplyArrayBlocks, } from './basics/array.mjs';
3
- import { breakdownDuration, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, } from './basics/clock.mjs';
3
+ import { breakdownDuration, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, getUserTimeFormat, } from './basics/clock.mjs';
4
4
  import { extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, objType, checkObj, objTypeName, isObjType, } from './basics/objFilter.mjs';
5
5
  import { countObj, isJsonObject, isValidObj } from './basics/objChecker.mjs';
6
6
  import { documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, } from './basics/fullScreen.mjs';
@@ -59,4 +59,4 @@ import { browserIs, getBrowserCssPrefix, getBrowserPings, getDuckTyping, isBrows
59
59
  // import TinyHtmlElems from './libs/TinyHtml/index.mjs';
60
60
  export { TinyDebugger, TinyMediaPlayer, TinyRadioFm, TinyClassManager, FuzzySet, MamdaniInferenceSystem, TinyArrayComparator, TinyTextDiffer, TinyAnalogClock,
61
61
  // TinyHtmlElems,
62
- TinyColorValidator, TinyLoadingScreen, TinyElementObserver, TinySimpleDice, TinyNeedBar, TinyI18, TinyCookieConsent, TinyInventory, TinyInventoryTrader, TinyArrayPaginator, TinyAdvancedRaffle, TinyDayNightCycle, TinyGamepad, TinyTextarea, TinyNewWinEvents, TinyIframeEvents, TinyLocalStorage, TinyTimeout, TinyColorConverter, TinyClipboard, TinyTextRangeEditor, TinySmartScroller, UltraRandomMsgGen, TinyAfterScrollWatcher, TinyHtml, TinyNotifications, TinyDomReadyManager, TinyDragger, TinyDragDropDetector, TinyToastNotify, TinyNotifyCenter, TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, getBrowserPings, isBrowserAgent, getBrowserCssPrefix, getDuckTyping, browserIs, isValidObj, createSingletonTask, waitForTrue, multiplyArrayBlocks, createCheckDestroyed, valMediaContentMetadata, valMediaContentMetadataPartial, parseMediaMetadata, extractMediaId3Tags, defuzzifyCentroid, trapezoid, diffArrayList, diffStrings, diffObjList, breakdownDuration, calculateMarketcap, compareMarketcap, getPercentage, areElsCollTop, areElsCollBottom, areElsCollLeft, areElsCollRight, areElsCollPerfTop, areElsCollPerfBottom, areElsCollPerfLeft, areElsCollPerfRight, areElsColliding, areElsPerfColliding, getElsColliding, getElsPerfColliding, getElsCollOverlap, getElsCollOverlapPos, getRectCenter, getElsRelativeCenterOffset, getElsCollDirDepth, getElsCollDetails, safeTextTrim, installWindowHiddenScript, genFibonacciSeq, isDirEmptyAsync, fileSizeAsync, dirSizeAsync, listFilesAsync, listDirsAsync, getLatestBackupPath, fetchJson, fetchText, readJsonBlob, readFileBlob, readBase64Blob, saveJsonFile, readJsonFile, writeJsonFile, ensureDirectory, clearDirectoryAsync, clearDirectory, fileExists, dirExists, isDirEmpty, ensureCopyFile, tryDeleteFile, writeTextFile, listFiles, listDirs, fileSize, dirSize, backupFile, restoreLatestBackup, renameFileBatch, renameFileRegex, renameFileAddPrefixSuffix, renameFileNormalizeCase, renameFilePadNumbers, documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, isJsonObject, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objTypeName, isObjType, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
62
+ TinyColorValidator, TinyLoadingScreen, TinyElementObserver, TinySimpleDice, TinyNeedBar, TinyI18, TinyCookieConsent, TinyInventory, TinyInventoryTrader, TinyArrayPaginator, TinyAdvancedRaffle, TinyDayNightCycle, TinyGamepad, TinyTextarea, TinyNewWinEvents, TinyIframeEvents, TinyLocalStorage, TinyTimeout, TinyColorConverter, TinyClipboard, TinyTextRangeEditor, TinySmartScroller, UltraRandomMsgGen, TinyAfterScrollWatcher, TinyHtml, TinyNotifications, TinyDomReadyManager, TinyDragger, TinyDragDropDetector, TinyToastNotify, TinyNotifyCenter, TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, getUserTimeFormat, getBrowserPings, isBrowserAgent, getBrowserCssPrefix, getDuckTyping, browserIs, isValidObj, createSingletonTask, waitForTrue, multiplyArrayBlocks, createCheckDestroyed, valMediaContentMetadata, valMediaContentMetadataPartial, parseMediaMetadata, extractMediaId3Tags, defuzzifyCentroid, trapezoid, diffArrayList, diffStrings, diffObjList, breakdownDuration, calculateMarketcap, compareMarketcap, getPercentage, areElsCollTop, areElsCollBottom, areElsCollLeft, areElsCollRight, areElsCollPerfTop, areElsCollPerfBottom, areElsCollPerfLeft, areElsCollPerfRight, areElsColliding, areElsPerfColliding, getElsColliding, getElsPerfColliding, getElsCollOverlap, getElsCollOverlapPos, getRectCenter, getElsRelativeCenterOffset, getElsCollDirDepth, getElsCollDetails, safeTextTrim, installWindowHiddenScript, genFibonacciSeq, isDirEmptyAsync, fileSizeAsync, dirSizeAsync, listFilesAsync, listDirsAsync, getLatestBackupPath, fetchJson, fetchText, readJsonBlob, readFileBlob, readBase64Blob, saveJsonFile, readJsonFile, writeJsonFile, ensureDirectory, clearDirectoryAsync, clearDirectory, fileExists, dirExists, isDirEmpty, ensureCopyFile, tryDeleteFile, writeTextFile, listFiles, listDirs, fileSize, dirSize, backupFile, restoreLatestBackup, renameFileBatch, renameFileRegex, renameFileAddPrefixSuffix, renameFileNormalizeCase, renameFilePadNumbers, documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, isJsonObject, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objTypeName, isObjType, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
@@ -88,16 +88,25 @@ class TinyMediaPlayer extends TinyDebugger {
88
88
  * @param {Object} [callbacks={}] - Callbacks for monitoring the loading process.
89
89
  * @param {(progress: LoadingMediaProgress) => void} [callbacks.onProgress] - Callback triggered on stage changes.
90
90
  * @param {(error: MediaLoadingErrorData) => void} [callbacks.onError] - Callback triggered when a non-fatal or fatal error occurs.
91
+ * @param {boolean} [convertBase64toBlob=true] - If the image content needs to be converted directly into a high-performance Blob URL, use this method.
91
92
  * @returns {Promise<MediaContent>} A promise that resolves to a valid MediaContent object.
92
93
  * @throws {MediaLoadingError} If the preparation process fails at any stage.
93
94
  */
94
- static async parseContent(source, defaultMetadata, metadata, parseFile, callbacks) {
95
+ static async parseContent(
96
+ source,
97
+ defaultMetadata,
98
+ metadata,
99
+ parseFile,
100
+ callbacks,
101
+ convertBase64toBlob,
102
+ ) {
95
103
  return mediaContent.parseMediaMetadata(
96
104
  source,
97
105
  defaultMetadata,
98
106
  metadata,
99
107
  parseFile,
100
108
  callbacks,
109
+ convertBase64toBlob,
101
110
  TinyMediaPlayer.#unknownArtist,
102
111
  );
103
112
  }
@@ -1202,7 +1211,14 @@ class TinyMediaPlayer extends TinyDebugger {
1202
1211
  checkDestroy(this.#destroyed);
1203
1212
  this.log('info', `Attempting to play track at index: ${this.#currentIndex}`);
1204
1213
  const adapter = this.#getActiveAdapter();
1205
- if (!adapter) return;
1214
+ if (!adapter) {
1215
+ this.log(
1216
+ 'error',
1217
+ 'Failed to play track:',
1218
+ `Active adapter not found for track at index ${this.#currentIndex}.`,
1219
+ );
1220
+ return;
1221
+ }
1206
1222
 
1207
1223
  // Ensure the adapter aligns with the global volume before playing
1208
1224
  if (this.#smoothPlayPauseVolume) {
@@ -117,6 +117,7 @@ declare class TinyMediaPlayer extends TinyDebugger {
117
117
  * @param {Object} [callbacks={}] - Callbacks for monitoring the loading process.
118
118
  * @param {(progress: LoadingMediaProgress) => void} [callbacks.onProgress] - Callback triggered on stage changes.
119
119
  * @param {(error: MediaLoadingErrorData) => void} [callbacks.onError] - Callback triggered when a non-fatal or fatal error occurs.
120
+ * @param {boolean} [convertBase64toBlob=true] - If the image content needs to be converted directly into a high-performance Blob URL, use this method.
120
121
  * @returns {Promise<MediaContent>} A promise that resolves to a valid MediaContent object.
121
122
  * @throws {MediaLoadingError} If the preparation process fails at any stage.
122
123
  */
@@ -129,7 +130,7 @@ declare class TinyMediaPlayer extends TinyDebugger {
129
130
  }, parseFile?: ParseMediaContentMetadata, callbacks?: {
130
131
  onProgress?: (progress: LoadingMediaProgress) => void;
131
132
  onError?: (error: MediaLoadingErrorData) => void;
132
- }): Promise<MediaContent>;
133
+ }, convertBase64toBlob?: boolean): Promise<MediaContent>;
133
134
  get destroyed(): boolean;
134
135
  /** @returns {number} The duration (ms) of the volume fade speed. */
135
136
  get fadeVolumeSpeed(): number;
@@ -76,11 +76,12 @@ class TinyMediaPlayer extends TinyDebugger {
76
76
  * @param {Object} [callbacks={}] - Callbacks for monitoring the loading process.
77
77
  * @param {(progress: LoadingMediaProgress) => void} [callbacks.onProgress] - Callback triggered on stage changes.
78
78
  * @param {(error: MediaLoadingErrorData) => void} [callbacks.onError] - Callback triggered when a non-fatal or fatal error occurs.
79
+ * @param {boolean} [convertBase64toBlob=true] - If the image content needs to be converted directly into a high-performance Blob URL, use this method.
79
80
  * @returns {Promise<MediaContent>} A promise that resolves to a valid MediaContent object.
80
81
  * @throws {MediaLoadingError} If the preparation process fails at any stage.
81
82
  */
82
- static async parseContent(source, defaultMetadata, metadata, parseFile, callbacks) {
83
- return parseMediaMetadata(source, defaultMetadata, metadata, parseFile, callbacks, TinyMediaPlayer.#unknownArtist);
83
+ static async parseContent(source, defaultMetadata, metadata, parseFile, callbacks, convertBase64toBlob) {
84
+ return parseMediaMetadata(source, defaultMetadata, metadata, parseFile, callbacks, convertBase64toBlob, TinyMediaPlayer.#unknownArtist);
84
85
  }
85
86
  /** @type {boolean} */
86
87
  #destroyed = false;
@@ -1073,8 +1074,10 @@ class TinyMediaPlayer extends TinyDebugger {
1073
1074
  checkDestroy(this.#destroyed);
1074
1075
  this.log('info', `Attempting to play track at index: ${this.#currentIndex}`);
1075
1076
  const adapter = this.#getActiveAdapter();
1076
- if (!adapter)
1077
+ if (!adapter) {
1078
+ this.log('error', 'Failed to play track:', `Active adapter not found for track at index ${this.#currentIndex}.`);
1077
1079
  return;
1080
+ }
1078
1081
  // Ensure the adapter aligns with the global volume before playing
1079
1082
  if (this.#smoothPlayPauseVolume) {
1080
1083
  await this.#fadeAdapterVolume(this.#volume);
@@ -150,16 +150,25 @@ class TinyRadioFm extends events.EventEmitter {
150
150
  * @param {Object} [callbacks={}] - Callbacks for monitoring the loading process.
151
151
  * @param {(progress: LoadingMediaProgress) => void} [callbacks.onProgress] - Callback triggered on stage changes.
152
152
  * @param {(error: MediaLoadingErrorData) => void} [callbacks.onError] - Callback triggered when a non-fatal or fatal error occurs.
153
+ * @param {boolean} [convertBase64toBlob=true] - If the image content needs to be converted directly into a high-performance Blob URL, use this method.
153
154
  * @returns {Promise<MediaContent>} A promise that resolves to a valid MediaContent object.
154
155
  * @throws {MediaLoadingError} If the preparation process fails at any stage.
155
156
  */
156
- static async parseContent(source, defaultMetadata, metadata, parseFile, callbacks) {
157
+ static async parseContent(
158
+ source,
159
+ defaultMetadata,
160
+ metadata,
161
+ parseFile,
162
+ callbacks,
163
+ convertBase64toBlob,
164
+ ) {
157
165
  return mediaContent.parseMediaMetadata(
158
166
  source,
159
167
  defaultMetadata,
160
168
  metadata,
161
169
  parseFile,
162
170
  callbacks,
171
+ convertBase64toBlob,
163
172
  TinyRadioFm.#unknownArtist,
164
173
  );
165
174
  }
@@ -341,6 +341,7 @@ declare class TinyRadioFm extends EventEmitter {
341
341
  * @param {Object} [callbacks={}] - Callbacks for monitoring the loading process.
342
342
  * @param {(progress: LoadingMediaProgress) => void} [callbacks.onProgress] - Callback triggered on stage changes.
343
343
  * @param {(error: MediaLoadingErrorData) => void} [callbacks.onError] - Callback triggered when a non-fatal or fatal error occurs.
344
+ * @param {boolean} [convertBase64toBlob=true] - If the image content needs to be converted directly into a high-performance Blob URL, use this method.
344
345
  * @returns {Promise<MediaContent>} A promise that resolves to a valid MediaContent object.
345
346
  * @throws {MediaLoadingError} If the preparation process fails at any stage.
346
347
  */
@@ -353,7 +354,7 @@ declare class TinyRadioFm extends EventEmitter {
353
354
  }, parseFile?: ParseMediaContentMetadata, callbacks?: {
354
355
  onProgress?: (progress: LoadingMediaProgress) => void;
355
356
  onError?: (error: MediaLoadingErrorData) => void;
356
- }): Promise<MediaContent>;
357
+ }, convertBase64toBlob?: boolean): Promise<MediaContent>;
357
358
  /**
358
359
  * Gets the current value used to represent unknown artists.
359
360
  * @returns {UnknownArtistGetter}
@@ -128,11 +128,12 @@ class TinyRadioFm extends EventEmitter {
128
128
  * @param {Object} [callbacks={}] - Callbacks for monitoring the loading process.
129
129
  * @param {(progress: LoadingMediaProgress) => void} [callbacks.onProgress] - Callback triggered on stage changes.
130
130
  * @param {(error: MediaLoadingErrorData) => void} [callbacks.onError] - Callback triggered when a non-fatal or fatal error occurs.
131
+ * @param {boolean} [convertBase64toBlob=true] - If the image content needs to be converted directly into a high-performance Blob URL, use this method.
131
132
  * @returns {Promise<MediaContent>} A promise that resolves to a valid MediaContent object.
132
133
  * @throws {MediaLoadingError} If the preparation process fails at any stage.
133
134
  */
134
- static async parseContent(source, defaultMetadata, metadata, parseFile, callbacks) {
135
- return parseMediaMetadata(source, defaultMetadata, metadata, parseFile, callbacks, TinyRadioFm.#unknownArtist);
135
+ static async parseContent(source, defaultMetadata, metadata, parseFile, callbacks, convertBase64toBlob) {
136
+ return parseMediaMetadata(source, defaultMetadata, metadata, parseFile, callbacks, convertBase64toBlob, TinyRadioFm.#unknownArtist);
136
137
  }
137
138
  /**
138
139
  * @type {UnknownArtistGetter}
@@ -6,6 +6,7 @@ A versatile time utility module for JavaScript that helps you calculate and form
6
6
 
7
7
  - ๐Ÿ”ข Calculate time differences in various units
8
8
  - ๐Ÿงญ Format durations into clean, readable timer strings
9
+ - ๐ŸŒ Locale-aware time cycle detection (12h vs 24h)
9
10
  - ๐Ÿงฑ Support for years, months, days, hours, minutes, seconds **and milliseconds**
10
11
  - ๐ŸŽ›๏ธ Customizable output with template-based formatting
11
12
  - ๐Ÿ› ๏ธ Built-in presets for classic timer formats
@@ -15,6 +16,14 @@ A versatile time utility module for JavaScript that helps you calculate and form
15
16
 
16
17
  ## ๐Ÿง  API Overview
17
18
 
19
+ ### ๐Ÿ”น `getUserTimeFormat()`
20
+
21
+ Detects the user's preferred time format (12-hour or 24-hour) based on the system's locale settings.
22
+
23
+ **Returns:** `number` โ€” `12` if the user's locale uses a 12-hour cycle, otherwise `24`.
24
+
25
+ ---
26
+
18
27
  ### ๐Ÿ”น `getTimeDuration(timeData, durationType = 'asSeconds', now = null)`
19
28
 
20
29
  Calculates how much time remains (or has passed) between now and a given time.
@@ -25,7 +34,7 @@ Calculates how much time remains (or has passed) between now and a given time.
25
34
  | `durationType` | `string` | Format to return (`asMilliseconds`, `asSeconds`, `asMinutes`, etc.) |
26
35
  | `now` | `Date` | Optional custom "now". Defaults to current time. |
27
36
 
28
- **Returns:** `number|null` โ€” The duration in the chosen unit.
37
+ **Returns:** `number` โ€” The duration in the chosen unit.
29
38
 
30
39
  ---
31
40
 
@@ -93,15 +102,22 @@ This is useful when you want numeric values to build your own custom formats.
93
102
  ## ๐Ÿงช Examples
94
103
 
95
104
  ```js
105
+ // Detect user time preference
106
+ const timeFormat = getUserTimeFormat();
107
+ console.log(timeFormat); // 12 or 24
108
+
109
+ // Calculate remaining time
96
110
  const futureTime = new Date(Date.now() + 10000);
97
111
  const secondsLeft = getTimeDuration(futureTime, 'asSeconds');
98
112
 
99
113
  console.log(formatTimer(secondsLeft)); // e.g. "00:00:09"
100
114
  console.log(formatDayTimer(172800 + 3661)); // "2d 01:01:01"
101
115
 
116
+ // Custom formatting
102
117
  const custom = formatCustomTimer(3600 * 26 + 61, 'days', '{days}d {hours}h {minutes}m {seconds}s');
103
118
  console.log(custom); // "1d 2h 1m 1s"
104
119
 
120
+ // Detailed breakdown
105
121
  const breakdown = breakdownDuration(987654321, 'years');
106
122
  console.log(breakdown);
107
123
  // {
@@ -77,6 +77,7 @@ Downloads an audio file and uses a provided parser to extract its internal metad
77
77
  * **Parameters:**
78
78
  * `url` (string): The full URL of the audio file.
79
79
  * `parseFile` (Function): A callback that accepts a `Blob` and returns a promise with metadata.
80
+ * `convertBase64toBlob` (boolean): If true, the image content will be converted directly into a high-performance Blob URL, use this method.
80
81
  * **Returns:** `Promise<MediaContentMetadata>`
81
82
  * **Throws:** `TypeError` for invalid arguments or `Error` for network/parsing failures.
82
83
 
@@ -94,6 +95,7 @@ Downloads an audio file and uses a provided parser to extract its internal metad
94
95
  | `metadata` | `Partial<MediaContent>` | Manual overrides for the metadata (highest priority). |
95
96
  | `parseFile` | `ParseMediaContentMetadata` | The library function used to parse the file. |
96
97
  | `callbacks` | `Object` | Contains `onProgress` and `onError` listeners. |
98
+ | `convertBase64toBlob` | `boolean` | If true, the image content will be converted directly into a high-performance Blob URL, use this method.
97
99
  | `unknownArtist` | `UnknownArtistGetter` | Logic to determine the artist if none is found. |
98
100
 
99
101
  #### ๐Ÿ’ก Usage Examples
@@ -181,7 +181,7 @@ When initializing `new TinyMediaPlayer(options)`, you can pass the following `Ti
181
181
  * **Getter/Setter**: Allows customization of the default event subscription list.
182
182
 
183
183
  #### Methods
184
- * **`parseContent(source, defaultMetadata, metadata, parseFile, callbacks)`**:
184
+ * **`parseContent(source, defaultMetadata, metadata, parseFile, callbacks, convertBase64toBlob)`**:
185
185
  * A static factory method to prepare a `MediaContent` object by extracting metadata from a URL or HTMLMediaElement.
186
186
  * **Parameters**:
187
187
  * `source`: `string | HTMLMediaElement`
@@ -189,6 +189,7 @@ When initializing `new TinyMediaPlayer(options)`, you can pass the following `Ti
189
189
  * `metadata`: `Partial<MediaContentBase & MediaContentMetadata>`
190
190
  * `parseFile`: `ParseMediaContentMetadata`
191
191
  * `callbacks`: `Object` (containing `onProgress` and `onError`)
192
+ * `convertBase64toBlob`: `boolean`
192
193
  * **Returns**: `Promise<MediaContent>`.
193
194
 
194
195
  ---
@@ -42,7 +42,7 @@ The behavior of the engine is controlled via the `RadioConfig` object.
42
42
 
43
43
  ### ๐Ÿ—๏ธ Static Methods
44
44
 
45
- #### `static parseContent(source, defaultMetadata, metadata, parseFile, callbacks)`
45
+ #### `static parseContent(source, defaultMetadata, metadata, parseFile, callbacks, convertBase64toBlob)`
46
46
  Prepares a `MediaContent` object by extracting metadata from an audio source.
47
47
  * **Parameters:**
48
48
  * `source`: A URL string or an existing `HTMLMediaElement`.
@@ -50,6 +50,7 @@ Prepares a `MediaContent` object by extracting metadata from an audio source.
50
50
  * `metadata`: Optional manual overrides.
51
51
  * `parseFile`: Internal helper for file parsing.
52
52
  * `callbacks`: Object containing `onProgress` and `onError` handlers.
53
+ * `convertBase64toBlob`: If true, the image content will be converted directly into a high-performance Blob URL, use this method.
53
54
  * **Returns:** `Promise<MediaContent>`
54
55
  * **Throws:** `MediaLoadingError`
55
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiny-essentials",
3
- "version": "1.28.10",
3
+ "version": "1.28.12",
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"