@fluixi/utils 1.0.0-alpha.100

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 (364) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +68 -0
  3. package/dist/index.cjs +2858 -0
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +1 -0
  7. package/dist/index.mjs +2838 -0
  8. package/dist/lib/array/advanced.cjs +2227 -0
  9. package/dist/lib/array/advanced.d.ts +1116 -0
  10. package/dist/lib/array/advanced.d.ts.map +1 -0
  11. package/dist/lib/array/advanced.js +2429 -0
  12. package/dist/lib/array/advanced.mjs +2204 -0
  13. package/dist/lib/array/array.cjs +57 -0
  14. package/dist/lib/array/array.d.ts +6 -0
  15. package/dist/lib/array/array.d.ts.map +1 -0
  16. package/dist/lib/array/array.js +31 -0
  17. package/dist/lib/array/array.mjs +36 -0
  18. package/dist/lib/array/index.cjs +2344 -0
  19. package/dist/lib/array/index.d.ts +4 -0
  20. package/dist/lib/array/index.d.ts.map +1 -0
  21. package/dist/lib/array/index.js +3 -0
  22. package/dist/lib/array/index.mjs +2322 -0
  23. package/dist/lib/array/utils.cjs +103 -0
  24. package/dist/lib/array/utils.d.ts +100 -0
  25. package/dist/lib/array/utils.d.ts.map +1 -0
  26. package/dist/lib/array/utils.js +165 -0
  27. package/dist/lib/array/utils.mjs +82 -0
  28. package/dist/lib/color/color.cjs +2190 -0
  29. package/dist/lib/color/color.d.ts +366 -0
  30. package/dist/lib/color/color.d.ts.map +1 -0
  31. package/dist/lib/color/color.js +722 -0
  32. package/dist/lib/color/color.mjs +2167 -0
  33. package/dist/lib/color/constants.cjs +380 -0
  34. package/dist/lib/color/constants.d.ts +361 -0
  35. package/dist/lib/color/constants.d.ts.map +1 -0
  36. package/dist/lib/color/constants.js +358 -0
  37. package/dist/lib/color/constants.mjs +359 -0
  38. package/dist/lib/color/conversions.cjs +629 -0
  39. package/dist/lib/color/conversions.d.ts +166 -0
  40. package/dist/lib/color/conversions.d.ts.map +1 -0
  41. package/dist/lib/color/conversions.js +766 -0
  42. package/dist/lib/color/conversions.mjs +608 -0
  43. package/dist/lib/color/helpers.cjs +2534 -0
  44. package/dist/lib/color/helpers.d.ts +75 -0
  45. package/dist/lib/color/helpers.d.ts.map +1 -0
  46. package/dist/lib/color/helpers.js +419 -0
  47. package/dist/lib/color/helpers.mjs +2511 -0
  48. package/dist/lib/color/index.cjs +2641 -0
  49. package/dist/lib/color/index.d.ts +12 -0
  50. package/dist/lib/color/index.d.ts.map +1 -0
  51. package/dist/lib/color/index.js +15 -0
  52. package/dist/lib/color/index.mjs +2619 -0
  53. package/dist/lib/color/types.cjs +18 -0
  54. package/dist/lib/color/types.d.ts +179 -0
  55. package/dist/lib/color/types.d.ts.map +1 -0
  56. package/dist/lib/color/types.js +1 -0
  57. package/dist/lib/color/types.mjs +0 -0
  58. package/dist/lib/color/utils.cjs +962 -0
  59. package/dist/lib/color/utils.d.ts +199 -0
  60. package/dist/lib/color/utils.d.ts.map +1 -0
  61. package/dist/lib/color/utils.js +858 -0
  62. package/dist/lib/color/utils.mjs +939 -0
  63. package/dist/lib/compare/comparators.cjs +171 -0
  64. package/dist/lib/compare/comparators.d.ts +65 -0
  65. package/dist/lib/compare/comparators.d.ts.map +1 -0
  66. package/dist/lib/compare/comparators.js +210 -0
  67. package/dist/lib/compare/comparators.mjs +150 -0
  68. package/dist/lib/compare/index.cjs +172 -0
  69. package/dist/lib/compare/index.d.ts +2 -0
  70. package/dist/lib/compare/index.d.ts.map +1 -0
  71. package/dist/lib/compare/index.js +1 -0
  72. package/dist/lib/compare/index.mjs +152 -0
  73. package/dist/lib/cookie/codec.cjs +72 -0
  74. package/dist/lib/cookie/codec.d.ts +22 -0
  75. package/dist/lib/cookie/codec.d.ts.map +1 -0
  76. package/dist/lib/cookie/codec.js +67 -0
  77. package/dist/lib/cookie/codec.mjs +51 -0
  78. package/dist/lib/cookie/index.cjs +75 -0
  79. package/dist/lib/cookie/index.d.ts +2 -0
  80. package/dist/lib/cookie/index.d.ts.map +1 -0
  81. package/dist/lib/cookie/index.js +1 -0
  82. package/dist/lib/cookie/index.mjs +53 -0
  83. package/dist/lib/crypto/hash.cjs +83 -0
  84. package/dist/lib/crypto/hash.d.ts +6 -0
  85. package/dist/lib/crypto/hash.d.ts.map +1 -0
  86. package/dist/lib/crypto/hash.js +53 -0
  87. package/dist/lib/crypto/hash.mjs +62 -0
  88. package/dist/lib/crypto/index.cjs +85 -0
  89. package/dist/lib/crypto/index.d.ts +2 -0
  90. package/dist/lib/crypto/index.d.ts.map +1 -0
  91. package/dist/lib/crypto/index.js +1 -0
  92. package/dist/lib/crypto/index.mjs +62 -0
  93. package/dist/lib/dom/events.cjs +40 -0
  94. package/dist/lib/dom/events.d.ts +159 -0
  95. package/dist/lib/dom/events.d.ts.map +1 -0
  96. package/dist/lib/dom/events.js +50 -0
  97. package/dist/lib/dom/events.mjs +19 -0
  98. package/dist/lib/dom/index.cjs +78 -0
  99. package/dist/lib/dom/index.d.ts +3 -0
  100. package/dist/lib/dom/index.d.ts.map +1 -0
  101. package/dist/lib/dom/index.js +2 -0
  102. package/dist/lib/dom/index.mjs +56 -0
  103. package/dist/lib/dom/utils.cjs +57 -0
  104. package/dist/lib/dom/utils.d.ts +6 -0
  105. package/dist/lib/dom/utils.d.ts.map +1 -0
  106. package/dist/lib/dom/utils.js +37 -0
  107. package/dist/lib/dom/utils.mjs +36 -0
  108. package/dist/lib/functions/functions.cjs +366 -0
  109. package/dist/lib/functions/functions.d.ts +329 -0
  110. package/dist/lib/functions/functions.d.ts.map +1 -0
  111. package/dist/lib/functions/functions.js +585 -0
  112. package/dist/lib/functions/functions.mjs +345 -0
  113. package/dist/lib/functions/index.cjs +369 -0
  114. package/dist/lib/functions/index.d.ts +3 -0
  115. package/dist/lib/functions/index.d.ts.map +1 -0
  116. package/dist/lib/functions/index.js +1 -0
  117. package/dist/lib/functions/index.mjs +347 -0
  118. package/dist/lib/functions/types.cjs +18 -0
  119. package/dist/lib/functions/types.d.ts +2 -0
  120. package/dist/lib/functions/types.d.ts.map +1 -0
  121. package/dist/lib/functions/types.js +1 -0
  122. package/dist/lib/functions/types.mjs +0 -0
  123. package/dist/lib/helpers.cjs +78 -0
  124. package/dist/lib/helpers.d.ts +13 -0
  125. package/dist/lib/helpers.d.ts.map +1 -0
  126. package/dist/lib/helpers.js +66 -0
  127. package/dist/lib/helpers.mjs +59 -0
  128. package/dist/lib/index.cjs +2857 -0
  129. package/dist/lib/index.d.ts +6 -0
  130. package/dist/lib/index.d.ts.map +1 -0
  131. package/dist/lib/index.js +8 -0
  132. package/dist/lib/index.mjs +2836 -0
  133. package/dist/lib/maths/constants.cjs +70 -0
  134. package/dist/lib/maths/constants.d.ts +84 -0
  135. package/dist/lib/maths/constants.d.ts.map +1 -0
  136. package/dist/lib/maths/constants.js +79 -0
  137. package/dist/lib/maths/constants.mjs +50 -0
  138. package/dist/lib/maths/fn/advanced.cjs +231 -0
  139. package/dist/lib/maths/fn/advanced.d.ts +149 -0
  140. package/dist/lib/maths/fn/advanced.d.ts.map +1 -0
  141. package/dist/lib/maths/fn/advanced.js +264 -0
  142. package/dist/lib/maths/fn/advanced.mjs +208 -0
  143. package/dist/lib/maths/fn/basic.cjs +212 -0
  144. package/dist/lib/maths/fn/basic.d.ts +182 -0
  145. package/dist/lib/maths/fn/basic.d.ts.map +1 -0
  146. package/dist/lib/maths/fn/basic.js +343 -0
  147. package/dist/lib/maths/fn/basic.mjs +191 -0
  148. package/dist/lib/maths/fn/complex.cjs +268 -0
  149. package/dist/lib/maths/fn/complex.d.ts +153 -0
  150. package/dist/lib/maths/fn/complex.d.ts.map +1 -0
  151. package/dist/lib/maths/fn/complex.js +383 -0
  152. package/dist/lib/maths/fn/complex.mjs +247 -0
  153. package/dist/lib/maths/fn/index.cjs +877 -0
  154. package/dist/lib/maths/fn/index.d.ts +10 -0
  155. package/dist/lib/maths/fn/index.d.ts.map +1 -0
  156. package/dist/lib/maths/fn/index.js +9 -0
  157. package/dist/lib/maths/fn/index.mjs +855 -0
  158. package/dist/lib/maths/fn/trigo.cjs +179 -0
  159. package/dist/lib/maths/fn/trigo.d.ts +147 -0
  160. package/dist/lib/maths/fn/trigo.d.ts.map +1 -0
  161. package/dist/lib/maths/fn/trigo.js +227 -0
  162. package/dist/lib/maths/fn/trigo.mjs +156 -0
  163. package/dist/lib/maths/fn/vector.cjs +728 -0
  164. package/dist/lib/maths/fn/vector.d.ts +512 -0
  165. package/dist/lib/maths/fn/vector.d.ts.map +1 -0
  166. package/dist/lib/maths/fn/vector.js +1136 -0
  167. package/dist/lib/maths/fn/vector.mjs +707 -0
  168. package/dist/lib/maths/formatter.cjs +61 -0
  169. package/dist/lib/maths/formatter.d.ts +35 -0
  170. package/dist/lib/maths/formatter.d.ts.map +1 -0
  171. package/dist/lib/maths/formatter.js +56 -0
  172. package/dist/lib/maths/formatter.mjs +40 -0
  173. package/dist/lib/maths/guards.cjs +164 -0
  174. package/dist/lib/maths/guards.d.ts +166 -0
  175. package/dist/lib/maths/guards.d.ts.map +1 -0
  176. package/dist/lib/maths/guards.js +315 -0
  177. package/dist/lib/maths/guards.mjs +144 -0
  178. package/dist/lib/maths/index.cjs +1152 -0
  179. package/dist/lib/maths/index.d.ts +24 -0
  180. package/dist/lib/maths/index.d.ts.map +1 -0
  181. package/dist/lib/maths/index.js +29 -0
  182. package/dist/lib/maths/index.mjs +1130 -0
  183. package/dist/lib/maths/parser.cjs +75 -0
  184. package/dist/lib/maths/parser.d.ts +20 -0
  185. package/dist/lib/maths/parser.d.ts.map +1 -0
  186. package/dist/lib/maths/parser.js +78 -0
  187. package/dist/lib/maths/parser.mjs +54 -0
  188. package/dist/lib/maths/random.cjs +49 -0
  189. package/dist/lib/maths/random.d.ts +27 -0
  190. package/dist/lib/maths/random.d.ts.map +1 -0
  191. package/dist/lib/maths/random.js +49 -0
  192. package/dist/lib/maths/random.mjs +28 -0
  193. package/dist/lib/maths/types/advanced.cjs +18 -0
  194. package/dist/lib/maths/types/advanced.d.ts +357 -0
  195. package/dist/lib/maths/types/advanced.d.ts.map +1 -0
  196. package/dist/lib/maths/types/advanced.js +5 -0
  197. package/dist/lib/maths/types/advanced.mjs +0 -0
  198. package/dist/lib/maths/types/basic.cjs +18 -0
  199. package/dist/lib/maths/types/basic.d.ts +95 -0
  200. package/dist/lib/maths/types/basic.d.ts.map +1 -0
  201. package/dist/lib/maths/types/basic.js +5 -0
  202. package/dist/lib/maths/types/basic.mjs +0 -0
  203. package/dist/lib/maths/types/index.cjs +19 -0
  204. package/dist/lib/maths/types/index.d.ts +4 -0
  205. package/dist/lib/maths/types/index.d.ts.map +1 -0
  206. package/dist/lib/maths/types/index.js +3 -0
  207. package/dist/lib/maths/types/index.mjs +1 -0
  208. package/dist/lib/maths/types/negative.cjs +18 -0
  209. package/dist/lib/maths/types/negative.d.ts +51 -0
  210. package/dist/lib/maths/types/negative.d.ts.map +1 -0
  211. package/dist/lib/maths/types/negative.js +5 -0
  212. package/dist/lib/maths/types/negative.mjs +0 -0
  213. package/dist/lib/maths/types/operations.cjs +18 -0
  214. package/dist/lib/maths/types/operations.d.ts +188 -0
  215. package/dist/lib/maths/types/operations.d.ts.map +1 -0
  216. package/dist/lib/maths/types/operations.js +6 -0
  217. package/dist/lib/maths/types/operations.mjs +0 -0
  218. package/dist/lib/object/clone.cjs +88 -0
  219. package/dist/lib/object/clone.d.ts +46 -0
  220. package/dist/lib/object/clone.d.ts.map +1 -0
  221. package/dist/lib/object/clone.js +104 -0
  222. package/dist/lib/object/clone.mjs +65 -0
  223. package/dist/lib/object/diff.cjs +573 -0
  224. package/dist/lib/object/diff.d.ts +203 -0
  225. package/dist/lib/object/diff.d.ts.map +1 -0
  226. package/dist/lib/object/diff.js +805 -0
  227. package/dist/lib/object/diff.mjs +550 -0
  228. package/dist/lib/object/getter-setter.cjs +2351 -0
  229. package/dist/lib/object/getter-setter.d.ts +361 -0
  230. package/dist/lib/object/getter-setter.d.ts.map +1 -0
  231. package/dist/lib/object/getter-setter.js +1771 -0
  232. package/dist/lib/object/getter-setter.mjs +2330 -0
  233. package/dist/lib/object/index.cjs +3956 -0
  234. package/dist/lib/object/index.d.ts +13 -0
  235. package/dist/lib/object/index.d.ts.map +1 -0
  236. package/dist/lib/object/index.js +12 -0
  237. package/dist/lib/object/index.mjs +3936 -0
  238. package/dist/lib/object/merge.cjs +1029 -0
  239. package/dist/lib/object/merge.d.ts +93 -0
  240. package/dist/lib/object/merge.d.ts.map +1 -0
  241. package/dist/lib/object/merge.js +474 -0
  242. package/dist/lib/object/merge.mjs +1006 -0
  243. package/dist/lib/object/object.cjs +280 -0
  244. package/dist/lib/object/object.d.ts +128 -0
  245. package/dist/lib/object/object.d.ts.map +1 -0
  246. package/dist/lib/object/object.js +432 -0
  247. package/dist/lib/object/object.mjs +257 -0
  248. package/dist/lib/object/omit.cjs +2022 -0
  249. package/dist/lib/object/omit.d.ts +351 -0
  250. package/dist/lib/object/omit.d.ts.map +1 -0
  251. package/dist/lib/object/omit.js +656 -0
  252. package/dist/lib/object/omit.mjs +1999 -0
  253. package/dist/lib/object/reconcile.cjs +126 -0
  254. package/dist/lib/object/reconcile.d.ts +7 -0
  255. package/dist/lib/object/reconcile.d.ts.map +1 -0
  256. package/dist/lib/object/reconcile.js +122 -0
  257. package/dist/lib/object/reconcile.mjs +105 -0
  258. package/dist/lib/object/selector.cjs +303 -0
  259. package/dist/lib/object/selector.d.ts +50 -0
  260. package/dist/lib/object/selector.d.ts.map +1 -0
  261. package/dist/lib/object/selector.js +371 -0
  262. package/dist/lib/object/selector.mjs +282 -0
  263. package/dist/lib/object/sort.cjs +209 -0
  264. package/dist/lib/object/sort.d.ts +149 -0
  265. package/dist/lib/object/sort.d.ts.map +1 -0
  266. package/dist/lib/object/sort.js +298 -0
  267. package/dist/lib/object/sort.mjs +186 -0
  268. package/dist/lib/object/transform.cjs +2211 -0
  269. package/dist/lib/object/transform.d.ts +620 -0
  270. package/dist/lib/object/transform.d.ts.map +1 -0
  271. package/dist/lib/object/transform.js +1058 -0
  272. package/dist/lib/object/transform.mjs +2190 -0
  273. package/dist/lib/object/types.cjs +18 -0
  274. package/dist/lib/object/types.d.ts +250 -0
  275. package/dist/lib/object/types.d.ts.map +1 -0
  276. package/dist/lib/object/types.js +1 -0
  277. package/dist/lib/object/types.mjs +0 -0
  278. package/dist/lib/object/utils.cjs +326 -0
  279. package/dist/lib/object/utils.d.ts +165 -0
  280. package/dist/lib/object/utils.d.ts.map +1 -0
  281. package/dist/lib/object/utils.js +444 -0
  282. package/dist/lib/object/utils.mjs +305 -0
  283. package/dist/lib/primitive/boolean/boolean.cjs +407 -0
  284. package/dist/lib/primitive/boolean/boolean.d.ts +276 -0
  285. package/dist/lib/primitive/boolean/boolean.d.ts.map +1 -0
  286. package/dist/lib/primitive/boolean/boolean.js +615 -0
  287. package/dist/lib/primitive/boolean/boolean.mjs +386 -0
  288. package/dist/lib/primitive/boolean/index.cjs +382 -0
  289. package/dist/lib/primitive/boolean/index.d.ts +3 -0
  290. package/dist/lib/primitive/boolean/index.d.ts.map +1 -0
  291. package/dist/lib/primitive/boolean/index.js +2 -0
  292. package/dist/lib/primitive/boolean/index.mjs +359 -0
  293. package/dist/lib/primitive/boolean/types.cjs +18 -0
  294. package/dist/lib/primitive/boolean/types.d.ts +14 -0
  295. package/dist/lib/primitive/boolean/types.d.ts.map +1 -0
  296. package/dist/lib/primitive/boolean/types.js +1 -0
  297. package/dist/lib/primitive/boolean/types.mjs +0 -0
  298. package/dist/lib/primitive/date/date.cjs +1126 -0
  299. package/dist/lib/primitive/date/date.d.ts +641 -0
  300. package/dist/lib/primitive/date/date.d.ts.map +1 -0
  301. package/dist/lib/primitive/date/date.js +1998 -0
  302. package/dist/lib/primitive/date/date.mjs +1105 -0
  303. package/dist/lib/primitive/date/index.cjs +1128 -0
  304. package/dist/lib/primitive/date/index.d.ts +3 -0
  305. package/dist/lib/primitive/date/index.d.ts.map +1 -0
  306. package/dist/lib/primitive/date/index.js +2 -0
  307. package/dist/lib/primitive/date/index.mjs +1105 -0
  308. package/dist/lib/primitive/date/types.cjs +18 -0
  309. package/dist/lib/primitive/date/types.d.ts +205 -0
  310. package/dist/lib/primitive/date/types.d.ts.map +1 -0
  311. package/dist/lib/primitive/date/types.js +7 -0
  312. package/dist/lib/primitive/date/types.mjs +0 -0
  313. package/dist/lib/primitive/index.cjs +2338 -0
  314. package/dist/lib/primitive/index.d.ts +5 -0
  315. package/dist/lib/primitive/index.d.ts.map +1 -0
  316. package/dist/lib/primitive/index.js +4 -0
  317. package/dist/lib/primitive/index.mjs +2316 -0
  318. package/dist/lib/primitive/string/index.cjs +875 -0
  319. package/dist/lib/primitive/string/index.d.ts +3 -0
  320. package/dist/lib/primitive/string/index.d.ts.map +1 -0
  321. package/dist/lib/primitive/string/index.js +2 -0
  322. package/dist/lib/primitive/string/index.mjs +852 -0
  323. package/dist/lib/primitive/string/parser-2.cjs +543 -0
  324. package/dist/lib/primitive/string/parser-2.d.ts +17 -0
  325. package/dist/lib/primitive/string/parser-2.d.ts.map +1 -0
  326. package/dist/lib/primitive/string/parser-2.js +656 -0
  327. package/dist/lib/primitive/string/parser-2.mjs +522 -0
  328. package/dist/lib/primitive/string/parser.cjs +236 -0
  329. package/dist/lib/primitive/string/parser.d.ts +9 -0
  330. package/dist/lib/primitive/string/parser.d.ts.map +1 -0
  331. package/dist/lib/primitive/string/parser.js +775 -0
  332. package/dist/lib/primitive/string/parser.mjs +215 -0
  333. package/dist/lib/primitive/string/string.cjs +926 -0
  334. package/dist/lib/primitive/string/string.d.ts +535 -0
  335. package/dist/lib/primitive/string/string.d.ts.map +1 -0
  336. package/dist/lib/primitive/string/string.js +1301 -0
  337. package/dist/lib/primitive/string/string.mjs +903 -0
  338. package/dist/lib/primitive/string/types.cjs +18 -0
  339. package/dist/lib/primitive/string/types.d.ts +318 -0
  340. package/dist/lib/primitive/string/types.d.ts.map +1 -0
  341. package/dist/lib/primitive/string/types.js +5 -0
  342. package/dist/lib/primitive/string/types.mjs +0 -0
  343. package/dist/lib/primitive/types.cjs +18 -0
  344. package/dist/lib/primitive/types.d.ts +27 -0
  345. package/dist/lib/primitive/types.d.ts.map +1 -0
  346. package/dist/lib/primitive/types.js +1 -0
  347. package/dist/lib/primitive/types.mjs +0 -0
  348. package/dist/lib/url/index.cjs +327 -0
  349. package/dist/lib/url/index.d.ts +3 -0
  350. package/dist/lib/url/index.d.ts.map +1 -0
  351. package/dist/lib/url/index.js +2 -0
  352. package/dist/lib/url/index.mjs +304 -0
  353. package/dist/lib/url/parser.cjs +325 -0
  354. package/dist/lib/url/parser.d.ts +216 -0
  355. package/dist/lib/url/parser.d.ts.map +1 -0
  356. package/dist/lib/url/parser.js +488 -0
  357. package/dist/lib/url/parser.mjs +304 -0
  358. package/dist/lib/url/types.cjs +18 -0
  359. package/dist/lib/url/types.d.ts +18 -0
  360. package/dist/lib/url/types.d.ts.map +1 -0
  361. package/dist/lib/url/types.js +1 -0
  362. package/dist/lib/url/types.mjs +0 -0
  363. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  364. package/package.json +127 -0
@@ -0,0 +1,298 @@
1
+ import { isPlainObject } from './utils.js';
2
+ // ─── Internal helpers ─────────────────────────────────────────────────────────
3
+ /** Read a value via dot-notation path, e.g. `'address.city'`. */
4
+ function getAtPath(obj, path) {
5
+ if (obj == null)
6
+ return undefined;
7
+ let cur = obj;
8
+ for (const segment of path.split('.')) {
9
+ if (cur == null)
10
+ return undefined;
11
+ cur = cur[segment];
12
+ }
13
+ return cur;
14
+ }
15
+ /**
16
+ * Natural, type-aware comparison.
17
+ * Returns negative / zero / positive like `Array.prototype.sort` expects.
18
+ * Handles: null/undefined (always pushed last), NaN, Date, boolean, number, string.
19
+ * Falls back to locale-aware string coercion for mixed / unknown types.
20
+ */
21
+ function compareValues(a, b, locale, localeOptions) {
22
+ // null / undefined: treated as "greater than anything" so they sink to the end
23
+ const aN = a == null;
24
+ const bN = b == null;
25
+ if (aN && bN)
26
+ return 0;
27
+ if (aN)
28
+ return 1;
29
+ if (bN)
30
+ return -1;
31
+ // NaN: sink below null
32
+ const aNaN = typeof a === 'number' && Number.isNaN(a);
33
+ const bNaN = typeof b === 'number' && Number.isNaN(b);
34
+ if (aNaN && bNaN)
35
+ return 0;
36
+ if (aNaN)
37
+ return 1;
38
+ if (bNaN)
39
+ return -1;
40
+ // Date
41
+ if (a instanceof Date && b instanceof Date) {
42
+ return a.getTime() - b.getTime();
43
+ }
44
+ // Boolean (false < true)
45
+ if (typeof a === 'boolean' && typeof b === 'boolean') {
46
+ return (a === b ? 0 : a ? 1 : -1);
47
+ }
48
+ // Number (covers BigInt with coercion below)
49
+ if (typeof a === 'number' && typeof b === 'number') {
50
+ return a - b;
51
+ }
52
+ // String: locale-aware
53
+ if (typeof a === 'string' && typeof b === 'string') {
54
+ return a.localeCompare(b, locale, localeOptions);
55
+ }
56
+ // Fallback: coerce both to string
57
+ return String(a).localeCompare(String(b), locale, localeOptions);
58
+ }
59
+ /** Build a single numeric direction multiplier for the i-th sort key. */
60
+ function dirFor(order, i) {
61
+ const o = Array.isArray(order) ? (order[i] ?? 'asc') : (order ?? 'asc');
62
+ return o === 'desc' ? -1 : 1;
63
+ }
64
+ // ─── Core sort functions ──────────────────────────────────────────────────────
65
+ /**
66
+ * Sort a flat array of primitives, Dates, or mixed values using natural
67
+ * comparison. Respects `order`, `locale`, `localeOptions`, and `nullsLast`.
68
+ */
69
+ function sortPrimitiveArray(arr, options) {
70
+ const { order, locale, localeOptions, nullsLast = true } = options;
71
+ const dir = dirFor(order, 0);
72
+ return arr.slice().sort((a, b) => {
73
+ const aN = a == null;
74
+ const bN = b == null;
75
+ if (aN && bN)
76
+ return 0;
77
+ if (aN)
78
+ return nullsLast ? 1 : -1;
79
+ if (bN)
80
+ return nullsLast ? -1 : 1;
81
+ return compareValues(a, b, locale, localeOptions) * dir;
82
+ });
83
+ }
84
+ /**
85
+ * Sort an array of objects by one or more key paths.
86
+ * Keys are compared left-to-right; the next key is only consulted when all
87
+ * previous keys produced a tie.
88
+ */
89
+ function sortObjectArray(arr, keys, options) {
90
+ const { order, locale, localeOptions, nullsLast = true, comparator } = options;
91
+ if (comparator) {
92
+ return arr.slice().sort(comparator);
93
+ }
94
+ return arr.slice().sort((a, b) => {
95
+ for (let i = 0; i < keys.length; i++) {
96
+ const aVal = getAtPath(a, keys[i]);
97
+ const bVal = getAtPath(b, keys[i]);
98
+ const aN = aVal == null;
99
+ const bN = bVal == null;
100
+ if (aN && bN)
101
+ continue;
102
+ if (aN)
103
+ return nullsLast ? 1 : -1;
104
+ if (bN)
105
+ return nullsLast ? -1 : 1;
106
+ const cmp = compareValues(aVal, bVal, locale, localeOptions);
107
+ if (cmp !== 0)
108
+ return cmp * dirFor(order, i);
109
+ }
110
+ return 0;
111
+ });
112
+ }
113
+ /**
114
+ * Return a new plain object whose own keys are sorted alphabetically, with
115
+ * `priorityKeys` pinned to the front. Values are left untouched unless
116
+ * `deep` is set.
117
+ */
118
+ function sortRecord(record, options) {
119
+ const { order, priorityKeys = [], locale, localeOptions, deep } = options;
120
+ const dir = dirFor(order, 0);
121
+ const prioritySet = new Set(priorityKeys);
122
+ const rest = Object.keys(record).filter((k) => !prioritySet.has(k));
123
+ rest.sort((a, b) => a.localeCompare(b, locale, localeOptions) * dir);
124
+ const ordered = [...priorityKeys.filter((k) => k in record), ...rest];
125
+ const result = {};
126
+ for (const key of ordered) {
127
+ result[key] = deep ? sortDeep(record[key], options) : record[key];
128
+ }
129
+ return result;
130
+ }
131
+ /**
132
+ * Recursively sort a value: sorts arrays in place (returning new array) and
133
+ * sorts record-object keys. Primitives and non-plain objects are returned
134
+ * unchanged.
135
+ */
136
+ function sortDeep(value, options) {
137
+ if (Array.isArray(value)) {
138
+ // Deep-sort elements first, then sort the array itself
139
+ const deepSorted = value.map((item) => sortDeep(item, options));
140
+ return sortArrayValue(deepSorted, options);
141
+ }
142
+ if (isPlainObject(value)) {
143
+ return sortRecord(value, options);
144
+ }
145
+ return value;
146
+ }
147
+ /**
148
+ * Apply an explicit index permutation to an array.
149
+ *
150
+ * `indices[i]` names the source index that appears at position `i` in the
151
+ * output. Input elements not named by any index are appended at the end in
152
+ * their original relative order. Out-of-range indices are ignored.
153
+ */
154
+ function applyIndices(arr, indices) {
155
+ const len = arr.length;
156
+ const used = new Set();
157
+ const result = [];
158
+ for (const idx of indices) {
159
+ if (idx >= 0 && idx < len && !used.has(idx)) {
160
+ result.push(arr[idx]);
161
+ used.add(idx);
162
+ }
163
+ }
164
+ // Append any elements not covered by the permutation
165
+ for (let i = 0; i < len; i++) {
166
+ if (!used.has(i))
167
+ result.push(arr[i]);
168
+ }
169
+ return result;
170
+ }
171
+ /**
172
+ * Dispatch array sorting to the appropriate strategy based on the options
173
+ * present: explicit index permutation → value-based sort → direction-only.
174
+ */
175
+ function sortArrayValue(arr, options) {
176
+ const { by, comparator, indices, order } = options;
177
+ // ── Explicit index permutation ───────────────────────────────────────────
178
+ if (indices) {
179
+ const permuted = applyIndices(arr, indices);
180
+ // order: 'desc' reverses the permuted result
181
+ return dirFor(order, 0) === -1 ? permuted.reverse() : permuted;
182
+ }
183
+ // ── Custom comparator ────────────────────────────────────────────────────
184
+ if (comparator) {
185
+ return arr.slice().sort(comparator);
186
+ }
187
+ // ── Key-based sort ───────────────────────────────────────────────────────
188
+ if (by) {
189
+ const keys = Array.isArray(by) ? by : [by];
190
+ return sortObjectArray(arr, keys, options);
191
+ }
192
+ // ── No key: object arrays are ordered by index position ──────────────────
193
+ // asc = natural order (unchanged)
194
+ // desc = reverse the array
195
+ const firstReal = arr.find((x) => x != null);
196
+ if (firstReal != null && isPlainObject(firstReal)) {
197
+ return dirFor(order, 0) === -1 ? arr.slice().reverse() : arr.slice();
198
+ }
199
+ // ── Primitive array ──────────────────────────────────────────────────────
200
+ return sortPrimitiveArray(arr, options);
201
+ }
202
+ export function sort(input, options = {}) {
203
+ const { deep } = options;
204
+ if (Array.isArray(input)) {
205
+ const items = deep
206
+ ? input.map((item) => sortDeep(item, options))
207
+ : input;
208
+ return sortArrayValue(items, options);
209
+ }
210
+ if (isPlainObject(input)) {
211
+ return sortRecord(input, options);
212
+ }
213
+ return input;
214
+ }
215
+ // ─── Convenience helpers ──────────────────────────────────────────────────────
216
+ /**
217
+ * Sort an array of objects by one or more key paths, returning a new array.
218
+ * Shorthand for `sort(arr, { by: key, order })`.
219
+ *
220
+ * @example
221
+ * sortBy(users, 'name')
222
+ * sortBy(users, ['lastName', 'firstName'], 'asc')
223
+ * sortBy(products, 'price', 'desc')
224
+ */
225
+ export function sortBy(arr, by, order = 'asc', options = {}) {
226
+ return sort(arr, { ...options, by, order });
227
+ }
228
+ /**
229
+ * Sort the keys of a record object, returning a new object.
230
+ * Shorthand for `sort(record, { order, priorityKeys, deep })`.
231
+ *
232
+ * @example
233
+ * sortKeys({ z: 1, a: 2 }) // { a: 2, z: 1 }
234
+ * sortKeys(obj, { priorityKeys: ['id', 'type'] })
235
+ * sortKeys(tree, { deep: true })
236
+ */
237
+ export function sortKeys(record, options = {}) {
238
+ return sort(record, options);
239
+ }
240
+ /**
241
+ * Move an element from one index to another, shifting the elements in between.
242
+ * Returns a new array; the original is not mutated.
243
+ *
244
+ * - Clamps `from` and `to` to valid array bounds.
245
+ * - When `from === to` the original array is returned as-is (same reference).
246
+ *
247
+ * @example
248
+ * move(['a','b','c','d'], 0, 2) // ['b','c','a','d'] (first → third)
249
+ * move(['a','b','c','d'], 3, 1) // ['a','d','b','c'] (last → second)
250
+ * move(users, fromIndex, toIndex)
251
+ */
252
+ export function move(arr, from, to) {
253
+ const len = arr.length;
254
+ if (len === 0)
255
+ return arr.slice();
256
+ const f = Math.max(0, Math.min(len - 1, from));
257
+ const t = Math.max(0, Math.min(len - 1, to));
258
+ if (f === t)
259
+ return arr.slice();
260
+ const result = arr.slice();
261
+ const [item] = result.splice(f, 1);
262
+ result.splice(t, 0, item);
263
+ return result;
264
+ }
265
+ /**
266
+ * Swap two elements by index, returning a new array.
267
+ * The original array is not mutated.
268
+ * Out-of-range indices throw a `RangeError`.
269
+ *
270
+ * @example
271
+ * swap(['a','b','c'], 0, 2) // ['c','b','a']
272
+ * swap(users, 1, 3)
273
+ */
274
+ export function swap(arr, i, j) {
275
+ const len = arr.length;
276
+ if (i < 0 || i >= len)
277
+ throw new RangeError(`swap: index ${i} out of range`);
278
+ if (j < 0 || j >= len)
279
+ throw new RangeError(`swap: index ${j} out of range`);
280
+ if (i === j)
281
+ return arr.slice();
282
+ const result = arr.slice();
283
+ result[i] = arr[j];
284
+ result[j] = arr[i];
285
+ return result;
286
+ }
287
+ /**
288
+ * Reorder an array by providing the full desired sequence of source indices.
289
+ * Shorthand for `sort(arr, { indices })`.
290
+ *
291
+ * @example
292
+ * reorder(['a','b','c'], [2, 0, 1]) // ['c','a','b']
293
+ * reorder(tabs, newIndexOrder) // apply UI drag-and-drop result
294
+ * reorder(rows, [3,1,0,2], 'desc') // permute then reverse
295
+ */
296
+ export function reorder(arr, indices, order = 'asc') {
297
+ return sort(arr, { indices, order });
298
+ }
@@ -0,0 +1,186 @@
1
+ // src/lib/object/utils.ts
2
+ function isPlainObject(v) {
3
+ if (typeof v !== "object" || v === null) return false;
4
+ const proto = Object.getPrototypeOf(v);
5
+ return proto === Object.prototype || proto === null;
6
+ }
7
+
8
+ // src/lib/object/sort.ts
9
+ function getAtPath(obj, path) {
10
+ if (obj == null) return void 0;
11
+ let cur = obj;
12
+ for (const segment of path.split(".")) {
13
+ if (cur == null) return void 0;
14
+ cur = cur[segment];
15
+ }
16
+ return cur;
17
+ }
18
+ function compareValues(a, b, locale, localeOptions) {
19
+ const aN = a == null;
20
+ const bN = b == null;
21
+ if (aN && bN) return 0;
22
+ if (aN) return 1;
23
+ if (bN) return -1;
24
+ const aNaN = typeof a === "number" && Number.isNaN(a);
25
+ const bNaN = typeof b === "number" && Number.isNaN(b);
26
+ if (aNaN && bNaN) return 0;
27
+ if (aNaN) return 1;
28
+ if (bNaN) return -1;
29
+ if (a instanceof Date && b instanceof Date) {
30
+ return a.getTime() - b.getTime();
31
+ }
32
+ if (typeof a === "boolean" && typeof b === "boolean") {
33
+ return a === b ? 0 : a ? 1 : -1;
34
+ }
35
+ if (typeof a === "number" && typeof b === "number") {
36
+ return a - b;
37
+ }
38
+ if (typeof a === "string" && typeof b === "string") {
39
+ return a.localeCompare(b, locale, localeOptions);
40
+ }
41
+ return String(a).localeCompare(String(b), locale, localeOptions);
42
+ }
43
+ function dirFor(order, i) {
44
+ const o = Array.isArray(order) ? order[i] ?? "asc" : order ?? "asc";
45
+ return o === "desc" ? -1 : 1;
46
+ }
47
+ function sortPrimitiveArray(arr, options) {
48
+ const { order, locale, localeOptions, nullsLast = true } = options;
49
+ const dir = dirFor(order, 0);
50
+ return arr.slice().sort((a, b) => {
51
+ const aN = a == null;
52
+ const bN = b == null;
53
+ if (aN && bN) return 0;
54
+ if (aN) return nullsLast ? 1 : -1;
55
+ if (bN) return nullsLast ? -1 : 1;
56
+ return compareValues(a, b, locale, localeOptions) * dir;
57
+ });
58
+ }
59
+ function sortObjectArray(arr, keys, options) {
60
+ const { order, locale, localeOptions, nullsLast = true, comparator } = options;
61
+ if (comparator) {
62
+ return arr.slice().sort(comparator);
63
+ }
64
+ return arr.slice().sort((a, b) => {
65
+ for (let i = 0; i < keys.length; i++) {
66
+ const aVal = getAtPath(a, keys[i]);
67
+ const bVal = getAtPath(b, keys[i]);
68
+ const aN = aVal == null;
69
+ const bN = bVal == null;
70
+ if (aN && bN) continue;
71
+ if (aN) return nullsLast ? 1 : -1;
72
+ if (bN) return nullsLast ? -1 : 1;
73
+ const cmp = compareValues(aVal, bVal, locale, localeOptions);
74
+ if (cmp !== 0) return cmp * dirFor(order, i);
75
+ }
76
+ return 0;
77
+ });
78
+ }
79
+ function sortRecord(record, options) {
80
+ const { order, priorityKeys = [], locale, localeOptions, deep } = options;
81
+ const dir = dirFor(order, 0);
82
+ const prioritySet = new Set(priorityKeys);
83
+ const rest = Object.keys(record).filter((k) => !prioritySet.has(k));
84
+ rest.sort(
85
+ (a, b) => a.localeCompare(b, locale, localeOptions) * dir
86
+ );
87
+ const ordered = [...priorityKeys.filter((k) => k in record), ...rest];
88
+ const result = {};
89
+ for (const key of ordered) {
90
+ result[key] = deep ? sortDeep(record[key], options) : record[key];
91
+ }
92
+ return result;
93
+ }
94
+ function sortDeep(value, options) {
95
+ if (Array.isArray(value)) {
96
+ const deepSorted = value.map((item) => sortDeep(item, options));
97
+ return sortArrayValue(deepSorted, options);
98
+ }
99
+ if (isPlainObject(value)) {
100
+ return sortRecord(value, options);
101
+ }
102
+ return value;
103
+ }
104
+ function applyIndices(arr, indices) {
105
+ const len = arr.length;
106
+ const used = /* @__PURE__ */ new Set();
107
+ const result = [];
108
+ for (const idx of indices) {
109
+ if (idx >= 0 && idx < len && !used.has(idx)) {
110
+ result.push(arr[idx]);
111
+ used.add(idx);
112
+ }
113
+ }
114
+ for (let i = 0; i < len; i++) {
115
+ if (!used.has(i)) result.push(arr[i]);
116
+ }
117
+ return result;
118
+ }
119
+ function sortArrayValue(arr, options) {
120
+ const { by, comparator, indices, order } = options;
121
+ if (indices) {
122
+ const permuted = applyIndices(arr, indices);
123
+ return dirFor(order, 0) === -1 ? permuted.reverse() : permuted;
124
+ }
125
+ if (comparator) {
126
+ return arr.slice().sort(comparator);
127
+ }
128
+ if (by) {
129
+ const keys = Array.isArray(by) ? by : [by];
130
+ return sortObjectArray(arr, keys, options);
131
+ }
132
+ const firstReal = arr.find((x) => x != null);
133
+ if (firstReal != null && isPlainObject(firstReal)) {
134
+ return dirFor(order, 0) === -1 ? arr.slice().reverse() : arr.slice();
135
+ }
136
+ return sortPrimitiveArray(arr, options);
137
+ }
138
+ function sort(input, options = {}) {
139
+ const { deep } = options;
140
+ if (Array.isArray(input)) {
141
+ const items = deep ? input.map((item) => sortDeep(item, options)) : input;
142
+ return sortArrayValue(items, options);
143
+ }
144
+ if (isPlainObject(input)) {
145
+ return sortRecord(input, options);
146
+ }
147
+ return input;
148
+ }
149
+ function sortBy(arr, by, order = "asc", options = {}) {
150
+ return sort(arr, { ...options, by, order });
151
+ }
152
+ function sortKeys(record, options = {}) {
153
+ return sort(record, options);
154
+ }
155
+ function move(arr, from, to) {
156
+ const len = arr.length;
157
+ if (len === 0) return arr.slice();
158
+ const f = Math.max(0, Math.min(len - 1, from));
159
+ const t = Math.max(0, Math.min(len - 1, to));
160
+ if (f === t) return arr.slice();
161
+ const result = arr.slice();
162
+ const [item] = result.splice(f, 1);
163
+ result.splice(t, 0, item);
164
+ return result;
165
+ }
166
+ function swap(arr, i, j) {
167
+ const len = arr.length;
168
+ if (i < 0 || i >= len) throw new RangeError(`swap: index ${i} out of range`);
169
+ if (j < 0 || j >= len) throw new RangeError(`swap: index ${j} out of range`);
170
+ if (i === j) return arr.slice();
171
+ const result = arr.slice();
172
+ result[i] = arr[j];
173
+ result[j] = arr[i];
174
+ return result;
175
+ }
176
+ function reorder(arr, indices, order = "asc") {
177
+ return sort(arr, { indices, order });
178
+ }
179
+ export {
180
+ move,
181
+ reorder,
182
+ sort,
183
+ sortBy,
184
+ sortKeys,
185
+ swap
186
+ };