tiny-essentials 1.28.0 → 1.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/changelog/1/28/1.md +23 -0
  2. package/dist/v1/TinyAdvancedRaffle.min.js +1 -1
  3. package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
  4. package/dist/v1/TinyAnalogClock.min.js +1 -1
  5. package/dist/v1/TinyBasicsEs.min.js +1 -1
  6. package/dist/v1/TinyDayNightCycle.min.js +1 -1
  7. package/dist/v1/TinyDragDropDetector.min.js +1 -1
  8. package/dist/v1/TinyDragger.min.js +1 -1
  9. package/dist/v1/TinyElementObserver.min.js +1 -1
  10. package/dist/v1/TinyEssentials.min.js +1 -1
  11. package/dist/v1/TinyGamepad.min.js +1 -1
  12. package/dist/v1/TinyHtml.min.js +1 -1
  13. package/dist/v1/TinyI18.min.js +1 -1
  14. package/dist/v1/TinyIframeEvents.min.js +1 -1
  15. package/dist/v1/TinyLocalStorage.min.js +1 -1
  16. package/dist/v1/TinyMediaPlayer.min.js +1 -1
  17. package/dist/v1/TinyNewWinEvents.min.js +1 -1
  18. package/dist/v1/TinyNotifyCenter.min.js +1 -1
  19. package/dist/v1/TinyRadioFm.min.js +1 -1
  20. package/dist/v1/TinyRateLimiter.min.js +1 -1
  21. package/dist/v1/TinySmartScroller.min.js +1 -1
  22. package/dist/v1/TinyTextDiffer.min.js +1 -1
  23. package/dist/v1/TinyTextarea.min.js +1 -1
  24. package/dist/v1/TinyTimeout.min.js +1 -1
  25. package/dist/v1/TinyToastNotify.min.js +1 -1
  26. package/dist/v1/TinyUploadClicker.min.js +1 -1
  27. package/dist/v1/UltraRandomMsgGen.min.js +1 -1
  28. package/dist/v1/basics/array.cjs +57 -9
  29. package/dist/v1/basics/array.d.mts +27 -11
  30. package/dist/v1/basics/array.mjs +51 -9
  31. package/dist/v1/basics/clock.cjs +94 -42
  32. package/dist/v1/basics/clock.d.mts +10 -10
  33. package/dist/v1/basics/clock.mjs +91 -54
  34. package/dist/v1/basics/deprecated/html.cjs +246 -0
  35. package/dist/v1/basics/deprecated/html.d.mts +63 -0
  36. package/dist/v1/basics/deprecated/html.mjs +190 -0
  37. package/dist/v1/basics/html.cjs +149 -130
  38. package/dist/v1/basics/html.d.mts +26 -61
  39. package/dist/v1/basics/html.mjs +113 -105
  40. package/dist/v1/basics/index.cjs +2 -0
  41. package/dist/v1/basics/index.d.mts +3 -1
  42. package/dist/v1/basics/index.mjs +3 -3
  43. package/dist/v1/basics/mediaContent.cjs +51 -9
  44. package/dist/v1/basics/mediaContent.d.mts +0 -87
  45. package/dist/v1/basics/mediaContent.mjs +40 -10
  46. package/dist/v1/basics/objChecker.cjs +7 -5
  47. package/dist/v1/basics/objChecker.d.mts +3 -2
  48. package/dist/v1/basics/objChecker.mjs +6 -6
  49. package/dist/v1/basics/objFilter.cjs +40 -7
  50. package/dist/v1/basics/objFilter.d.mts +6 -6
  51. package/dist/v1/basics/objFilter.mjs +32 -7
  52. package/dist/v1/basics/simpleMath.cjs +81 -25
  53. package/dist/v1/basics/simpleMath.d.mts +2 -2
  54. package/dist/v1/basics/simpleMath.mjs +70 -27
  55. package/dist/v1/basics/text.cjs +76 -31
  56. package/dist/v1/basics/text.d.mts +69 -7
  57. package/dist/v1/basics/text.mjs +62 -31
  58. package/dist/v1/index.cjs +4 -0
  59. package/dist/v1/index.d.mts +4 -1
  60. package/dist/v1/index.mjs +4 -3
  61. package/dist/v1/libs/TinyAdvancedRaffle.cjs +64 -50
  62. package/dist/v1/libs/TinyAdvancedRaffle.d.mts +4 -13
  63. package/dist/v1/libs/TinyAdvancedRaffle.mjs +62 -49
  64. package/dist/v1/libs/TinyAfterScrollWatcher.cjs +17 -1
  65. package/dist/v1/libs/TinyAfterScrollWatcher.d.mts +4 -1
  66. package/dist/v1/libs/TinyAfterScrollWatcher.mjs +15 -1
  67. package/dist/v1/libs/TinyAnalogClock.cjs +60 -0
  68. package/dist/v1/libs/TinyAnalogClock.d.mts +6 -0
  69. package/dist/v1/libs/TinyAnalogClock.mjs +57 -0
  70. package/dist/v1/libs/TinyClipboard.cjs +2 -0
  71. package/dist/v1/libs/TinyClipboard.d.mts +4 -2
  72. package/dist/v1/libs/TinyClipboard.mjs +2 -0
  73. package/dist/v1/libs/TinyColorConverter.cjs +1 -0
  74. package/dist/v1/libs/TinyColorConverter.d.mts +2 -1
  75. package/dist/v1/libs/TinyColorConverter.mjs +1 -0
  76. package/dist/v1/libs/TinyDayNightCycle.cjs +67 -42
  77. package/dist/v1/libs/TinyDayNightCycle.d.mts +2 -7
  78. package/dist/v1/libs/TinyDayNightCycle.mjs +65 -41
  79. package/dist/v1/libs/TinyDragDropDetector.cjs +25 -0
  80. package/dist/v1/libs/TinyDragDropDetector.d.mts +6 -0
  81. package/dist/v1/libs/TinyDragDropDetector.mjs +22 -0
  82. package/dist/v1/libs/TinyDragger.cjs +46 -19
  83. package/dist/v1/libs/TinyDragger.mjs +45 -18
  84. package/dist/v1/libs/TinyElementObserver.cjs +39 -0
  85. package/dist/v1/libs/TinyElementObserver.d.mts +6 -0
  86. package/dist/v1/libs/TinyElementObserver.mjs +36 -0
  87. package/dist/v1/libs/TinyGamepad.cjs +131 -1
  88. package/dist/v1/libs/TinyGamepad.mjs +129 -1
  89. package/dist/v1/libs/TinyHtml.cjs +1 -1
  90. package/dist/v1/libs/TinyHtml.mjs +2 -2
  91. package/dist/v1/libs/TinyI18.cjs +61 -0
  92. package/dist/v1/libs/TinyI18.d.mts +14 -0
  93. package/dist/v1/libs/TinyI18.mjs +55 -0
  94. package/dist/v1/libs/TinyIframeEvents.cjs +18 -1
  95. package/dist/v1/libs/TinyIframeEvents.mjs +18 -1
  96. package/dist/v1/libs/TinyLocalStorage.cjs +48 -0
  97. package/dist/v1/libs/TinyLocalStorage.d.mts +6 -0
  98. package/dist/v1/libs/TinyLocalStorage.mjs +45 -0
  99. package/dist/v1/libs/TinyMediaPlayer.cjs +72 -0
  100. package/dist/v1/libs/TinyMediaPlayer.d.mts +10 -0
  101. package/dist/v1/libs/TinyMediaPlayer.mjs +66 -0
  102. package/dist/v1/libs/TinyNewWinEvents.cjs +29 -0
  103. package/dist/v1/libs/TinyNewWinEvents.d.mts +6 -0
  104. package/dist/v1/libs/TinyNewWinEvents.mjs +26 -0
  105. package/dist/v1/libs/TinyNotifyCenter.cjs +36 -0
  106. package/dist/v1/libs/TinyNotifyCenter.d.mts +6 -0
  107. package/dist/v1/libs/TinyNotifyCenter.mjs +32 -0
  108. package/dist/v1/libs/TinyRadioFm.cjs +38 -0
  109. package/dist/v1/libs/TinyRadioFm.d.mts +1 -0
  110. package/dist/v1/libs/TinyRadioFm.mjs +35 -0
  111. package/dist/v1/libs/TinyRateLimiter.cjs +52 -0
  112. package/dist/v1/libs/TinyRateLimiter.d.mts +6 -0
  113. package/dist/v1/libs/TinyRateLimiter.mjs +48 -0
  114. package/dist/v1/libs/TinySmartScroller.cjs +52 -3
  115. package/dist/v1/libs/TinySmartScroller.d.mts +17 -15
  116. package/dist/v1/libs/TinySmartScroller.mjs +51 -5
  117. package/dist/v1/libs/TinyTextDiffer.cjs +19 -18
  118. package/dist/v1/libs/TinyTextDiffer.d.mts +1 -0
  119. package/dist/v1/libs/TinyTextDiffer.mjs +16 -17
  120. package/dist/v1/libs/TinyTextarea.cjs +19 -0
  121. package/dist/v1/libs/TinyTextarea.d.mts +6 -0
  122. package/dist/v1/libs/TinyTextarea.mjs +17 -0
  123. package/dist/v1/libs/TinyTimeout.cjs +11 -1
  124. package/dist/v1/libs/TinyTimeout.mjs +9 -1
  125. package/dist/v1/libs/TinyToastNotify.cjs +35 -0
  126. package/dist/v1/libs/TinyToastNotify.d.mts +6 -0
  127. package/dist/v1/libs/TinyToastNotify.mjs +31 -0
  128. package/dist/v1/libs/TinyUploadClicker.cjs +19 -0
  129. package/dist/v1/libs/TinyUploadClicker.d.mts +6 -0
  130. package/dist/v1/libs/TinyUploadClicker.mjs +17 -0
  131. package/dist/v1/libs/UltraRandomMsgGen.cjs +148 -35
  132. package/dist/v1/libs/UltraRandomMsgGen.d.mts +17 -3
  133. package/dist/v1/libs/UltraRandomMsgGen.mjs +133 -34
  134. package/dist/v1/libs/utils.cjs +21 -0
  135. package/dist/v1/libs/utils.d.mts +2 -0
  136. package/dist/v1/libs/utils.mjs +16 -0
  137. package/docs/v1/README.md +1 -0
  138. package/docs/v1/basics/array.md +2 -2
  139. package/docs/v1/basics/deprecated/html.md +17 -0
  140. package/docs/v1/basics/fullScreen.md +1 -1
  141. package/docs/v1/basics/html.md +12 -26
  142. package/docs/v1/basics/mediaContent.md +1 -1
  143. package/docs/v1/basics/objChecker.md +1 -1
  144. package/docs/v1/basics/text.md +2 -2
  145. package/docs/v1/fileManager/main.md +1 -1
  146. package/docs/v1/libs/ColorSafeStringify.md +1 -1
  147. package/docs/v1/libs/TinyAfterScrollWatcher.md +1 -1
  148. package/docs/v1/libs/TinyAnalogClock.md +1 -1
  149. package/docs/v1/libs/TinyArrayComparator.md +1 -1
  150. package/docs/v1/libs/TinyArrayPaginator.md +1 -1
  151. package/docs/v1/libs/TinyClassManager/TinyPluginInliner.md +2 -2
  152. package/docs/v1/libs/TinyClassManager.md +1 -1
  153. package/docs/v1/libs/TinyClipboard.md +1 -1
  154. package/docs/v1/libs/TinyCookieConsent.md +1 -1
  155. package/docs/v1/libs/TinyDomReadyManager.md +1 -1
  156. package/docs/v1/libs/TinyDragDropDetector.md +1 -1
  157. package/docs/v1/libs/TinyDragger.md +1 -1
  158. package/docs/v1/libs/TinyElementObserver.md +1 -1
  159. package/docs/v1/libs/TinyHtml.md +1 -1
  160. package/docs/v1/libs/TinyIframeEvents.md +2 -2
  161. package/docs/v1/libs/TinyLevelUp.md +1 -1
  162. package/docs/v1/libs/TinyLoadingScreen.md +1 -1
  163. package/docs/v1/libs/TinyNewWinEvents.md +2 -2
  164. package/docs/v1/libs/TinyNotifications.md +1 -1
  165. package/docs/v1/libs/TinyPromiseQueue.md +2 -2
  166. package/docs/v1/libs/TinyTextDiffer.md +1 -1
  167. package/docs/v1/libs/TinyTextarea.md +1 -1
  168. package/package.json +10 -1
@@ -2,31 +2,41 @@
2
2
  * Calculates the time duration between the current time and a given time offset.
3
3
  *
4
4
  * @param {Date} timeData - The target time as a Date object.
5
- * @param {string} [durationType='asSeconds'] - The type of duration to return. Can be 'asMilliseconds', 'asSeconds', 'asMinutes', 'asHours', 'asDays'.
5
+ * @param {'asMilliseconds'|'asSeconds'|'asMinutes'|'asHours'|'asDays'} [durationType='asSeconds'] - The type of duration to return.
6
6
  * @param {Date|null} [now=null] - The current time as a Date object. Defaults to the current date and time if not provided.
7
7
  * @returns {number|null} The calculated duration in the specified unit, or `null` if `timeData` is not provided.
8
8
  */
9
9
  export function getTimeDuration(timeData = new Date(), durationType = 'asSeconds', now = null) {
10
- if (timeData instanceof Date) {
11
- const currentTime = now instanceof Date ? now : new Date();
12
- /** @type {number} */
13
- const diffMs = timeData.getTime() - currentTime.getTime();
14
- switch (durationType) {
15
- case 'asMilliseconds':
16
- return diffMs;
17
- case 'asSeconds':
18
- return diffMs / 1000;
19
- case 'asMinutes':
20
- return diffMs / (1000 * 60);
21
- case 'asHours':
22
- return diffMs / (1000 * 60 * 60);
23
- case 'asDays':
24
- return diffMs / (1000 * 60 * 60 * 24);
25
- default:
26
- return diffMs / 1000; // default to seconds
27
- }
10
+ if (!(timeData instanceof Date)) {
11
+ throw new TypeError("The 'timeData' argument must be an instance of Date.");
12
+ }
13
+ if (typeof durationType !== 'string') {
14
+ throw new TypeError("The 'durationType' argument must be a string.");
15
+ }
16
+ const validDurationTypes = ['asMilliseconds', 'asSeconds', 'asMinutes', 'asHours', 'asDays'];
17
+ if (!validDurationTypes.includes(durationType)) {
18
+ throw new RangeError(`The 'durationType' must be one of: ${validDurationTypes.join(', ')}.`);
19
+ }
20
+ if (now !== null && !(now instanceof Date)) {
21
+ throw new TypeError("The 'now' argument must be an instance of Date or null.");
22
+ }
23
+ const currentTime = now instanceof Date ? now : new Date();
24
+ /** @type {number} */
25
+ const diffMs = timeData.getTime() - currentTime.getTime();
26
+ switch (durationType) {
27
+ case 'asMilliseconds':
28
+ return diffMs;
29
+ case 'asSeconds':
30
+ return diffMs / 1000;
31
+ case 'asMinutes':
32
+ return diffMs / (1000 * 60);
33
+ case 'asHours':
34
+ return diffMs / (1000 * 60 * 60);
35
+ case 'asDays':
36
+ return diffMs / (1000 * 60 * 60 * 24);
37
+ default:
38
+ return diffMs / 1000; // default to seconds
28
39
  }
29
- return null;
30
40
  }
31
41
  /**
32
42
  * Formats a custom timer string based on total seconds and a detail level.
@@ -38,8 +48,20 @@ export function getTimeDuration(timeData = new Date(), durationType = 'asSeconds
38
48
  * @returns {string} The formatted timer string.
39
49
  */
40
50
  export function formatCustomTimer(totalSeconds, level = 'seconds', format = '{time}') {
41
- totalSeconds = Math.max(0, Math.floor(totalSeconds));
51
+ if (typeof totalSeconds !== 'number' || Number.isNaN(totalSeconds)) {
52
+ throw new TypeError("The 'totalSeconds' argument must be a valid number.");
53
+ }
54
+ if (typeof level !== 'string') {
55
+ throw new TypeError("The 'level' argument must be a string.");
56
+ }
42
57
  const levels = ['seconds', 'minutes', 'hours', 'days', 'months', 'years'];
58
+ if (!levels.includes(level)) {
59
+ throw new RangeError(`The 'level' must be one of: ${levels.join(', ')}.`);
60
+ }
61
+ if (typeof format !== 'string') {
62
+ throw new TypeError("The 'format' argument must be a string.");
63
+ }
64
+ totalSeconds = Math.max(0, Math.floor(totalSeconds));
43
65
  const index = levels.indexOf(level);
44
66
  const include = {
45
67
  years: index >= 5,
@@ -51,13 +73,13 @@ export function formatCustomTimer(totalSeconds, level = 'seconds', format = '{ti
51
73
  };
52
74
  /**
53
75
  * @type {{
54
- * years: number|NaN,
55
- * months: number|NaN,
56
- * days: number|NaN,
57
- * hours: number|NaN,
58
- * minutes: number|NaN,
59
- * seconds: number|NaN,
60
- * total: number|NaN
76
+ * years: number|NaN,
77
+ * months: number|NaN,
78
+ * days: number|NaN,
79
+ * hours: number|NaN,
80
+ * minutes: number|NaN,
81
+ * seconds: number|NaN,
82
+ * total: number|NaN
61
83
  * }}
62
84
  */
63
85
  const parts = {
@@ -109,14 +131,14 @@ export function formatCustomTimer(totalSeconds, level = 'seconds', format = '{ti
109
131
  parts.seconds = remaining;
110
132
  }
111
133
  // Calculate total
112
- const totalMap = {
113
- seconds: include.seconds ? totalSeconds : NaN,
114
- minutes: include.minutes ? totalSeconds / 60 : NaN,
115
- hours: include.hours ? totalSeconds / 3600 : NaN,
116
- days: include.days ? totalSeconds / 86400 : NaN,
117
- months: include.months ? parts.years * 12 + parts.months + (parts.days || 0) / 30 : NaN,
118
- years: include.years ? parts.years + (parts.months || 0) / 12 + (parts.days || 0) / 365 : NaN,
119
- };
134
+ /** const totalMap = {
135
+ seconds: include.seconds ? totalSeconds : NaN,
136
+ minutes: include.minutes ? totalSeconds / 60 : NaN,
137
+ hours: include.hours ? totalSeconds / 3600 : NaN,
138
+ days: include.days ? totalSeconds / 86400 : NaN,
139
+ months: include.months ? parts.years * 12 + parts.months + (parts.days || 0) / 30 : NaN,
140
+ years: include.years ? parts.years + (parts.months || 0) / 12 + (parts.days || 0) / 365 : NaN,
141
+ }; */
120
142
  parts.total = +totalSeconds.toFixed(2).replace(/\.00$/, '');
121
143
  /**
122
144
  * Pads a number to ensure it is at least two digits long, using leading zeros if necessary.
@@ -155,6 +177,9 @@ export function formatCustomTimer(totalSeconds, level = 'seconds', format = '{ti
155
177
  * @returns {string} The formatted timer string in "HH:MM:SS" format.
156
178
  */
157
179
  export function formatTimer(seconds) {
180
+ if (typeof seconds !== 'number' || Number.isNaN(seconds)) {
181
+ throw new TypeError("The 'seconds' argument must be a valid number.");
182
+ }
158
183
  return formatCustomTimer(seconds, 'hours', '{hours}:{minutes}:{seconds}');
159
184
  }
160
185
  /**
@@ -166,6 +191,9 @@ export function formatTimer(seconds) {
166
191
  * @returns {string} The formatted timer string in "Xd HH:MM:SS" format.
167
192
  */
168
193
  export function formatDayTimer(seconds) {
194
+ if (typeof seconds !== 'number' || Number.isNaN(seconds)) {
195
+ throw new TypeError("The 'seconds' argument must be a valid number.");
196
+ }
169
197
  return formatCustomTimer(seconds, 'days', '{days}d {hours}:{minutes}:{seconds}');
170
198
  }
171
199
  /**
@@ -174,19 +202,28 @@ export function formatDayTimer(seconds) {
174
202
  * @param {number} totalMs - The total duration in milliseconds.
175
203
  * @param {'milliseconds'|'seconds'|'minutes'|'hours'|'days'|'months'|'years'} [level='milliseconds'] - The highest level to calculate and display.
176
204
  * @returns {{
177
- * years: number|NaN,
178
- * months: number|NaN,
179
- * days: number|NaN,
180
- * hours: number|NaN,
181
- * minutes: number|NaN,
182
- * seconds: number|NaN,
183
- * milliseconds: number|NaN,
184
- * total: number|NaN
205
+ * years: number|NaN,
206
+ * months: number|NaN,
207
+ * days: number|NaN,
208
+ * hours: number|NaN,
209
+ * minutes: number|NaN,
210
+ * seconds: number|NaN,
211
+ * milliseconds: number|NaN,
212
+ * total: number|NaN
185
213
  * }}
186
214
  */
187
215
  export function breakdownDuration(totalMs, level = 'milliseconds') {
188
- totalMs = Math.max(0, Math.floor(totalMs));
216
+ if (typeof totalMs !== 'number' || Number.isNaN(totalMs)) {
217
+ throw new TypeError("The 'totalMs' argument must be a valid number.");
218
+ }
219
+ if (typeof level !== 'string') {
220
+ throw new TypeError("The 'level' argument must be a string.");
221
+ }
189
222
  const levels = ['milliseconds', 'seconds', 'minutes', 'hours', 'days', 'months', 'years'];
223
+ if (!levels.includes(level)) {
224
+ throw new RangeError(`The 'level' must be one of: ${levels.join(', ')}.`);
225
+ }
226
+ totalMs = Math.max(0, Math.floor(totalMs));
190
227
  const index = levels.indexOf(level);
191
228
  const include = {
192
229
  years: index >= 6,
@@ -251,15 +288,15 @@ export function breakdownDuration(totalMs, level = 'milliseconds') {
251
288
  parts.milliseconds = remaining;
252
289
  }
253
290
  // Totals
254
- const totalMap = {
255
- milliseconds: include.milliseconds ? totalMs : NaN,
256
- seconds: include.seconds ? totalMs / 1000 : NaN,
257
- minutes: include.minutes ? totalMs / 60000 : NaN,
258
- hours: include.hours ? totalMs / 3600000 : NaN,
259
- days: include.days ? totalMs / 86400000 : NaN,
260
- months: include.months ? parts.years * 12 + parts.months + (parts.days || 0) / 30 : NaN,
261
- years: include.years ? parts.years + (parts.months || 0) / 12 + (parts.days || 0) / 365 : NaN,
262
- };
291
+ /** const totalMap = {
292
+ milliseconds: include.milliseconds ? totalMs : NaN,
293
+ seconds: include.seconds ? totalMs / 1000 : NaN,
294
+ minutes: include.minutes ? totalMs / 60000 : NaN,
295
+ hours: include.hours ? totalMs / 3600000 : NaN,
296
+ days: include.days ? totalMs / 86400000 : NaN,
297
+ months: include.months ? parts.years * 12 + parts.months + (parts.days || 0) / 30 : NaN,
298
+ years: include.years ? parts.years + (parts.months || 0) / 12 + (parts.days || 0) / 365 : NaN,
299
+ }; */
263
300
  parts.total = +totalMs;
264
301
  return parts;
265
302
  }
@@ -0,0 +1,246 @@
1
+ 'use strict';
2
+
3
+ var html = require('../html.cjs');
4
+ var objChecker = require('../objChecker.cjs');
5
+
6
+ /**
7
+ * @typedef {Object} FetchTemplateOptions
8
+ * @property {string} [method="GET"] - HTTP method to use (GET, POST, etc.).
9
+ * @property {any} [body] - Request body (only for methods like POST, PUT).
10
+ * @property {number} [timeout=0] - Timeout in milliseconds (ignored if signal is provided).
11
+ * @property {number} [retries=0] - Number of retry attempts (ignored if signal is provided).
12
+ * @property {Headers|Record<string, *>} [headers={}] - Additional headers.
13
+ * @property {AbortSignal|null} [signal] - External AbortSignal; disables timeout and retries.
14
+ * @property {import('../html.mjs').FetchOnProgressResult} [onProgress] - Track the load progress.
15
+ * @deprecated
16
+ */
17
+
18
+ /**
19
+ * @param {string} url - The full URL to fetch data from.
20
+ * @param {FetchTemplateOptions} [options] - Optional settings.
21
+ * @returns {Promise<Response>} Result data.
22
+ * @throws {Error} Throws if fetch fails, times out.
23
+ */
24
+ async function fetchTemplate(url, options = {}) {
25
+ if (options !== null && typeof options !== 'object') {
26
+ throw new TypeError('The "options" argument must be an object.');
27
+ }
28
+
29
+ const {
30
+ method = 'GET',
31
+ body,
32
+ timeout = 0,
33
+ retries = 0,
34
+ headers = {},
35
+ signal = null,
36
+ onProgress,
37
+ } = options;
38
+
39
+ if (
40
+ typeof url !== 'string' ||
41
+ (!url.startsWith('../') &&
42
+ !url.startsWith('./') &&
43
+ !url.startsWith('/') &&
44
+ !url.startsWith('https://') &&
45
+ !url.startsWith('http://'))
46
+ )
47
+ throw new Error('Invalid URL: must be a valid http or https address.');
48
+
49
+ if (typeof method !== 'string' || !method.trim())
50
+ throw new Error('Invalid method: must be a non-empty string.');
51
+
52
+ if (headers !== null && typeof headers !== 'object') {
53
+ throw new TypeError('The "headers" option must be an object.');
54
+ }
55
+
56
+ if (signal !== null && !(signal instanceof AbortSignal)) {
57
+ throw new TypeError('The "signal" option must be an instance of AbortSignal.');
58
+ }
59
+
60
+ if (onProgress !== undefined && typeof onProgress !== 'function') {
61
+ throw new TypeError('The "onProgress" option must be a function.');
62
+ }
63
+
64
+ if (!signal) {
65
+ if (
66
+ typeof timeout !== 'number' ||
67
+ !Number.isFinite(timeout) ||
68
+ Number.isNaN(timeout) ||
69
+ timeout < 0
70
+ )
71
+ throw new Error('Invalid timeout: must be a positive number.');
72
+
73
+ if (
74
+ typeof retries !== 'number' ||
75
+ !Number.isFinite(retries) ||
76
+ Number.isNaN(retries) ||
77
+ retries < 0
78
+ )
79
+ throw new Error('Invalid retries: must be a positive number.');
80
+ }
81
+
82
+ const attempts = signal ? 1 : retries + 1;
83
+ /** @type {Error|null} */
84
+ let lastError = null;
85
+
86
+ for (let attempt = 0; attempt < attempts; attempt++) {
87
+ const controller = signal ? null : new AbortController();
88
+ const localSignal = signal || (controller?.signal ?? null);
89
+ const timer =
90
+ !signal && timeout && controller ? setTimeout(() => controller.abort(), timeout) : null;
91
+
92
+ try {
93
+ const response = await fetch(url, {
94
+ method: method.toUpperCase(),
95
+ headers: {
96
+ Accept: 'application/json',
97
+ ...headers,
98
+ },
99
+ body: body !== undefined ? (objChecker.isJsonObject(body) ? JSON.stringify(body) : body) : undefined,
100
+ signal: localSignal,
101
+ });
102
+
103
+ if (timer) clearTimeout(timer);
104
+
105
+ if (!response.ok) throw new Error(`HTTP error: ${response.status} ${response.statusText}`);
106
+
107
+ // If onProgress is not provided or body is null, return original response
108
+ if (!onProgress) return response;
109
+ return html.trackFetchProgress(response, onProgress);
110
+ } catch (err) {
111
+ lastError = /** @type {Error} */ (err);
112
+ if (signal) break; // if an external signal came, it does not retry
113
+ if (attempt < retries)
114
+ await new Promise((resolve) => setTimeout(resolve, 300 * (attempt + 1)));
115
+ }
116
+ }
117
+
118
+ throw new Error(
119
+ `Failed to fetch JSON from "${url}"${lastError ? `: ${lastError.message}` : '.'}`,
120
+ );
121
+ }
122
+
123
+ /**
124
+ * Loads and parses a JSON from a remote URL using Fetch API.
125
+ *
126
+ * @param {string} url - The full URL to fetch JSON from.
127
+ * @param {FetchTemplateOptions} [options] - Optional settings.
128
+ * @returns {Promise<any[] | Record<string | number | symbol, unknown>>} Parsed JSON object.
129
+ * @throws {Error} Throws if fetch fails, times out, or returns invalid JSON.
130
+ * @deprecated
131
+ */
132
+ async function fetchJson(url, options) {
133
+ if (typeof url !== 'string') {
134
+ return Promise.reject(new TypeError('The "url" argument must be a string.'));
135
+ }
136
+ if (options !== undefined && (options === null || typeof options !== 'object')) {
137
+ return Promise.reject(new TypeError('The "options" argument must be an object.'));
138
+ }
139
+
140
+ return new Promise((resolve, reject) => {
141
+ fetchTemplate(url, options)
142
+ .then(async (res) => {
143
+ const contentType = res.headers.get('content-type') || '';
144
+ if (!contentType.includes('application/json'))
145
+ throw new Error(`Unexpected content-type: ${contentType}`);
146
+
147
+ const data = await res.json();
148
+
149
+ if (!Array.isArray(data) && !objChecker.isJsonObject(data))
150
+ throw new Error('Received invalid data instead of valid JSON.');
151
+
152
+ return resolve(data);
153
+ })
154
+ .catch(reject);
155
+ });
156
+ }
157
+
158
+ /**
159
+ * Loads a remote file as a Blob using Fetch API.
160
+ *
161
+ * @param {string} url - The full URL to fetch the file from.
162
+ * @param {string[]} [allowedMimeTypes] - Optional list of accepted MIME types (e.g., ['image/jpeg']).
163
+ * @param {FetchTemplateOptions} [options] - Optional fetch options.
164
+ * @returns {Promise<Blob>} - The fetched file as a Blob.
165
+ * @throws {Error} Throws if fetch fails, response is not ok, or MIME type is not allowed.
166
+ * @deprecated
167
+ */
168
+ async function fetchBlob(url, allowedMimeTypes, options) {
169
+ if (typeof url !== 'string') {
170
+ return Promise.reject(new TypeError('The "url" argument must be a string.'));
171
+ }
172
+ if (allowedMimeTypes !== undefined && !Array.isArray(allowedMimeTypes)) {
173
+ return Promise.reject(
174
+ new TypeError('The "allowedMimeTypes" argument must be an array of strings.'),
175
+ );
176
+ }
177
+ if (options !== undefined && (options === null || typeof options !== 'object')) {
178
+ return Promise.reject(new TypeError('The "options" argument must be an object.'));
179
+ }
180
+
181
+ return new Promise((resolve, reject) => {
182
+ fetchTemplate(url, options)
183
+ .then(async (res) => {
184
+ const contentType = res.headers.get('content-type') || '';
185
+
186
+ if (
187
+ Array.isArray(allowedMimeTypes) &&
188
+ allowedMimeTypes.length > 0 &&
189
+ !allowedMimeTypes.some((type) => contentType.includes(type))
190
+ ) {
191
+ throw new Error(`Blocked MIME type: ${contentType}`);
192
+ }
193
+
194
+ const data = await res.blob();
195
+ return resolve(data);
196
+ })
197
+ .catch(reject);
198
+ });
199
+ }
200
+
201
+ /**
202
+ * Loads a remote file as a text using Fetch API.
203
+ *
204
+ * @param {string} url - The full URL to fetch the file from.
205
+ * @param {string[]} [allowedMimeTypes] - Optional list of accepted MIME types (e.g., ['image/jpeg']).
206
+ * @param {FetchTemplateOptions} [options] - Optional fetch options.
207
+ * @returns {Promise<string>} - The fetched file as a text.
208
+ * @throws {Error} Throws if fetch fails, response is not ok, or MIME type is not allowed.
209
+ * @deprecated
210
+ */
211
+ async function fetchText(url, allowedMimeTypes, options) {
212
+ if (typeof url !== 'string') {
213
+ return Promise.reject(new TypeError('The "url" argument must be a string.'));
214
+ }
215
+ if (allowedMimeTypes !== undefined && !Array.isArray(allowedMimeTypes)) {
216
+ return Promise.reject(
217
+ new TypeError('The "allowedMimeTypes" argument must be an array of strings.'),
218
+ );
219
+ }
220
+ if (options !== undefined && (options === null || typeof options !== 'object')) {
221
+ return Promise.reject(new TypeError('The "options" argument must be an object.'));
222
+ }
223
+
224
+ return new Promise((resolve, reject) => {
225
+ fetchTemplate(url, options)
226
+ .then(async (res) => {
227
+ const contentType = res.headers.get('content-type') || '';
228
+
229
+ if (
230
+ Array.isArray(allowedMimeTypes) &&
231
+ allowedMimeTypes.length > 0 &&
232
+ !allowedMimeTypes.some((type) => contentType.includes(type))
233
+ ) {
234
+ throw new Error(`Blocked MIME type: ${contentType}`);
235
+ }
236
+
237
+ const data = await res.text();
238
+ return resolve(data);
239
+ })
240
+ .catch(reject);
241
+ });
242
+ }
243
+
244
+ exports.fetchBlob = fetchBlob;
245
+ exports.fetchJson = fetchJson;
246
+ exports.fetchText = fetchText;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Loads and parses a JSON from a remote URL using Fetch API.
3
+ *
4
+ * @param {string} url - The full URL to fetch JSON from.
5
+ * @param {FetchTemplateOptions} [options] - Optional settings.
6
+ * @returns {Promise<any[] | Record<string | number | symbol, unknown>>} Parsed JSON object.
7
+ * @throws {Error} Throws if fetch fails, times out, or returns invalid JSON.
8
+ * @deprecated
9
+ */
10
+ export function fetchJson(url: string, options?: FetchTemplateOptions): Promise<any[] | Record<string | number | symbol, unknown>>;
11
+ /**
12
+ * Loads a remote file as a Blob using Fetch API.
13
+ *
14
+ * @param {string} url - The full URL to fetch the file from.
15
+ * @param {string[]} [allowedMimeTypes] - Optional list of accepted MIME types (e.g., ['image/jpeg']).
16
+ * @param {FetchTemplateOptions} [options] - Optional fetch options.
17
+ * @returns {Promise<Blob>} - The fetched file as a Blob.
18
+ * @throws {Error} Throws if fetch fails, response is not ok, or MIME type is not allowed.
19
+ * @deprecated
20
+ */
21
+ export function fetchBlob(url: string, allowedMimeTypes?: string[], options?: FetchTemplateOptions): Promise<Blob>;
22
+ /**
23
+ * Loads a remote file as a text using Fetch API.
24
+ *
25
+ * @param {string} url - The full URL to fetch the file from.
26
+ * @param {string[]} [allowedMimeTypes] - Optional list of accepted MIME types (e.g., ['image/jpeg']).
27
+ * @param {FetchTemplateOptions} [options] - Optional fetch options.
28
+ * @returns {Promise<string>} - The fetched file as a text.
29
+ * @throws {Error} Throws if fetch fails, response is not ok, or MIME type is not allowed.
30
+ * @deprecated
31
+ */
32
+ export function fetchText(url: string, allowedMimeTypes?: string[], options?: FetchTemplateOptions): Promise<string>;
33
+ export type FetchTemplateOptions = {
34
+ /**
35
+ * - HTTP method to use (GET, POST, etc.).
36
+ */
37
+ method?: string | undefined;
38
+ /**
39
+ * - Request body (only for methods like POST, PUT).
40
+ */
41
+ body?: any;
42
+ /**
43
+ * - Timeout in milliseconds (ignored if signal is provided).
44
+ */
45
+ timeout?: number | undefined;
46
+ /**
47
+ * - Number of retry attempts (ignored if signal is provided).
48
+ */
49
+ retries?: number | undefined;
50
+ /**
51
+ * - Additional headers.
52
+ */
53
+ headers?: Headers | Record<string, any> | undefined;
54
+ /**
55
+ * - External AbortSignal; disables timeout and retries.
56
+ */
57
+ signal?: AbortSignal | null | undefined;
58
+ /**
59
+ * - Track the load progress.
60
+ */
61
+ onProgress?: import("../html.mjs").FetchOnProgressResult | undefined;
62
+ };
63
+ //# sourceMappingURL=html.d.mts.map