yummies 5.4.5 → 5.4.6

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 (516) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.github/FUNDING.yml +1 -0
  4. package/.github/workflows/main.yml +34 -0
  5. package/.github/workflows/version-or-publish.yml +45 -0
  6. package/.nvmrc +1 -0
  7. package/.vscode/settings.json +19 -0
  8. package/CHANGELOG.md +215 -0
  9. package/CONTRIBUTING.md +8 -0
  10. package/Makefile +7 -0
  11. package/assets/logo.png +0 -0
  12. package/assets/logo.pxz +0 -0
  13. package/biome.json +3 -0
  14. package/commitfmt.toml +18 -0
  15. package/lefthook.yml +14 -0
  16. package/package.json +3 -389
  17. package/scripts/post-build.ts +71 -0
  18. package/src/async.ts +86 -0
  19. package/src/common.ts +26 -0
  20. package/src/complex/counter.test.ts +41 -0
  21. package/src/complex/counter.ts +40 -0
  22. package/src/complex/global-config.ts +55 -0
  23. package/src/complex/index.ts +3 -0
  24. package/src/complex/modules-factory.ts +65 -0
  25. package/src/cookie.ts +11 -0
  26. package/src/css.ts +60 -0
  27. package/src/data.test.ts +99 -0
  28. package/src/data.ts +65 -0
  29. package/src/date-time.test.ts +119 -0
  30. package/src/date-time.ts +236 -0
  31. package/src/device.ts +42 -0
  32. package/src/encodings.ts +270 -0
  33. package/src/errors.ts +40 -0
  34. package/src/file.ts +25 -0
  35. package/src/format/_exports.ts +4 -0
  36. package/{dist/format/constants.js → src/format/constants.ts} +2 -0
  37. package/{dist/format/index.js → src/format/index.ts} +2 -1
  38. package/src/format/number.test.ts +16 -0
  39. package/src/format/number.ts +96 -0
  40. package/src/format/percent.ts +40 -0
  41. package/src/format/skip-spaces.ts +4 -0
  42. package/src/html.ts +238 -0
  43. package/{dist/id.js → src/id.ts} +16 -6
  44. package/src/imports.ts +52 -0
  45. package/src/math.ts +20 -0
  46. package/src/media.ts +134 -0
  47. package/src/mobx/apply-observable.ts +20 -0
  48. package/src/mobx/create-enhanced-atom.ts +28 -0
  49. package/src/mobx/deep-observable-struct.test.ts +69 -0
  50. package/src/mobx/deep-observable-struct.ts +69 -0
  51. package/src/mobx/get-mobx-administration.ts +10 -0
  52. package/src/mobx/index.ts +5 -0
  53. package/src/mobx/lazy-observe.ts +59 -0
  54. package/src/ms.ts +20 -0
  55. package/src/number.ts +14 -0
  56. package/src/parser/_exports.ts +3 -0
  57. package/{dist/parser/index.js → src/parser/index.ts} +2 -1
  58. package/src/parser/number.test.ts +38 -0
  59. package/src/parser/number.ts +73 -0
  60. package/src/parser/percent.ts +11 -0
  61. package/src/parser/string.ts +29 -0
  62. package/src/price.ts +33 -0
  63. package/src/random.ts +27 -0
  64. package/src/react/hooks/index.ts +21 -0
  65. package/src/react/hooks/use-abort-controller.ts +15 -0
  66. package/src/react/hooks/use-abort-signal.ts +5 -0
  67. package/src/react/hooks/use-click-outside.ts +27 -0
  68. package/{dist/react/hooks/use-constant.js → src/react/hooks/use-constant.ts} +9 -6
  69. package/{dist/react/hooks/use-define-ref.js → src/react/hooks/use-define-ref.ts} +10 -7
  70. package/src/react/hooks/use-element-ref.ts +11 -0
  71. package/src/react/hooks/use-event-listener.ts +29 -0
  72. package/src/react/hooks/use-event.ts +23 -0
  73. package/src/react/hooks/use-flag.ts +27 -0
  74. package/src/react/hooks/use-force-update.ts +9 -0
  75. package/src/react/hooks/use-initial-height.ts +16 -0
  76. package/{dist/react/hooks/use-instance.js → src/react/hooks/use-instance.ts} +31 -9
  77. package/src/react/hooks/use-intersection-observer.ts +18 -0
  78. package/src/react/hooks/use-last-defined-value.ts +9 -0
  79. package/src/react/hooks/use-last-value-ref.ts +11 -0
  80. package/src/react/hooks/use-life-cycle.ts +17 -0
  81. package/src/react/hooks/use-resize-observer.ts +14 -0
  82. package/src/react/hooks/use-sync-ref.ts +7 -0
  83. package/src/react/hooks/use-toggle.ts +9 -0
  84. package/src/react/hooks/use-value.ts +10 -0
  85. package/src/react/hooks/use-visibility-state.ts +19 -0
  86. package/src/react/index.ts +1 -0
  87. package/src/sound.ts +15 -0
  88. package/src/storage.ts +137 -0
  89. package/src/text.test.ts +91 -0
  90. package/src/text.ts +60 -0
  91. package/src/type-guard/_exports.ts +154 -0
  92. package/src/type-guard/index.test.ts +127 -0
  93. package/{dist/type-guard/index.js → src/type-guard/index.ts} +2 -1
  94. package/src/vibrate.ts +8 -0
  95. package/tsconfig.json +26 -0
  96. package/tsconfig.test.json +33 -0
  97. package/vitest.config.ts +20 -0
  98. package/dist/async.cjs +0 -70
  99. package/dist/async.d.cts +0 -28
  100. package/dist/async.d.cts.map +0 -1
  101. package/dist/async.d.ts +0 -28
  102. package/dist/async.d.ts.map +0 -1
  103. package/dist/async.js +0 -62
  104. package/dist/common.cjs +0 -18
  105. package/dist/common.d.cts +0 -15
  106. package/dist/common.d.cts.map +0 -1
  107. package/dist/common.d.ts +0 -15
  108. package/dist/common.d.ts.map +0 -1
  109. package/dist/common.js +0 -14
  110. package/dist/complex/counter.cjs +0 -21
  111. package/dist/complex/counter.d.cts +0 -15
  112. package/dist/complex/counter.d.cts.map +0 -1
  113. package/dist/complex/counter.d.ts +0 -15
  114. package/dist/complex/counter.d.ts.map +0 -1
  115. package/dist/complex/counter.js +0 -17
  116. package/dist/complex/global-config.cjs +0 -46
  117. package/dist/complex/global-config.d.cts +0 -11
  118. package/dist/complex/global-config.d.cts.map +0 -1
  119. package/dist/complex/global-config.d.ts +0 -11
  120. package/dist/complex/global-config.d.ts.map +0 -1
  121. package/dist/complex/global-config.js +0 -41
  122. package/dist/complex/index.cjs +0 -19
  123. package/dist/complex/index.d.cts +0 -4
  124. package/dist/complex/index.d.cts.map +0 -1
  125. package/dist/complex/index.d.ts +0 -4
  126. package/dist/complex/index.d.ts.map +0 -1
  127. package/dist/complex/index.js +0 -3
  128. package/dist/complex/modules-factory.cjs +0 -50
  129. package/dist/complex/modules-factory.d.cts +0 -49
  130. package/dist/complex/modules-factory.d.cts.map +0 -1
  131. package/dist/complex/modules-factory.d.ts +0 -49
  132. package/dist/complex/modules-factory.d.ts.map +0 -1
  133. package/dist/complex/modules-factory.js +0 -46
  134. package/dist/cookie.cjs +0 -13
  135. package/dist/cookie.d.cts +0 -3
  136. package/dist/cookie.d.cts.map +0 -1
  137. package/dist/cookie.d.ts +0 -3
  138. package/dist/cookie.d.ts.map +0 -1
  139. package/dist/cookie.js +0 -9
  140. package/dist/css.cjs +0 -28
  141. package/dist/css.d.cts +0 -36
  142. package/dist/css.d.cts.map +0 -1
  143. package/dist/css.d.ts +0 -36
  144. package/dist/css.d.ts.map +0 -1
  145. package/dist/css.js +0 -20
  146. package/dist/data.cjs +0 -58
  147. package/dist/data.d.cts +0 -4
  148. package/dist/data.d.cts.map +0 -1
  149. package/dist/data.d.ts +0 -4
  150. package/dist/data.d.ts.map +0 -1
  151. package/dist/data.js +0 -52
  152. package/dist/date-time.cjs +0 -171
  153. package/dist/date-time.d.cts +0 -28
  154. package/dist/date-time.d.cts.map +0 -1
  155. package/dist/date-time.d.ts +0 -28
  156. package/dist/date-time.d.ts.map +0 -1
  157. package/dist/date-time.js +0 -160
  158. package/dist/device.cjs +0 -28
  159. package/dist/device.d.cts +0 -8
  160. package/dist/device.d.cts.map +0 -1
  161. package/dist/device.d.ts +0 -8
  162. package/dist/device.d.ts.map +0 -1
  163. package/dist/device.js +0 -21
  164. package/dist/encodings.cjs +0 -270
  165. package/dist/encodings.d.cts +0 -2
  166. package/dist/encodings.d.cts.map +0 -1
  167. package/dist/encodings.d.ts +0 -2
  168. package/dist/encodings.d.ts.map +0 -1
  169. package/dist/encodings.js +0 -267
  170. package/dist/errors.cjs +0 -34
  171. package/dist/errors.d.cts +0 -19
  172. package/dist/errors.d.cts.map +0 -1
  173. package/dist/errors.d.ts +0 -19
  174. package/dist/errors.d.ts.map +0 -1
  175. package/dist/errors.js +0 -30
  176. package/dist/file.cjs +0 -29
  177. package/dist/file.d.cts +0 -3
  178. package/dist/file.d.cts.map +0 -1
  179. package/dist/file.d.ts +0 -3
  180. package/dist/file.d.ts.map +0 -1
  181. package/dist/file.js +0 -24
  182. package/dist/format/_exports.cjs +0 -20
  183. package/dist/format/_exports.d.cts +0 -5
  184. package/dist/format/_exports.d.cts.map +0 -1
  185. package/dist/format/_exports.d.ts +0 -5
  186. package/dist/format/_exports.d.ts.map +0 -1
  187. package/dist/format/_exports.js +0 -4
  188. package/dist/format/constants.cjs +0 -6
  189. package/dist/format/constants.d.cts +0 -4
  190. package/dist/format/constants.d.cts.map +0 -1
  191. package/dist/format/constants.d.ts +0 -4
  192. package/dist/format/constants.d.ts.map +0 -1
  193. package/dist/format/index.cjs +0 -40
  194. package/dist/format/index.d.cts +0 -3
  195. package/dist/format/index.d.cts.map +0 -1
  196. package/dist/format/index.d.ts +0 -3
  197. package/dist/format/index.d.ts.map +0 -1
  198. package/dist/format/number.cjs +0 -48
  199. package/dist/format/number.d.cts +0 -36
  200. package/dist/format/number.d.cts.map +0 -1
  201. package/dist/format/number.d.ts +0 -36
  202. package/dist/format/number.d.ts.map +0 -1
  203. package/dist/format/number.js +0 -44
  204. package/dist/format/percent.cjs +0 -27
  205. package/dist/format/percent.d.cts +0 -15
  206. package/dist/format/percent.d.cts.map +0 -1
  207. package/dist/format/percent.d.ts +0 -15
  208. package/dist/format/percent.d.ts.map +0 -1
  209. package/dist/format/percent.js +0 -23
  210. package/dist/format/skip-spaces.cjs +0 -8
  211. package/dist/format/skip-spaces.d.cts +0 -5
  212. package/dist/format/skip-spaces.d.cts.map +0 -1
  213. package/dist/format/skip-spaces.d.ts +0 -5
  214. package/dist/format/skip-spaces.d.ts.map +0 -1
  215. package/dist/format/skip-spaces.js +0 -4
  216. package/dist/html.cjs +0 -202
  217. package/dist/html.d.cts +0 -44
  218. package/dist/html.d.cts.map +0 -1
  219. package/dist/html.d.ts +0 -44
  220. package/dist/html.d.ts.map +0 -1
  221. package/dist/html.js +0 -182
  222. package/dist/id.cjs +0 -76
  223. package/dist/id.d.cts +0 -63
  224. package/dist/id.d.cts.map +0 -1
  225. package/dist/id.d.ts +0 -63
  226. package/dist/id.d.ts.map +0 -1
  227. package/dist/imports.cjs +0 -45
  228. package/dist/imports.d.cts +0 -15
  229. package/dist/imports.d.cts.map +0 -1
  230. package/dist/imports.d.ts +0 -15
  231. package/dist/imports.d.ts.map +0 -1
  232. package/dist/imports.js +0 -40
  233. package/dist/math.cjs +0 -23
  234. package/dist/math.d.cts +0 -13
  235. package/dist/math.d.cts.map +0 -1
  236. package/dist/math.d.ts +0 -13
  237. package/dist/math.d.ts.map +0 -1
  238. package/dist/math.js +0 -17
  239. package/dist/media.cjs +0 -115
  240. package/dist/media.d.cts +0 -20
  241. package/dist/media.d.cts.map +0 -1
  242. package/dist/media.d.ts +0 -20
  243. package/dist/media.d.ts.map +0 -1
  244. package/dist/media.js +0 -103
  245. package/dist/mobx/apply-observable.cjs +0 -16
  246. package/dist/mobx/apply-observable.d.cts +0 -4
  247. package/dist/mobx/apply-observable.d.cts.map +0 -1
  248. package/dist/mobx/apply-observable.d.ts +0 -4
  249. package/dist/mobx/apply-observable.d.ts.map +0 -1
  250. package/dist/mobx/apply-observable.js +0 -12
  251. package/dist/mobx/create-enhanced-atom.cjs +0 -16
  252. package/dist/mobx/create-enhanced-atom.d.cts +0 -11
  253. package/dist/mobx/create-enhanced-atom.d.cts.map +0 -1
  254. package/dist/mobx/create-enhanced-atom.d.ts +0 -11
  255. package/dist/mobx/create-enhanced-atom.d.ts.map +0 -1
  256. package/dist/mobx/create-enhanced-atom.js +0 -12
  257. package/dist/mobx/deep-observable-struct.cjs +0 -61
  258. package/dist/mobx/deep-observable-struct.d.cts +0 -7
  259. package/dist/mobx/deep-observable-struct.d.cts.map +0 -1
  260. package/dist/mobx/deep-observable-struct.d.ts +0 -7
  261. package/dist/mobx/deep-observable-struct.d.ts.map +0 -1
  262. package/dist/mobx/deep-observable-struct.js +0 -57
  263. package/dist/mobx/get-mobx-administration.cjs +0 -6
  264. package/dist/mobx/get-mobx-administration.d.cts +0 -6
  265. package/dist/mobx/get-mobx-administration.d.cts.map +0 -1
  266. package/dist/mobx/get-mobx-administration.d.ts +0 -6
  267. package/dist/mobx/get-mobx-administration.d.ts.map +0 -1
  268. package/dist/mobx/get-mobx-administration.js +0 -2
  269. package/dist/mobx/index.cjs +0 -21
  270. package/dist/mobx/index.d.cts +0 -6
  271. package/dist/mobx/index.d.cts.map +0 -1
  272. package/dist/mobx/index.d.ts +0 -6
  273. package/dist/mobx/index.d.ts.map +0 -1
  274. package/dist/mobx/index.js +0 -5
  275. package/dist/mobx/lazy-observe.cjs +0 -47
  276. package/dist/mobx/lazy-observe.d.cts +0 -8
  277. package/dist/mobx/lazy-observe.d.cts.map +0 -1
  278. package/dist/mobx/lazy-observe.d.ts +0 -8
  279. package/dist/mobx/lazy-observe.d.ts.map +0 -1
  280. package/dist/mobx/lazy-observe.js +0 -43
  281. package/dist/ms.cjs +0 -22
  282. package/dist/ms.d.cts +0 -19
  283. package/dist/ms.d.cts.map +0 -1
  284. package/dist/ms.d.ts +0 -19
  285. package/dist/ms.d.ts.map +0 -1
  286. package/dist/ms.js +0 -18
  287. package/dist/number.cjs +0 -16
  288. package/dist/number.d.cts +0 -8
  289. package/dist/number.d.cts.map +0 -1
  290. package/dist/number.d.ts +0 -8
  291. package/dist/number.d.ts.map +0 -1
  292. package/dist/number.js +0 -13
  293. package/dist/parser/_exports.cjs +0 -19
  294. package/dist/parser/_exports.d.cts +0 -4
  295. package/dist/parser/_exports.d.cts.map +0 -1
  296. package/dist/parser/_exports.d.ts +0 -4
  297. package/dist/parser/_exports.d.ts.map +0 -1
  298. package/dist/parser/_exports.js +0 -3
  299. package/dist/parser/index.cjs +0 -40
  300. package/dist/parser/index.d.cts +0 -3
  301. package/dist/parser/index.d.cts.map +0 -1
  302. package/dist/parser/index.d.ts +0 -3
  303. package/dist/parser/index.d.ts.map +0 -1
  304. package/dist/parser/number.cjs +0 -48
  305. package/dist/parser/number.d.cts +0 -21
  306. package/dist/parser/number.d.cts.map +0 -1
  307. package/dist/parser/number.d.ts +0 -21
  308. package/dist/parser/number.d.ts.map +0 -1
  309. package/dist/parser/number.js +0 -44
  310. package/dist/parser/percent.cjs +0 -8
  311. package/dist/parser/percent.d.cts +0 -4
  312. package/dist/parser/percent.d.cts.map +0 -1
  313. package/dist/parser/percent.d.ts +0 -4
  314. package/dist/parser/percent.d.ts.map +0 -1
  315. package/dist/parser/percent.js +0 -4
  316. package/dist/parser/string.cjs +0 -18
  317. package/dist/parser/string.d.cts +0 -7
  318. package/dist/parser/string.d.cts.map +0 -1
  319. package/dist/parser/string.d.ts +0 -7
  320. package/dist/parser/string.d.ts.map +0 -1
  321. package/dist/parser/string.js +0 -14
  322. package/dist/price.cjs +0 -21
  323. package/dist/price.d.cts +0 -6
  324. package/dist/price.d.cts.map +0 -1
  325. package/dist/price.d.ts +0 -6
  326. package/dist/price.d.ts.map +0 -1
  327. package/dist/price.js +0 -17
  328. package/dist/random.cjs +0 -25
  329. package/dist/random.d.cts +0 -9
  330. package/dist/random.d.cts.map +0 -1
  331. package/dist/random.d.ts +0 -9
  332. package/dist/random.d.ts.map +0 -1
  333. package/dist/random.js +0 -14
  334. package/dist/react/hooks/index.cjs +0 -37
  335. package/dist/react/hooks/index.d.cts +0 -22
  336. package/dist/react/hooks/index.d.cts.map +0 -1
  337. package/dist/react/hooks/index.d.ts +0 -22
  338. package/dist/react/hooks/index.d.ts.map +0 -1
  339. package/dist/react/hooks/index.js +0 -21
  340. package/dist/react/hooks/use-abort-controller.cjs +0 -15
  341. package/dist/react/hooks/use-abort-controller.d.cts +0 -2
  342. package/dist/react/hooks/use-abort-controller.d.cts.map +0 -1
  343. package/dist/react/hooks/use-abort-controller.d.ts +0 -2
  344. package/dist/react/hooks/use-abort-controller.d.ts.map +0 -1
  345. package/dist/react/hooks/use-abort-controller.js +0 -11
  346. package/dist/react/hooks/use-abort-signal.cjs +0 -8
  347. package/dist/react/hooks/use-abort-signal.d.cts +0 -2
  348. package/dist/react/hooks/use-abort-signal.d.cts.map +0 -1
  349. package/dist/react/hooks/use-abort-signal.d.ts +0 -2
  350. package/dist/react/hooks/use-abort-signal.d.ts.map +0 -1
  351. package/dist/react/hooks/use-abort-signal.js +0 -4
  352. package/dist/react/hooks/use-click-outside.cjs +0 -17
  353. package/dist/react/hooks/use-click-outside.d.cts +0 -9
  354. package/dist/react/hooks/use-click-outside.d.cts.map +0 -1
  355. package/dist/react/hooks/use-click-outside.d.ts +0 -9
  356. package/dist/react/hooks/use-click-outside.d.ts.map +0 -1
  357. package/dist/react/hooks/use-click-outside.js +0 -13
  358. package/dist/react/hooks/use-constant.cjs +0 -19
  359. package/dist/react/hooks/use-constant.d.cts +0 -9
  360. package/dist/react/hooks/use-constant.d.cts.map +0 -1
  361. package/dist/react/hooks/use-constant.d.ts +0 -9
  362. package/dist/react/hooks/use-constant.d.ts.map +0 -1
  363. package/dist/react/hooks/use-define-ref.cjs +0 -19
  364. package/dist/react/hooks/use-define-ref.d.cts +0 -10
  365. package/dist/react/hooks/use-define-ref.d.cts.map +0 -1
  366. package/dist/react/hooks/use-define-ref.d.ts +0 -10
  367. package/dist/react/hooks/use-define-ref.d.ts.map +0 -1
  368. package/dist/react/hooks/use-element-ref.cjs +0 -12
  369. package/dist/react/hooks/use-element-ref.d.cts +0 -2
  370. package/dist/react/hooks/use-element-ref.d.cts.map +0 -1
  371. package/dist/react/hooks/use-element-ref.d.ts +0 -2
  372. package/dist/react/hooks/use-element-ref.d.ts.map +0 -1
  373. package/dist/react/hooks/use-element-ref.js +0 -8
  374. package/dist/react/hooks/use-event-listener.cjs +0 -17
  375. package/dist/react/hooks/use-event-listener.d.cts +0 -8
  376. package/dist/react/hooks/use-event-listener.d.cts.map +0 -1
  377. package/dist/react/hooks/use-event-listener.d.ts +0 -8
  378. package/dist/react/hooks/use-event-listener.d.ts.map +0 -1
  379. package/dist/react/hooks/use-event-listener.js +0 -13
  380. package/dist/react/hooks/use-event.cjs +0 -23
  381. package/dist/react/hooks/use-event.d.cts +0 -3
  382. package/dist/react/hooks/use-event.d.cts.map +0 -1
  383. package/dist/react/hooks/use-event.d.ts +0 -3
  384. package/dist/react/hooks/use-event.d.ts.map +0 -1
  385. package/dist/react/hooks/use-event.js +0 -19
  386. package/dist/react/hooks/use-flag.cjs +0 -19
  387. package/dist/react/hooks/use-flag.d.cts +0 -8
  388. package/dist/react/hooks/use-flag.d.cts.map +0 -1
  389. package/dist/react/hooks/use-flag.d.ts +0 -8
  390. package/dist/react/hooks/use-flag.d.ts.map +0 -1
  391. package/dist/react/hooks/use-flag.js +0 -15
  392. package/dist/react/hooks/use-force-update.cjs +0 -11
  393. package/dist/react/hooks/use-force-update.d.cts +0 -2
  394. package/dist/react/hooks/use-force-update.d.cts.map +0 -1
  395. package/dist/react/hooks/use-force-update.d.ts +0 -2
  396. package/dist/react/hooks/use-force-update.d.ts.map +0 -1
  397. package/dist/react/hooks/use-force-update.js +0 -7
  398. package/dist/react/hooks/use-initial-height.cjs +0 -15
  399. package/dist/react/hooks/use-initial-height.d.cts +0 -5
  400. package/dist/react/hooks/use-initial-height.d.cts.map +0 -1
  401. package/dist/react/hooks/use-initial-height.d.ts +0 -5
  402. package/dist/react/hooks/use-initial-height.d.ts.map +0 -1
  403. package/dist/react/hooks/use-initial-height.js +0 -11
  404. package/dist/react/hooks/use-instance.cjs +0 -31
  405. package/dist/react/hooks/use-instance.d.cts +0 -27
  406. package/dist/react/hooks/use-instance.d.cts.map +0 -1
  407. package/dist/react/hooks/use-instance.d.ts +0 -27
  408. package/dist/react/hooks/use-instance.d.ts.map +0 -1
  409. package/dist/react/hooks/use-intersection-observer.cjs +0 -14
  410. package/dist/react/hooks/use-intersection-observer.d.cts +0 -2
  411. package/dist/react/hooks/use-intersection-observer.d.cts.map +0 -1
  412. package/dist/react/hooks/use-intersection-observer.d.ts +0 -2
  413. package/dist/react/hooks/use-intersection-observer.d.ts.map +0 -1
  414. package/dist/react/hooks/use-intersection-observer.js +0 -10
  415. package/dist/react/hooks/use-last-defined-value.cjs +0 -12
  416. package/dist/react/hooks/use-last-defined-value.d.cts +0 -2
  417. package/dist/react/hooks/use-last-defined-value.d.cts.map +0 -1
  418. package/dist/react/hooks/use-last-defined-value.d.ts +0 -2
  419. package/dist/react/hooks/use-last-defined-value.d.ts.map +0 -1
  420. package/dist/react/hooks/use-last-defined-value.js +0 -8
  421. package/dist/react/hooks/use-last-value-ref.cjs +0 -12
  422. package/dist/react/hooks/use-last-value-ref.d.cts +0 -2
  423. package/dist/react/hooks/use-last-value-ref.d.cts.map +0 -1
  424. package/dist/react/hooks/use-last-value-ref.d.ts +0 -2
  425. package/dist/react/hooks/use-last-value-ref.d.ts.map +0 -1
  426. package/dist/react/hooks/use-last-value-ref.js +0 -8
  427. package/dist/react/hooks/use-life-cycle.cjs +0 -14
  428. package/dist/react/hooks/use-life-cycle.d.cts +0 -5
  429. package/dist/react/hooks/use-life-cycle.d.cts.map +0 -1
  430. package/dist/react/hooks/use-life-cycle.d.ts +0 -5
  431. package/dist/react/hooks/use-life-cycle.d.ts.map +0 -1
  432. package/dist/react/hooks/use-life-cycle.js +0 -10
  433. package/dist/react/hooks/use-resize-observer.cjs +0 -15
  434. package/dist/react/hooks/use-resize-observer.d.cts +0 -2
  435. package/dist/react/hooks/use-resize-observer.d.cts.map +0 -1
  436. package/dist/react/hooks/use-resize-observer.d.ts +0 -2
  437. package/dist/react/hooks/use-resize-observer.d.ts.map +0 -1
  438. package/dist/react/hooks/use-resize-observer.js +0 -11
  439. package/dist/react/hooks/use-sync-ref.cjs +0 -10
  440. package/dist/react/hooks/use-sync-ref.d.cts +0 -2
  441. package/dist/react/hooks/use-sync-ref.d.cts.map +0 -1
  442. package/dist/react/hooks/use-sync-ref.d.ts +0 -2
  443. package/dist/react/hooks/use-sync-ref.d.ts.map +0 -1
  444. package/dist/react/hooks/use-sync-ref.js +0 -6
  445. package/dist/react/hooks/use-toggle.cjs +0 -10
  446. package/dist/react/hooks/use-toggle.d.cts +0 -2
  447. package/dist/react/hooks/use-toggle.d.cts.map +0 -1
  448. package/dist/react/hooks/use-toggle.d.ts +0 -2
  449. package/dist/react/hooks/use-toggle.d.ts.map +0 -1
  450. package/dist/react/hooks/use-toggle.js +0 -6
  451. package/dist/react/hooks/use-value.cjs +0 -12
  452. package/dist/react/hooks/use-value.d.cts +0 -5
  453. package/dist/react/hooks/use-value.d.cts.map +0 -1
  454. package/dist/react/hooks/use-value.d.ts +0 -5
  455. package/dist/react/hooks/use-value.d.ts.map +0 -1
  456. package/dist/react/hooks/use-value.js +0 -8
  457. package/dist/react/hooks/use-visibility-state.cjs +0 -18
  458. package/dist/react/hooks/use-visibility-state.d.cts +0 -2
  459. package/dist/react/hooks/use-visibility-state.d.cts.map +0 -1
  460. package/dist/react/hooks/use-visibility-state.d.ts +0 -2
  461. package/dist/react/hooks/use-visibility-state.d.ts.map +0 -1
  462. package/dist/react/hooks/use-visibility-state.js +0 -14
  463. package/dist/react/index.cjs +0 -17
  464. package/dist/react/index.d.cts +0 -2
  465. package/dist/react/index.d.cts.map +0 -1
  466. package/dist/react/index.d.ts +0 -2
  467. package/dist/react/index.d.ts.map +0 -1
  468. package/dist/react/index.js +0 -1
  469. package/dist/sound.cjs +0 -16
  470. package/dist/sound.d.cts +0 -7
  471. package/dist/sound.d.cts.map +0 -1
  472. package/dist/sound.d.ts +0 -7
  473. package/dist/sound.d.ts.map +0 -1
  474. package/dist/sound.js +0 -12
  475. package/dist/storage.cjs +0 -48
  476. package/dist/storage.d.cts +0 -39
  477. package/dist/storage.d.cts.map +0 -1
  478. package/dist/storage.d.ts +0 -39
  479. package/dist/storage.d.ts.map +0 -1
  480. package/dist/storage.js +0 -43
  481. package/dist/text.cjs +0 -53
  482. package/dist/text.d.cts +0 -15
  483. package/dist/text.d.cts.map +0 -1
  484. package/dist/text.d.ts +0 -15
  485. package/dist/text.d.ts.map +0 -1
  486. package/dist/text.js +0 -48
  487. package/dist/type-guard/_exports.cjs +0 -129
  488. package/dist/type-guard/_exports.d.cts +0 -86
  489. package/dist/type-guard/_exports.d.cts.map +0 -1
  490. package/dist/type-guard/_exports.d.ts +0 -86
  491. package/dist/type-guard/_exports.d.ts.map +0 -1
  492. package/dist/type-guard/_exports.js +0 -125
  493. package/dist/type-guard/index.cjs +0 -40
  494. package/dist/type-guard/index.d.cts +0 -3
  495. package/dist/type-guard/index.d.cts.map +0 -1
  496. package/dist/type-guard/index.d.ts +0 -3
  497. package/dist/type-guard/index.d.ts.map +0 -1
  498. package/dist/utils/types.cjs +0 -2
  499. package/dist/utils/types.d.cts +0 -395
  500. package/dist/utils/types.d.cts.map +0 -1
  501. package/dist/utils/types.d.ts +0 -395
  502. package/dist/utils/types.d.ts.map +0 -1
  503. package/dist/utils/types.js +0 -1
  504. package/dist/vibrate.cjs +0 -12
  505. package/dist/vibrate.d.cts +0 -5
  506. package/dist/vibrate.d.cts.map +0 -1
  507. package/dist/vibrate.d.ts +0 -5
  508. package/dist/vibrate.d.ts.map +0 -1
  509. package/dist/vibrate.js +0 -8
  510. package/utility-types.d.ts +0 -395
  511. package/utils/types.cjs +0 -2
  512. package/utils/types.d.cts +0 -395
  513. package/utils/types.d.cts.map +0 -1
  514. package/utils/types.d.ts +0 -395
  515. package/utils/types.d.ts.map +0 -1
  516. package/utils/types.js +0 -1
@@ -0,0 +1,96 @@
1
+ import { number as toNumber } from '../parser/number.js';
2
+ import { typeGuard } from '../type-guard/index.js';
3
+ import type { Maybe } from '../utils/types.js';
4
+
5
+ import { NO_VALUE } from './constants.js';
6
+
7
+ export interface NumberFormatSettings {
8
+ delimiter?: string;
9
+ /**
10
+ * digitsOnlyForFloat - Show digits after decimal point only if they are not zeros after converting to number.
11
+ * Example: "0.00" -> "0", "0.10" -> "0.1", but "0.003" -> "0.003"
12
+ *
13
+ * @default true
14
+ */
15
+ digitsOnlyForFloat?: boolean;
16
+ /**
17
+ * Text which will be returned if the value is undefined, null, NaN, Infinity or empty string.
18
+ * Example: "–" will be returned if the value is undefined and emptyText is "–".
19
+ */
20
+ emptyText?: string;
21
+ /**
22
+ * Text to append to the end of the formatted number.
23
+ * Example: if value is 1000 and postfix is "₽", result will be "1 000₽".
24
+ */
25
+ postfix?: string;
26
+ /**
27
+ * Fixed number of digits after the decimal point (number.toFixed() method)
28
+ * If set to false, the truncation is ignored!
29
+ */
30
+ digits?: number | false;
31
+ /**
32
+ * Remove trailing zeros from the end of the number
33
+ * Example: 0.010000000000000000000000000000000000000000000 -> 0.01
34
+ */
35
+ cutZeros?: boolean;
36
+ }
37
+
38
+ export const number = (
39
+ rawValue: Maybe<string | number>,
40
+ userSettings?: Maybe<NumberFormatSettings>,
41
+ ): string => {
42
+ const settings = {
43
+ ...number.defaultSettings,
44
+ ...userSettings,
45
+ };
46
+
47
+ const digits = settings.digits ?? 0;
48
+ const cutZeros = settings?.cutZeros ?? false;
49
+ const delimiter = settings.delimiter ?? ' ';
50
+ const postfix = settings.postfix ?? '';
51
+ const emptyText = settings.emptyText ?? NO_VALUE;
52
+ const digitsOnlyForFloat = settings.digitsOnlyForFloat ?? true;
53
+
54
+ let value: Maybe<number>;
55
+
56
+ if (typeGuard.isString(rawValue)) {
57
+ value = toNumber(value, { fallback: undefined });
58
+ } else {
59
+ value = rawValue;
60
+ }
61
+
62
+ if (typeGuard.isNumber(value)) {
63
+ let raw: string = `${value}`;
64
+
65
+ if (digits !== false) {
66
+ raw = value.toFixed(digits);
67
+ }
68
+ if (cutZeros) {
69
+ raw = `${+raw}`;
70
+ }
71
+
72
+ const [integerPart, decimalPart] = raw.split('.', 2);
73
+
74
+ let formattedIntegerPart = integerPart;
75
+ let formattedDecimalPart = '';
76
+
77
+ if (decimalPart && (!digitsOnlyForFloat || !/^0+$/.test(decimalPart))) {
78
+ formattedDecimalPart = `.${decimalPart}`;
79
+ }
80
+
81
+ const rgx = /(\d+)(\d{3})/;
82
+
83
+ while (rgx.test(formattedIntegerPart) && delimiter) {
84
+ formattedIntegerPart = formattedIntegerPart.replace(
85
+ rgx,
86
+ `$1${delimiter}$2`,
87
+ );
88
+ }
89
+
90
+ return formattedIntegerPart + formattedDecimalPart + postfix;
91
+ }
92
+
93
+ return emptyText;
94
+ };
95
+
96
+ number.defaultSettings = {} as NumberFormatSettings;
@@ -0,0 +1,40 @@
1
+ import { type NumberParserSettings, number } from '../parser/number.js';
2
+ import { typeGuard } from '../type-guard/index.js';
3
+ import type { Maybe } from '../utils/types.js';
4
+
5
+ import { NO_VALUE } from './constants.js';
6
+
7
+ export interface PercentFormatSettings
8
+ extends Omit<NumberParserSettings, 'fallback'> {
9
+ divider?: string;
10
+ delimiter?: string;
11
+ symbol?: string;
12
+ emptyText?: string;
13
+ }
14
+
15
+ /**
16
+ * 100 -> 100%
17
+ * 99.123214412 -> 99.12%
18
+ * 99.123214412 -> 99,12%
19
+ */
20
+ export const percent = (
21
+ value: Maybe<number | string>,
22
+ settings?: PercentFormatSettings,
23
+ ) => {
24
+ const numericValue = number(value, {
25
+ ...settings,
26
+ digits: settings?.digits ?? 2,
27
+ fallback: Number.NaN,
28
+ });
29
+
30
+ if (typeGuard.isNumber(numericValue)) {
31
+ const divider = settings?.divider ?? '.';
32
+
33
+ const formattedPercent =
34
+ divider === '.' ? numericValue : `${numericValue}`.replace('.', divider);
35
+
36
+ return `${formattedPercent}${settings?.delimiter ?? ''}${settings?.symbol ?? '%'}`;
37
+ } else {
38
+ return settings?.emptyText ?? NO_VALUE;
39
+ }
40
+ };
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Removes all spaces in string
3
+ */
4
+ export const skipSpaces = (value: string) => value.replaceAll(/\s/g, '');
package/src/html.ts ADDED
@@ -0,0 +1,238 @@
1
+ import DOMPurify, { type Config as DOMPurifyConfig } from 'dompurify';
2
+
3
+ import { blobToUrl } from './media.js';
4
+ import type { Maybe } from './utils/types.js';
5
+
6
+ /**
7
+ * Вытаскивает RGB из любого цвета
8
+ *
9
+ * Не рекомендуется к использованию так как вызывает reflow
10
+ */
11
+ export const getComputedColor = (color?: string): string | null => {
12
+ if (!color) return null;
13
+
14
+ const d = document.createElement('div');
15
+ d.style.color = color;
16
+ document.body.append(d);
17
+ const rgbcolor = globalThis.getComputedStyle(d).color;
18
+ const match =
19
+ /rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*\d+[.d+]*)*\)/g.exec(rgbcolor);
20
+
21
+ d.remove();
22
+
23
+ if (!match) return null;
24
+
25
+ return `${match[1]}, ${match[2]}, ${match[3]}`;
26
+ };
27
+
28
+ export const downloadUsingAnchor = (
29
+ urlOrBlob: string | Blob,
30
+ fileName?: string,
31
+ ) => {
32
+ const url = blobToUrl(urlOrBlob);
33
+
34
+ const a = document.createElement('a');
35
+ a.href = url;
36
+
37
+ a.download = fileName ?? 'file';
38
+
39
+ a.target = '_blank';
40
+
41
+ document.body.append(a);
42
+
43
+ a.click();
44
+
45
+ a.remove();
46
+ };
47
+
48
+ /**
49
+ * Surrounds string in an anchor tag
50
+ */
51
+ export function wrapTextToTagLink(link: string) {
52
+ const descr = String(link).replace(/^(https?:\/{0,2})?(w{3}\.)?/, 'www.');
53
+ if (!/^https?:\/{2}/.test(link)) link = `http://${link}`;
54
+ return `<a href=${link} target="_blank">${descr}</a>`;
55
+ }
56
+
57
+ export const collectOffsetTop = (element: HTMLElement | null) => {
58
+ let offsetTop = 0;
59
+ let node = element;
60
+
61
+ while (node != null) {
62
+ offsetTop += node.offsetTop;
63
+ node = node.parentElement;
64
+ }
65
+
66
+ return offsetTop;
67
+ };
68
+
69
+ export const skipEvent = (e: Event) => {
70
+ e.preventDefault();
71
+ e.stopPropagation();
72
+
73
+ return false;
74
+ };
75
+
76
+ export const globalScrollIntoViewForY = (node: HTMLElement) => {
77
+ const scrollContainer = document.body;
78
+ const pageHeight = window.innerHeight;
79
+ const nodeBounding = node.getBoundingClientRect();
80
+ const scrollPagesCount = scrollContainer.scrollHeight / pageHeight;
81
+
82
+ const scrollPageNumber = Math.min(
83
+ Math.max(nodeBounding.top / pageHeight, 1),
84
+ scrollPagesCount,
85
+ );
86
+
87
+ window.scroll({
88
+ top: scrollPageNumber * pageHeight,
89
+ behavior: 'smooth',
90
+ });
91
+ };
92
+
93
+ const sanitizeDefaults: DOMPurifyConfig = {
94
+ ALLOWED_TAGS: [
95
+ 'a',
96
+ 'article',
97
+ 'b',
98
+ 'blockquote',
99
+ 'br',
100
+ 'caption',
101
+ 'code',
102
+ 'del',
103
+ 'details',
104
+ 'div',
105
+ 'em',
106
+ 'h1',
107
+ 'h2',
108
+ 'h3',
109
+ 'h4',
110
+ 'h5',
111
+ 'h6',
112
+ 'hr',
113
+ 'i',
114
+ 'img',
115
+ 'ins',
116
+ 'kbd',
117
+ 'li',
118
+ 'main',
119
+ 'ol',
120
+ 'p',
121
+ 'pre',
122
+ 'section',
123
+ 'span',
124
+ 'strong',
125
+ 'sub',
126
+ 'summary',
127
+ 'sup',
128
+ 'table',
129
+ 'tbody',
130
+ 'td',
131
+ 'th',
132
+ 'thead',
133
+ 'tr',
134
+ 'u',
135
+ 'ul',
136
+ ],
137
+ ALLOWED_ATTR: ['href', 'target', 'name', 'src', 'class'],
138
+ };
139
+
140
+ export const sanitizeHtml = (html: Maybe<string>, config?: DOMPurifyConfig) => {
141
+ return DOMPurify.sanitize(html || '', {
142
+ ...sanitizeDefaults,
143
+ ...config,
144
+ });
145
+ };
146
+
147
+ export const checkElementHasParent = (
148
+ element: HTMLElement | null,
149
+ parent: Maybe<HTMLElement>,
150
+ ) => {
151
+ let node = element;
152
+
153
+ if (!parent) return false;
154
+
155
+ while (node != null) {
156
+ if (node === parent) {
157
+ return true;
158
+ } else {
159
+ node = node.parentElement;
160
+ }
161
+ }
162
+
163
+ return false;
164
+ };
165
+
166
+ /**
167
+ * Executes a function within a view transition if supported by the browser.
168
+ *
169
+ * @param {VoidFunction} fn - The function to be executed.
170
+ * @returns {ViewTransition} - The result of the executed function.
171
+ *
172
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition | MDN: Document.startViewTransition}
173
+ */
174
+ export const startViewTransitionSafety = (
175
+ fn: VoidFunction,
176
+ params?: { disabled?: boolean },
177
+ ) => {
178
+ if (document.startViewTransition && !params?.disabled) {
179
+ return document.startViewTransition(fn);
180
+ }
181
+ fn();
182
+ };
183
+
184
+ /**
185
+ * Вычисляет размер скроллбара
186
+ */
187
+ export const calcScrollbarWidth = () => {
188
+ const outer = document.createElement('div');
189
+
190
+ outer.style.visibility = 'hidden';
191
+ outer.style.width = '100px';
192
+ outer.style.overflow = 'scroll';
193
+
194
+ document.body.append(outer);
195
+
196
+ const inner = document.createElement('div');
197
+ inner.style.width = '100%';
198
+
199
+ outer.append(inner);
200
+
201
+ const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
202
+
203
+ outer.parentNode?.removeChild(outer);
204
+
205
+ return scrollbarWidth;
206
+ };
207
+
208
+ /**
209
+ * Calculates the inner height of an HTML element, accounting for padding.
210
+ */
211
+ export function getElementInnerHeight(element: HTMLElement) {
212
+ const { clientHeight } = element;
213
+ const { paddingTop, paddingBottom } = getComputedStyle(element);
214
+ return (
215
+ clientHeight -
216
+ Number.parseFloat(paddingTop) -
217
+ Number.parseFloat(paddingBottom)
218
+ );
219
+ }
220
+
221
+ /**
222
+ * Calculates the inner width of an HTML element, accounting for padding.
223
+ */
224
+ export function getElementInnerWidth(el: HTMLElement) {
225
+ const { clientWidth } = el;
226
+ const { paddingLeft, paddingRight } = getComputedStyle(el);
227
+ return (
228
+ clientWidth -
229
+ Number.parseFloat(paddingLeft) -
230
+ Number.parseFloat(paddingRight)
231
+ );
232
+ }
233
+
234
+ export const isPrefersDarkTheme = () =>
235
+ !!globalThis.matchMedia?.('(prefers-color-scheme: dark)')?.matches;
236
+
237
+ export const isPrefersLightTheme = () =>
238
+ !!globalThis.matchMedia?.('(prefers-color-scheme: light)')?.matches;
@@ -1,27 +1,34 @@
1
1
  import { customAlphabet } from 'nanoid';
2
+
2
3
  const DIGITS = '0123456789';
3
4
  const LATIN_CHARS = 'abcdefghijklmnopqrstuvwxyz';
5
+
4
6
  const ALPHABET = `${LATIN_CHARS}${DIGITS}`;
7
+
5
8
  /**
6
9
  * Использует алфавит abcdefghijklmnopqrstuvwxyz0123456789
7
10
  * Размер 6
8
11
  */
9
12
  export const generateId = customAlphabet(ALPHABET, 6);
13
+
10
14
  /**
11
15
  * Использует алфавит abcdefghijklmnopqrstuvwxyz0123456789
12
16
  * Размер 4
13
17
  */
14
18
  export const generateShortId = customAlphabet(ALPHABET, 4);
19
+
15
20
  /**
16
21
  * Использует алфавит 0123456789
17
22
  * Размер 6
18
23
  */
19
24
  export const generateNumericId = customAlphabet(DIGITS, 6);
25
+
20
26
  /**
21
27
  * Использует алфавит 0123456789
22
28
  * Размер 4
23
29
  */
24
30
  export const generateNumericShortId = customAlphabet(DIGITS, 4);
31
+
25
32
  /**
26
33
  * Создает функцию, которая будет создавать уникальную строку, уникальность которой основана на порядке вызова этой функции
27
34
  *
@@ -41,12 +48,13 @@ export const generateNumericShortId = customAlphabet(DIGITS, 4);
41
48
  * @param size размер
42
49
  * @returns {()=>string}
43
50
  */
44
- export const createLinearNumericIdGenerator = (size = 9) => {
45
- let lastCount = 0;
46
- return () => {
47
- return (lastCount++).toString().padStart(size, '0');
48
- };
51
+ export const createLinearNumericIdGenerator = (size: number = 9) => {
52
+ let lastCount = 0;
53
+ return () => {
54
+ return (lastCount++).toString().padStart(size, '0');
55
+ };
49
56
  };
57
+
50
58
  /**
51
59
  *
52
60
  * @example
@@ -63,9 +71,11 @@ export const createLinearNumericIdGenerator = (size = 9) => {
63
71
  *
64
72
  */
65
73
  export const generateLinearNumericId = createLinearNumericIdGenerator();
74
+
66
75
  /**
67
76
  * Is not recommended to use.
68
77
  *
69
78
  * Generates execution stack based pseudo-id (just sliced string from error stack)
70
79
  */
71
- export const generateStackBasedId = () => new Error().stack.split('\n').slice(1, 4).join('');
80
+ export const generateStackBasedId = () =>
81
+ new Error().stack!.split('\n').slice(1, 4).join('');
package/src/imports.ts ADDED
@@ -0,0 +1,52 @@
1
+ import { sleep } from './async.js';
2
+
3
+ /**
4
+ * Функция ленивой загрузки модуля, с возможностью вызова доп. попыток
5
+ * @example
6
+ * ```ts
7
+ * fetchLazyModule(() => import("./test.ts"), 3) // начнет загрузку test.ts
8
+ * // Произошла ошибка загрузки test.ts, тогда fetchLazyModule повторно вызовет fn()
9
+ * // Вызывать будет столько раз сколько указано attempts (по умолчанию 3)
10
+ * ```
11
+ */
12
+ export const fetchLazyModule = async <T>(
13
+ fetchModule: () => Promise<T>,
14
+ attempts = 3,
15
+ delay = 1000,
16
+ ): Promise<T> => {
17
+ const attemptsArray = Array.from<typeof fetchModule>({
18
+ length: attempts,
19
+ }).fill(fetchModule);
20
+
21
+ let lastError: null | Error = null;
22
+
23
+ for await (const attempt of attemptsArray) {
24
+ try {
25
+ if (lastError !== null) {
26
+ await sleep(delay);
27
+ }
28
+ return await attempt();
29
+ } catch (error) {
30
+ lastError = error as Error;
31
+ }
32
+ }
33
+ throw lastError;
34
+ };
35
+
36
+ export type PackedAsyncModule<T> = Promise<T | { default: T }>;
37
+
38
+ export const unpackAsyncModule = async <T>(
39
+ maybeModule: T | PackedAsyncModule<T>,
40
+ ): Promise<T> => {
41
+ if (maybeModule instanceof Promise) {
42
+ const data = (await maybeModule) as any;
43
+
44
+ if ((data as any).default) {
45
+ return (data as any).default;
46
+ } else {
47
+ return data;
48
+ }
49
+ }
50
+
51
+ return maybeModule;
52
+ };
package/src/math.ts ADDED
@@ -0,0 +1,20 @@
1
+ import type { Maybe } from './utils/types.js';
2
+
3
+ export function degToRad(deg: number) {
4
+ return deg * (Math.PI / 180);
5
+ }
6
+ export function radToDeg(rad: number) {
7
+ return rad * (180 / Math.PI);
8
+ }
9
+
10
+ /**
11
+ * Получить процент от числа
12
+ * @example
13
+ * ```ts
14
+ * percentFrom(500, 2000) // 25
15
+ * percentFrom(1000, 2000) // 50
16
+ * ```
17
+ */
18
+ export const percentFrom = (value: Maybe<number>, from: Maybe<number>) => {
19
+ return ((value ?? 0) / (from ?? 0)) * 100 || 0;
20
+ };
package/src/media.ts ADDED
@@ -0,0 +1,134 @@
1
+ import { degToRad } from './math.js';
2
+
3
+ export function blobToBase64(blob: Blob): Promise<string> {
4
+ return new Promise((resolve, reject) => {
5
+ const reader = new FileReader();
6
+ reader.onloadend = () => resolve(reader.result as string);
7
+ reader.onerror = reject;
8
+ reader.readAsDataURL(blob);
9
+ });
10
+ }
11
+
12
+ export const blobToUrl = (urlOrBlob: string | Blob) =>
13
+ urlOrBlob instanceof Blob ? URL.createObjectURL(urlOrBlob) : urlOrBlob;
14
+
15
+ export const fileToBlob = (file: File) => {
16
+ return new Blob([file], { type: file.type });
17
+ };
18
+
19
+ export const imageToBlob = (
20
+ imageElement: HTMLImageElement,
21
+ mimeType: string = 'image/png',
22
+ ) => {
23
+ const canvas = document.createElement('canvas');
24
+
25
+ canvas.width = imageElement.naturalWidth || 300;
26
+ canvas.height = imageElement.naturalHeight || 300;
27
+
28
+ canvas.getContext('2d')!.drawImage(imageElement, 0, 0);
29
+
30
+ const dataUri = canvas.toDataURL(mimeType, 1);
31
+ const base64data = dataUri.split(',')[1];
32
+ const base64MimeType = dataUri.split(';')[0].slice(5);
33
+
34
+ const bytes = globalThis.atob(base64data);
35
+ const buf = new ArrayBuffer(bytes.length);
36
+ const array = new Uint8Array(buf);
37
+
38
+ for (let index = 0; index < bytes.length; index++) {
39
+ array[index] = bytes.charCodeAt(index);
40
+ }
41
+
42
+ const blob = new Blob([array], { type: base64MimeType });
43
+
44
+ return blob;
45
+ };
46
+
47
+ /**
48
+ * Загружает и отрисовывает изображение с использованием Image
49
+ *
50
+ * @returns {Promise<HTMLImageElement>}
51
+ */
52
+ export const renderImage = (urlOrBlob: Blob | string) =>
53
+ new Promise<HTMLImageElement>((resolve, reject) => {
54
+ const image = new Image();
55
+ image.src = blobToUrl(urlOrBlob);
56
+ image.onload = () => resolve(image);
57
+ image.onerror = () => reject();
58
+ });
59
+
60
+ function cropImageFromCanvas(context: CanvasRenderingContext2D) {
61
+ const canvas = context.canvas;
62
+ let w = canvas.width;
63
+ let h = canvas.height;
64
+ const pix: { x: number[]; y: number[] } = { x: [], y: [] };
65
+ const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
66
+ let x: number;
67
+ let y: number;
68
+ let index: number;
69
+
70
+ for (y = 0; y < h; y++) {
71
+ for (x = 0; x < w; x++) {
72
+ index = (y * w + x) * 4;
73
+ if (imageData.data[index + 3] > 0) {
74
+ pix.x.push(x);
75
+ pix.y.push(y);
76
+ }
77
+ }
78
+ }
79
+ pix.x.sort((a, b) => a - b);
80
+ pix.y.sort((a, b) => a - b);
81
+ const n = pix.x.length - 1;
82
+
83
+ w = 1 + pix.x[n] - pix.x[0];
84
+ h = 1 + pix.y[n] - pix.y[0];
85
+ const cut = context.getImageData(pix.x[0], pix.y[0], w, h);
86
+
87
+ canvas.width = w;
88
+ canvas.height = h;
89
+ context.putImageData(cut, 0, 0);
90
+ return canvas;
91
+ }
92
+
93
+ // TODO: ломает iphone с огромными изображениями
94
+ export const rotateImage = (image: HTMLImageElement, angle: number) => {
95
+ const maxSize = Math.max(image.width, image.height);
96
+ const canvas = document.createElement('canvas');
97
+ canvas.width = maxSize;
98
+ canvas.height = maxSize;
99
+ const context = canvas.getContext('2d')!;
100
+ context.save();
101
+ context.translate(canvas.width / 2, canvas.height / 2);
102
+ context.rotate(degToRad(angle));
103
+ context.drawImage(image, -image.width / 2, -image.height / 2);
104
+ context.restore();
105
+ cropImageFromCanvas(context);
106
+ return renderImage(canvas.toDataURL('image/png'));
107
+ };
108
+
109
+ interface DecodedDataUrl {
110
+ mimeType?: string;
111
+ data?: string;
112
+ }
113
+
114
+ /*
115
+ * Returning object which contains base64 data and mime type of passed data url string.
116
+ * */
117
+ export function decodeDataUrl(url: string): DecodedDataUrl {
118
+ const regex = /^data:(.*);base64,\s?(.*)$/;
119
+ const matches = new RegExp(regex).exec(url);
120
+
121
+ return {
122
+ mimeType: matches?.[1],
123
+ data: matches?.[2],
124
+ };
125
+ }
126
+
127
+ export const isHttpUrl = (url: string): boolean => {
128
+ return url.startsWith('https://') || url.startsWith('http://');
129
+ };
130
+
131
+ export const isBase64Image = (str: string): boolean => {
132
+ const { mimeType, data } = decodeDataUrl(str);
133
+ return !!(data && mimeType?.startsWith('image/'));
134
+ };
@@ -0,0 +1,20 @@
1
+ import { makeObservable } from 'mobx';
2
+ import type { AnyObject } from '../utils/types.js';
3
+
4
+ export type ObservableAnnotationsArray = [string, any][];
5
+
6
+ export const applyObservable = (
7
+ context: AnyObject,
8
+ annotationsArray: ObservableAnnotationsArray,
9
+ useDecorators?: boolean,
10
+ ) => {
11
+ if (useDecorators) {
12
+ annotationsArray.forEach(([field, annotation]) => {
13
+ annotation(context, field);
14
+ });
15
+
16
+ makeObservable(context);
17
+ } else {
18
+ makeObservable(context, Object.fromEntries(annotationsArray));
19
+ }
20
+ };
@@ -0,0 +1,28 @@
1
+ import { createAtom, type IAtom } from 'mobx';
2
+ import type { AnyObject } from '../utils/types.js';
3
+
4
+ export interface IEnhancedAtom<TMeta extends AnyObject = AnyObject>
5
+ extends IAtom {
6
+ meta: TMeta;
7
+ }
8
+
9
+ /**
10
+ * Creates an enhanced atom with meta data
11
+ * And bind `reportChanged` and `reportObserved` method to the atom
12
+ */
13
+ export const createEnhancedAtom = <TMeta extends AnyObject>(
14
+ name: string,
15
+ onBecomeObservedHandler?: (atom: IEnhancedAtom<TMeta>) => void,
16
+ onBecomeUnobservedHandler?: (atom: IEnhancedAtom<TMeta>) => void,
17
+ meta?: TMeta,
18
+ ): IEnhancedAtom<TMeta> => {
19
+ const atom = createAtom(
20
+ name,
21
+ onBecomeObservedHandler && (() => onBecomeObservedHandler?.(atom)),
22
+ onBecomeUnobservedHandler && (() => onBecomeUnobservedHandler?.(atom)),
23
+ ) as IEnhancedAtom<TMeta>;
24
+ atom.meta = meta ?? ({} as TMeta);
25
+ atom.reportChanged = atom.reportChanged.bind(atom);
26
+ atom.reportObserved = atom.reportObserved.bind(atom);
27
+ return atom;
28
+ };