@kdtlabs/utils 0.0.4 → 0.0.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 (454) hide show
  1. package/SKILL.md +12 -9
  2. package/dist/arrays/comparators.d.ts +8 -0
  3. package/dist/arrays/comparators.d.ts.map +1 -0
  4. package/{arrays → dist/arrays}/index.d.ts +1 -0
  5. package/dist/arrays/index.d.ts.map +1 -0
  6. package/{common → dist/common}/assertions.d.ts +1 -1
  7. package/{common → dist/common}/assertions.d.ts.map +1 -1
  8. package/{common → dist/common}/types.d.ts +1 -1
  9. package/{common → dist/common}/types.d.ts.map +1 -1
  10. package/{functions → dist/functions}/executions.d.ts +1 -1
  11. package/{functions → dist/functions}/executions.d.ts.map +1 -1
  12. package/dist/index.js +14 -0
  13. package/dist/index.js.map +101 -0
  14. package/{objects → dist/objects}/transformations.d.ts +1 -1
  15. package/{objects → dist/objects}/transformations.d.ts.map +1 -1
  16. package/{objects → dist/objects}/types.d.ts +1 -1
  17. package/{objects → dist/objects}/types.d.ts.map +1 -1
  18. package/{promises → dist/promises}/deferred.d.ts +1 -1
  19. package/{promises → dist/promises}/deferred.d.ts.map +1 -1
  20. package/{promises → dist/promises}/timers.d.ts +1 -1
  21. package/{promises → dist/promises}/timers.d.ts.map +1 -1
  22. package/{serializer → dist/serializer}/context.d.ts +1 -1
  23. package/{serializer → dist/serializer}/context.d.ts.map +1 -1
  24. package/{serializer → dist/serializer}/serialize.d.ts +1 -1
  25. package/{serializer → dist/serializer}/serialize.d.ts.map +1 -1
  26. package/{serializer → dist/serializer}/serializers/array.d.ts +1 -1
  27. package/{serializer → dist/serializer}/serializers/array.d.ts.map +1 -1
  28. package/{serializer → dist/serializer}/serializers/binary.d.ts +1 -1
  29. package/dist/serializer/serializers/binary.d.ts.map +1 -0
  30. package/{serializer → dist/serializer}/serializers/blob.d.ts +1 -1
  31. package/dist/serializer/serializers/blob.d.ts.map +1 -0
  32. package/{serializer → dist/serializer}/serializers/collection.d.ts +1 -1
  33. package/{serializer → dist/serializer}/serializers/collection.d.ts.map +1 -1
  34. package/{serializer → dist/serializer}/serializers/compound.d.ts +1 -1
  35. package/{serializer → dist/serializer}/serializers/compound.d.ts.map +1 -1
  36. package/{serializer → dist/serializer}/serializers/error.d.ts +1 -1
  37. package/{serializer → dist/serializer}/serializers/error.d.ts.map +1 -1
  38. package/{serializer → dist/serializer}/serializers/function.d.ts +1 -1
  39. package/{serializer → dist/serializer}/serializers/function.d.ts.map +1 -1
  40. package/{serializer → dist/serializer}/serializers/leaf-object.d.ts +1 -1
  41. package/{serializer → dist/serializer}/serializers/leaf-object.d.ts.map +1 -1
  42. package/{serializer → dist/serializer}/serializers/number.d.ts +1 -1
  43. package/dist/serializer/serializers/number.d.ts.map +1 -0
  44. package/{serializer → dist/serializer}/serializers/object.d.ts +1 -1
  45. package/{serializer → dist/serializer}/serializers/object.d.ts.map +1 -1
  46. package/{serializer → dist/serializer}/serializers/opaque.d.ts +1 -1
  47. package/dist/serializer/serializers/opaque.d.ts.map +1 -0
  48. package/{serializer → dist/serializer}/serializers/primitive.d.ts +1 -1
  49. package/{serializer → dist/serializer}/serializers/primitive.d.ts.map +1 -1
  50. package/{serializer → dist/serializer}/types.d.ts +1 -1
  51. package/{serializer → dist/serializer}/types.d.ts.map +1 -1
  52. package/{serializer → dist/serializer}/utils.d.ts +1 -1
  53. package/{serializer → dist/serializer}/utils.d.ts.map +1 -1
  54. package/{strings → dist/strings}/index.d.ts +1 -0
  55. package/{strings → dist/strings}/index.d.ts.map +1 -1
  56. package/{strings → dist/strings}/manipulations.d.ts +2 -0
  57. package/{strings → dist/strings}/manipulations.d.ts.map +1 -1
  58. package/dist/strings/strip-ansi.d.ts +2 -0
  59. package/dist/strings/strip-ansi.d.ts.map +1 -0
  60. package/{system → dist/system}/fetch.d.ts +2 -2
  61. package/{system → dist/system}/fetch.d.ts.map +1 -1
  62. package/dist/system/types.d.ts +3 -0
  63. package/{system → dist/system}/types.d.ts.map +1 -1
  64. package/{times → dist/times}/conversions.d.ts +1 -1
  65. package/{times → dist/times}/conversions.d.ts.map +1 -1
  66. package/package.json +11 -73
  67. package/src/arrays/accessors.ts +25 -0
  68. package/src/arrays/comparators.ts +53 -0
  69. package/src/arrays/conversions.ts +16 -0
  70. package/src/arrays/factories.ts +13 -0
  71. package/src/arrays/guards.ts +7 -0
  72. package/src/arrays/index.ts +9 -0
  73. package/src/arrays/operations.ts +103 -0
  74. package/src/arrays/set-operations.ts +11 -0
  75. package/src/arrays/types.ts +21 -0
  76. package/src/buffers/conversions.ts +26 -0
  77. package/src/buffers/guards.ts +13 -0
  78. package/src/buffers/index.ts +5 -0
  79. package/src/buffers/operations.ts +44 -0
  80. package/src/buffers/types.ts +1 -0
  81. package/src/collections/fifo-map.ts +33 -0
  82. package/src/collections/fifo-set.ts +29 -0
  83. package/src/collections/guards.ts +11 -0
  84. package/src/collections/index.ts +10 -0
  85. package/src/collections/linked-base.ts +117 -0
  86. package/src/collections/linked-map.ts +82 -0
  87. package/src/collections/linked-set.ts +69 -0
  88. package/src/collections/lru-map.ts +36 -0
  89. package/src/collections/lru-set.ts +25 -0
  90. package/src/collections/types.ts +12 -0
  91. package/src/common/assertions.ts +11 -0
  92. package/src/common/guards.ts +58 -0
  93. package/src/common/index.ts +5 -0
  94. package/src/common/transformations.ts +20 -0
  95. package/src/common/types.ts +3 -0
  96. package/src/core/constants.ts +1 -0
  97. package/src/core/conversions.ts +9 -0
  98. package/src/core/guards.ts +57 -0
  99. package/src/core/index.ts +5 -0
  100. package/src/core/types.ts +15 -0
  101. package/src/errors/base-error.ts +48 -0
  102. package/src/errors/factories.ts +74 -0
  103. package/src/errors/guards.ts +12 -0
  104. package/src/errors/index.ts +7 -0
  105. package/src/errors/operations.ts +15 -0
  106. package/src/errors/stringify.ts +131 -0
  107. package/src/errors/types.ts +11 -0
  108. package/src/events/emitter.ts +117 -0
  109. package/src/events/index.ts +2 -0
  110. package/src/events/types.ts +11 -0
  111. package/src/functions/compositions.ts +17 -0
  112. package/src/functions/debounce.ts +34 -0
  113. package/src/functions/executions.ts +12 -0
  114. package/src/functions/guards.ts +5 -0
  115. package/src/functions/index.ts +11 -0
  116. package/src/functions/memoize.ts +33 -0
  117. package/src/functions/once.ts +33 -0
  118. package/src/functions/pipe.ts +39 -0
  119. package/src/functions/throttle.ts +59 -0
  120. package/src/functions/timer-state.ts +33 -0
  121. package/src/functions/types.ts +8 -0
  122. package/src/index.ts +16 -0
  123. package/src/json-rpc/constants.ts +15 -0
  124. package/src/json-rpc/factories.ts +22 -0
  125. package/src/json-rpc/guards.ts +58 -0
  126. package/src/json-rpc/index.ts +5 -0
  127. package/src/json-rpc/types.ts +48 -0
  128. package/src/numbers/bigint-math.ts +163 -0
  129. package/src/numbers/constants.ts +14 -0
  130. package/src/numbers/conversions.ts +83 -0
  131. package/src/numbers/factories.ts +6 -0
  132. package/src/numbers/formats.ts +52 -0
  133. package/src/numbers/guards.ts +22 -0
  134. package/src/numbers/index.ts +10 -0
  135. package/src/numbers/maths.ts +28 -0
  136. package/src/numbers/ranges.ts +17 -0
  137. package/src/numbers/types.ts +7 -0
  138. package/src/objects/deep-merge.ts +76 -0
  139. package/src/objects/guards.ts +21 -0
  140. package/src/objects/index.ts +5 -0
  141. package/src/objects/transformations.ts +34 -0
  142. package/src/objects/types.ts +33 -0
  143. package/src/promises/abortable.ts +37 -0
  144. package/src/promises/compositions.ts +18 -0
  145. package/src/promises/deferred.ts +131 -0
  146. package/src/promises/guards.ts +8 -0
  147. package/src/promises/index.ts +10 -0
  148. package/src/promises/pipe.ts +39 -0
  149. package/src/promises/poll.ts +92 -0
  150. package/src/promises/retry.ts +138 -0
  151. package/src/promises/timers.ts +16 -0
  152. package/src/promises/types.ts +1 -0
  153. package/src/serializer/constants.ts +5 -0
  154. package/src/serializer/context.ts +24 -0
  155. package/src/serializer/index.ts +8 -0
  156. package/src/serializer/serialize.ts +51 -0
  157. package/src/serializer/serializers/array.ts +17 -0
  158. package/src/serializer/serializers/binary.ts +24 -0
  159. package/src/serializer/serializers/blob.ts +18 -0
  160. package/src/serializer/serializers/collection.ts +25 -0
  161. package/src/serializer/serializers/compound.ts +79 -0
  162. package/src/serializer/serializers/error.ts +75 -0
  163. package/src/serializer/serializers/function.ts +13 -0
  164. package/src/serializer/serializers/index.ts +12 -0
  165. package/src/serializer/serializers/leaf-object.ts +18 -0
  166. package/src/serializer/serializers/number.ts +14 -0
  167. package/src/serializer/serializers/object.ts +62 -0
  168. package/src/serializer/serializers/opaque.ts +36 -0
  169. package/src/serializer/serializers/primitive.ts +32 -0
  170. package/src/serializer/symbol-registry.ts +28 -0
  171. package/src/serializer/types.ts +42 -0
  172. package/src/serializer/utils.ts +15 -0
  173. package/src/strings/constants.ts +1 -0
  174. package/src/strings/factories.ts +9 -0
  175. package/src/strings/guards.ts +51 -0
  176. package/src/strings/index.ts +7 -0
  177. package/src/strings/manipulations.ts +145 -0
  178. package/src/strings/strip-ansi.ts +14 -0
  179. package/src/strings/types.ts +3 -0
  180. package/src/system/env.ts +32 -0
  181. package/src/system/fetch.ts +23 -0
  182. package/src/system/graceful-exit.ts +46 -0
  183. package/src/system/index.ts +6 -0
  184. package/src/system/path.ts +12 -0
  185. package/src/system/types.ts +3 -0
  186. package/src/times/constants.ts +6 -0
  187. package/src/times/conversions.ts +85 -0
  188. package/src/times/factories.ts +3 -0
  189. package/src/times/guards.ts +3 -0
  190. package/src/times/index.ts +5 -0
  191. package/src/times/operations.ts +9 -0
  192. package/CHANGELOG.md +0 -57
  193. package/arrays/index.d.ts.map +0 -1
  194. package/arrays/index.js +0 -4
  195. package/arrays/index.js.map +0 -9
  196. package/buffers/index.js +0 -4
  197. package/buffers/index.js.map +0 -9
  198. package/chunk-25ja9350.js +0 -4
  199. package/chunk-25ja9350.js.map +0 -13
  200. package/chunk-3w6nt7kb.js +0 -4
  201. package/chunk-3w6nt7kb.js.map +0 -12
  202. package/chunk-5txwcr6j.js +0 -4
  203. package/chunk-5txwcr6j.js.map +0 -17
  204. package/chunk-6dxad51h.js +0 -4
  205. package/chunk-6dxad51h.js.map +0 -12
  206. package/chunk-6kdnnxe0.js +0 -4
  207. package/chunk-6kdnnxe0.js.map +0 -17
  208. package/chunk-7cndek91.js +0 -4
  209. package/chunk-7cndek91.js.map +0 -15
  210. package/chunk-bee0nxse.js +0 -6
  211. package/chunk-bee0nxse.js.map +0 -14
  212. package/chunk-bjmntg2y.js +0 -4
  213. package/chunk-bjmntg2y.js.map +0 -18
  214. package/chunk-d0d0d285.js +0 -4
  215. package/chunk-d0d0d285.js.map +0 -26
  216. package/chunk-jny2gdyy.js +0 -4
  217. package/chunk-jny2gdyy.js.map +0 -12
  218. package/chunk-kbzgn0z4.js +0 -4
  219. package/chunk-kbzgn0z4.js.map +0 -10
  220. package/chunk-qmbgp0vr.js +0 -4
  221. package/chunk-qmbgp0vr.js.map +0 -12
  222. package/chunk-qn6n0ff5.js +0 -4
  223. package/chunk-qn6n0ff5.js.map +0 -17
  224. package/chunk-r3maskdb.js +0 -5
  225. package/chunk-r3maskdb.js.map +0 -13
  226. package/chunk-st3dxvqt.js +0 -4
  227. package/chunk-st3dxvqt.js.map +0 -14
  228. package/chunk-xp18wdk6.js +0 -4
  229. package/chunk-xp18wdk6.js.map +0 -12
  230. package/collections/index.js +0 -4
  231. package/collections/index.js.map +0 -9
  232. package/common/index.js +0 -4
  233. package/common/index.js.map +0 -9
  234. package/core/index.js +0 -4
  235. package/core/index.js.map +0 -9
  236. package/errors/index.js +0 -4
  237. package/errors/index.js.map +0 -9
  238. package/events/index.js +0 -4
  239. package/events/index.js.map +0 -9
  240. package/functions/index.js +0 -4
  241. package/functions/index.js.map +0 -9
  242. package/index.js +0 -4
  243. package/index.js.map +0 -9
  244. package/json-rpc/index.js +0 -4
  245. package/json-rpc/index.js.map +0 -9
  246. package/meta.json +0 -2998
  247. package/meta.md +0 -1816
  248. package/numbers/index.js +0 -4
  249. package/numbers/index.js.map +0 -9
  250. package/objects/index.js +0 -4
  251. package/objects/index.js.map +0 -9
  252. package/promises/index.js +0 -4
  253. package/promises/index.js.map +0 -9
  254. package/serializer/index.js +0 -4
  255. package/serializer/index.js.map +0 -9
  256. package/serializer/serializers/binary.d.ts.map +0 -1
  257. package/serializer/serializers/blob.d.ts.map +0 -1
  258. package/serializer/serializers/number.d.ts.map +0 -1
  259. package/serializer/serializers/opaque.d.ts.map +0 -1
  260. package/strings/index.js +0 -4
  261. package/strings/index.js.map +0 -9
  262. package/system/index.js +0 -4
  263. package/system/index.js.map +0 -9
  264. package/system/types.d.ts +0 -3
  265. package/times/index.js +0 -4
  266. package/times/index.js.map +0 -9
  267. /package/{arrays → dist/arrays}/accessors.d.ts +0 -0
  268. /package/{arrays → dist/arrays}/accessors.d.ts.map +0 -0
  269. /package/{arrays → dist/arrays}/conversions.d.ts +0 -0
  270. /package/{arrays → dist/arrays}/conversions.d.ts.map +0 -0
  271. /package/{arrays → dist/arrays}/factories.d.ts +0 -0
  272. /package/{arrays → dist/arrays}/factories.d.ts.map +0 -0
  273. /package/{arrays → dist/arrays}/guards.d.ts +0 -0
  274. /package/{arrays → dist/arrays}/guards.d.ts.map +0 -0
  275. /package/{arrays → dist/arrays}/operations.d.ts +0 -0
  276. /package/{arrays → dist/arrays}/operations.d.ts.map +0 -0
  277. /package/{arrays → dist/arrays}/set-operations.d.ts +0 -0
  278. /package/{arrays → dist/arrays}/set-operations.d.ts.map +0 -0
  279. /package/{arrays → dist/arrays}/types.d.ts +0 -0
  280. /package/{arrays → dist/arrays}/types.d.ts.map +0 -0
  281. /package/{buffers → dist/buffers}/conversions.d.ts +0 -0
  282. /package/{buffers → dist/buffers}/conversions.d.ts.map +0 -0
  283. /package/{buffers → dist/buffers}/guards.d.ts +0 -0
  284. /package/{buffers → dist/buffers}/guards.d.ts.map +0 -0
  285. /package/{buffers → dist/buffers}/index.d.ts +0 -0
  286. /package/{buffers → dist/buffers}/index.d.ts.map +0 -0
  287. /package/{buffers → dist/buffers}/operations.d.ts +0 -0
  288. /package/{buffers → dist/buffers}/operations.d.ts.map +0 -0
  289. /package/{buffers → dist/buffers}/types.d.ts +0 -0
  290. /package/{buffers → dist/buffers}/types.d.ts.map +0 -0
  291. /package/{collections → dist/collections}/fifo-map.d.ts +0 -0
  292. /package/{collections → dist/collections}/fifo-map.d.ts.map +0 -0
  293. /package/{collections → dist/collections}/fifo-set.d.ts +0 -0
  294. /package/{collections → dist/collections}/fifo-set.d.ts.map +0 -0
  295. /package/{collections → dist/collections}/guards.d.ts +0 -0
  296. /package/{collections → dist/collections}/guards.d.ts.map +0 -0
  297. /package/{collections → dist/collections}/index.d.ts +0 -0
  298. /package/{collections → dist/collections}/index.d.ts.map +0 -0
  299. /package/{collections → dist/collections}/linked-base.d.ts +0 -0
  300. /package/{collections → dist/collections}/linked-base.d.ts.map +0 -0
  301. /package/{collections → dist/collections}/linked-map.d.ts +0 -0
  302. /package/{collections → dist/collections}/linked-map.d.ts.map +0 -0
  303. /package/{collections → dist/collections}/linked-set.d.ts +0 -0
  304. /package/{collections → dist/collections}/linked-set.d.ts.map +0 -0
  305. /package/{collections → dist/collections}/lru-map.d.ts +0 -0
  306. /package/{collections → dist/collections}/lru-map.d.ts.map +0 -0
  307. /package/{collections → dist/collections}/lru-set.d.ts +0 -0
  308. /package/{collections → dist/collections}/lru-set.d.ts.map +0 -0
  309. /package/{collections → dist/collections}/types.d.ts +0 -0
  310. /package/{collections → dist/collections}/types.d.ts.map +0 -0
  311. /package/{common → dist/common}/guards.d.ts +0 -0
  312. /package/{common → dist/common}/guards.d.ts.map +0 -0
  313. /package/{common → dist/common}/index.d.ts +0 -0
  314. /package/{common → dist/common}/index.d.ts.map +0 -0
  315. /package/{common → dist/common}/transformations.d.ts +0 -0
  316. /package/{common → dist/common}/transformations.d.ts.map +0 -0
  317. /package/{core → dist/core}/constants.d.ts +0 -0
  318. /package/{core → dist/core}/constants.d.ts.map +0 -0
  319. /package/{core → dist/core}/conversions.d.ts +0 -0
  320. /package/{core → dist/core}/conversions.d.ts.map +0 -0
  321. /package/{core → dist/core}/guards.d.ts +0 -0
  322. /package/{core → dist/core}/guards.d.ts.map +0 -0
  323. /package/{core → dist/core}/index.d.ts +0 -0
  324. /package/{core → dist/core}/index.d.ts.map +0 -0
  325. /package/{core → dist/core}/types.d.ts +0 -0
  326. /package/{core → dist/core}/types.d.ts.map +0 -0
  327. /package/{errors → dist/errors}/base-error.d.ts +0 -0
  328. /package/{errors → dist/errors}/base-error.d.ts.map +0 -0
  329. /package/{errors → dist/errors}/factories.d.ts +0 -0
  330. /package/{errors → dist/errors}/factories.d.ts.map +0 -0
  331. /package/{errors → dist/errors}/guards.d.ts +0 -0
  332. /package/{errors → dist/errors}/guards.d.ts.map +0 -0
  333. /package/{errors → dist/errors}/index.d.ts +0 -0
  334. /package/{errors → dist/errors}/index.d.ts.map +0 -0
  335. /package/{errors → dist/errors}/operations.d.ts +0 -0
  336. /package/{errors → dist/errors}/operations.d.ts.map +0 -0
  337. /package/{errors → dist/errors}/stringify.d.ts +0 -0
  338. /package/{errors → dist/errors}/stringify.d.ts.map +0 -0
  339. /package/{errors → dist/errors}/types.d.ts +0 -0
  340. /package/{errors → dist/errors}/types.d.ts.map +0 -0
  341. /package/{events → dist/events}/emitter.d.ts +0 -0
  342. /package/{events → dist/events}/emitter.d.ts.map +0 -0
  343. /package/{events → dist/events}/index.d.ts +0 -0
  344. /package/{events → dist/events}/index.d.ts.map +0 -0
  345. /package/{events → dist/events}/types.d.ts +0 -0
  346. /package/{events → dist/events}/types.d.ts.map +0 -0
  347. /package/{functions → dist/functions}/compositions.d.ts +0 -0
  348. /package/{functions → dist/functions}/compositions.d.ts.map +0 -0
  349. /package/{functions → dist/functions}/debounce.d.ts +0 -0
  350. /package/{functions → dist/functions}/debounce.d.ts.map +0 -0
  351. /package/{functions → dist/functions}/guards.d.ts +0 -0
  352. /package/{functions → dist/functions}/guards.d.ts.map +0 -0
  353. /package/{functions → dist/functions}/index.d.ts +0 -0
  354. /package/{functions → dist/functions}/index.d.ts.map +0 -0
  355. /package/{functions → dist/functions}/memoize.d.ts +0 -0
  356. /package/{functions → dist/functions}/memoize.d.ts.map +0 -0
  357. /package/{functions → dist/functions}/once.d.ts +0 -0
  358. /package/{functions → dist/functions}/once.d.ts.map +0 -0
  359. /package/{functions → dist/functions}/pipe.d.ts +0 -0
  360. /package/{functions → dist/functions}/pipe.d.ts.map +0 -0
  361. /package/{functions → dist/functions}/throttle.d.ts +0 -0
  362. /package/{functions → dist/functions}/throttle.d.ts.map +0 -0
  363. /package/{functions → dist/functions}/timer-state.d.ts +0 -0
  364. /package/{functions → dist/functions}/timer-state.d.ts.map +0 -0
  365. /package/{functions → dist/functions}/types.d.ts +0 -0
  366. /package/{functions → dist/functions}/types.d.ts.map +0 -0
  367. /package/{index.d.ts → dist/index.d.ts} +0 -0
  368. /package/{index.d.ts.map → dist/index.d.ts.map} +0 -0
  369. /package/{json-rpc → dist/json-rpc}/constants.d.ts +0 -0
  370. /package/{json-rpc → dist/json-rpc}/constants.d.ts.map +0 -0
  371. /package/{json-rpc → dist/json-rpc}/factories.d.ts +0 -0
  372. /package/{json-rpc → dist/json-rpc}/factories.d.ts.map +0 -0
  373. /package/{json-rpc → dist/json-rpc}/guards.d.ts +0 -0
  374. /package/{json-rpc → dist/json-rpc}/guards.d.ts.map +0 -0
  375. /package/{json-rpc → dist/json-rpc}/index.d.ts +0 -0
  376. /package/{json-rpc → dist/json-rpc}/index.d.ts.map +0 -0
  377. /package/{json-rpc → dist/json-rpc}/types.d.ts +0 -0
  378. /package/{json-rpc → dist/json-rpc}/types.d.ts.map +0 -0
  379. /package/{numbers → dist/numbers}/bigint-math.d.ts +0 -0
  380. /package/{numbers → dist/numbers}/bigint-math.d.ts.map +0 -0
  381. /package/{numbers → dist/numbers}/constants.d.ts +0 -0
  382. /package/{numbers → dist/numbers}/constants.d.ts.map +0 -0
  383. /package/{numbers → dist/numbers}/conversions.d.ts +0 -0
  384. /package/{numbers → dist/numbers}/conversions.d.ts.map +0 -0
  385. /package/{numbers → dist/numbers}/factories.d.ts +0 -0
  386. /package/{numbers → dist/numbers}/factories.d.ts.map +0 -0
  387. /package/{numbers → dist/numbers}/formats.d.ts +0 -0
  388. /package/{numbers → dist/numbers}/formats.d.ts.map +0 -0
  389. /package/{numbers → dist/numbers}/guards.d.ts +0 -0
  390. /package/{numbers → dist/numbers}/guards.d.ts.map +0 -0
  391. /package/{numbers → dist/numbers}/index.d.ts +0 -0
  392. /package/{numbers → dist/numbers}/index.d.ts.map +0 -0
  393. /package/{numbers → dist/numbers}/maths.d.ts +0 -0
  394. /package/{numbers → dist/numbers}/maths.d.ts.map +0 -0
  395. /package/{numbers → dist/numbers}/ranges.d.ts +0 -0
  396. /package/{numbers → dist/numbers}/ranges.d.ts.map +0 -0
  397. /package/{numbers → dist/numbers}/types.d.ts +0 -0
  398. /package/{numbers → dist/numbers}/types.d.ts.map +0 -0
  399. /package/{objects → dist/objects}/deep-merge.d.ts +0 -0
  400. /package/{objects → dist/objects}/deep-merge.d.ts.map +0 -0
  401. /package/{objects → dist/objects}/guards.d.ts +0 -0
  402. /package/{objects → dist/objects}/guards.d.ts.map +0 -0
  403. /package/{objects → dist/objects}/index.d.ts +0 -0
  404. /package/{objects → dist/objects}/index.d.ts.map +0 -0
  405. /package/{promises → dist/promises}/abortable.d.ts +0 -0
  406. /package/{promises → dist/promises}/abortable.d.ts.map +0 -0
  407. /package/{promises → dist/promises}/compositions.d.ts +0 -0
  408. /package/{promises → dist/promises}/compositions.d.ts.map +0 -0
  409. /package/{promises → dist/promises}/guards.d.ts +0 -0
  410. /package/{promises → dist/promises}/guards.d.ts.map +0 -0
  411. /package/{promises → dist/promises}/index.d.ts +0 -0
  412. /package/{promises → dist/promises}/index.d.ts.map +0 -0
  413. /package/{promises → dist/promises}/pipe.d.ts +0 -0
  414. /package/{promises → dist/promises}/pipe.d.ts.map +0 -0
  415. /package/{promises → dist/promises}/poll.d.ts +0 -0
  416. /package/{promises → dist/promises}/poll.d.ts.map +0 -0
  417. /package/{promises → dist/promises}/retry.d.ts +0 -0
  418. /package/{promises → dist/promises}/retry.d.ts.map +0 -0
  419. /package/{promises → dist/promises}/types.d.ts +0 -0
  420. /package/{promises → dist/promises}/types.d.ts.map +0 -0
  421. /package/{serializer → dist/serializer}/constants.d.ts +0 -0
  422. /package/{serializer → dist/serializer}/constants.d.ts.map +0 -0
  423. /package/{serializer → dist/serializer}/index.d.ts +0 -0
  424. /package/{serializer → dist/serializer}/index.d.ts.map +0 -0
  425. /package/{serializer → dist/serializer}/serializers/index.d.ts +0 -0
  426. /package/{serializer → dist/serializer}/serializers/index.d.ts.map +0 -0
  427. /package/{serializer → dist/serializer}/symbol-registry.d.ts +0 -0
  428. /package/{serializer → dist/serializer}/symbol-registry.d.ts.map +0 -0
  429. /package/{strings → dist/strings}/constants.d.ts +0 -0
  430. /package/{strings → dist/strings}/constants.d.ts.map +0 -0
  431. /package/{strings → dist/strings}/factories.d.ts +0 -0
  432. /package/{strings → dist/strings}/factories.d.ts.map +0 -0
  433. /package/{strings → dist/strings}/guards.d.ts +0 -0
  434. /package/{strings → dist/strings}/guards.d.ts.map +0 -0
  435. /package/{strings → dist/strings}/types.d.ts +0 -0
  436. /package/{strings → dist/strings}/types.d.ts.map +0 -0
  437. /package/{system → dist/system}/env.d.ts +0 -0
  438. /package/{system → dist/system}/env.d.ts.map +0 -0
  439. /package/{system → dist/system}/graceful-exit.d.ts +0 -0
  440. /package/{system → dist/system}/graceful-exit.d.ts.map +0 -0
  441. /package/{system → dist/system}/index.d.ts +0 -0
  442. /package/{system → dist/system}/index.d.ts.map +0 -0
  443. /package/{system → dist/system}/path.d.ts +0 -0
  444. /package/{system → dist/system}/path.d.ts.map +0 -0
  445. /package/{times → dist/times}/constants.d.ts +0 -0
  446. /package/{times → dist/times}/constants.d.ts.map +0 -0
  447. /package/{times → dist/times}/factories.d.ts +0 -0
  448. /package/{times → dist/times}/factories.d.ts.map +0 -0
  449. /package/{times → dist/times}/guards.d.ts +0 -0
  450. /package/{times → dist/times}/guards.d.ts.map +0 -0
  451. /package/{times → dist/times}/index.d.ts +0 -0
  452. /package/{times → dist/times}/index.d.ts.map +0 -0
  453. /package/{times → dist/times}/operations.d.ts +0 -0
  454. /package/{times → dist/times}/operations.d.ts.map +0 -0
@@ -0,0 +1,83 @@
1
+ import type { Numberish } from './types'
2
+ import { SUBSCRIPT_CHARS } from './constants'
3
+ import { roundTo } from './maths'
4
+
5
+ export function toSubscriptDigits(input: Numberish) {
6
+ let result = ''
7
+
8
+ for (const char of input.toString()) {
9
+ result += SUBSCRIPT_CHARS[char] ?? char
10
+ }
11
+
12
+ return result
13
+ }
14
+
15
+ export function parseExponential(input: Numberish) {
16
+ const str = input.toString().toLowerCase()
17
+ const [mantissa, rawExp] = str.split('e')
18
+
19
+ if (rawExp === undefined) {
20
+ return str
21
+ }
22
+
23
+ const [rawInt, fracPart = ''] = mantissa?.split('.') ?? []
24
+
25
+ if (!rawInt) {
26
+ return str
27
+ }
28
+
29
+ const sign = rawInt.startsWith('-') ? '-' : ''
30
+ const intPart = sign ? rawInt.slice(1) : rawInt
31
+ const exp = Number(rawExp)
32
+
33
+ if (exp >= 0) {
34
+ const neededZeros = Math.max(0, exp - fracPart.length)
35
+ const padded = fracPart + '0'.repeat(neededZeros)
36
+
37
+ if (padded.length > exp) {
38
+ return `${sign}${intPart}${padded.slice(0, exp)}.${padded.slice(exp)}`
39
+ }
40
+
41
+ return `${sign}${intPart}${padded}`
42
+ }
43
+
44
+ const absExp = -exp
45
+ const digits = intPart + fracPart
46
+ const totalLeadingZeros = Math.max(0, absExp - intPart.length)
47
+
48
+ return `${sign}0.${'0'.repeat(totalLeadingZeros)}${digits}`
49
+ }
50
+
51
+ export function toOrdinal(n: number) {
52
+ const remainder100 = Math.abs(n) % 100
53
+ const remainder10 = remainder100 % 10
54
+
55
+ if (remainder100 >= 11 && remainder100 <= 13) {
56
+ return `${n}th`
57
+ }
58
+
59
+ switch (remainder10) {
60
+ case 1:
61
+ return `${n}st`
62
+ case 2:
63
+ return `${n}nd`
64
+ case 3:
65
+ return `${n}rd`
66
+ default:
67
+ return `${n}th`
68
+ }
69
+ }
70
+
71
+ export function toPercent(value: number, total: number, decimals?: number) {
72
+ if (total === 0) {
73
+ return 0
74
+ }
75
+
76
+ const result = (value / total) * 100
77
+
78
+ if (decimals === undefined) {
79
+ return result
80
+ }
81
+
82
+ return roundTo(result, decimals)
83
+ }
@@ -0,0 +1,6 @@
1
+ export function random(min: number, max: number) {
2
+ const lo = Math.min(min, max)
3
+ const hi = Math.max(min, max)
4
+
5
+ return Math.floor(Math.random() * (hi - lo + 1)) + lo
6
+ }
@@ -0,0 +1,52 @@
1
+ import type { Numberish } from './types'
2
+ import { parseExponential, toSubscriptDigits } from './conversions'
3
+
4
+ export function countLeadingZeros(input: string) {
5
+ let count = 0
6
+
7
+ for (let i = 0; i < input.length && input[i] === '0'; i++) {
8
+ count++
9
+ }
10
+
11
+ return count
12
+ }
13
+
14
+ export interface FormatNumberOptions extends Intl.NumberFormatOptions {
15
+ formatLeadingZeros?: (count: number) => string
16
+ groupFractionLeadingZeros?: boolean
17
+ locales?: Intl.LocalesArgument
18
+ }
19
+
20
+ export function formatNumber(input: Numberish, options_: FormatNumberOptions = {}) {
21
+ const { formatLeadingZeros = (count: number) => `0${toSubscriptDigits(count)}`, groupFractionLeadingZeros = true, locales = 'en-US', maximumFractionDigits = 4, ...options } = options_
22
+
23
+ const formatInput = (digits: number) => (
24
+ new Intl.NumberFormat(locales, { ...options, maximumFractionDigits: digits }).format(input as Intl.StringNumericLiteral)
25
+ )
26
+
27
+ if (!groupFractionLeadingZeros) {
28
+ return formatInput(maximumFractionDigits)
29
+ }
30
+
31
+ const numericStr = parseExponential(input)
32
+ const [, fractionPart = ''] = numericStr.split('.', 2)
33
+ const leadingZerosCount = countLeadingZeros(fractionPart)
34
+
35
+ if (leadingZerosCount <= 1) {
36
+ return formatInput(maximumFractionDigits)
37
+ }
38
+
39
+ const replaceFractionZeros = (part: Intl.NumberFormatPart) => {
40
+ if (part.type === 'fraction') {
41
+ return `${formatLeadingZeros(leadingZerosCount)}${part.value.slice(leadingZerosCount)}`
42
+ }
43
+
44
+ return part.value
45
+ }
46
+
47
+ const parts = new Intl.NumberFormat(locales, {
48
+ ...options, maximumFractionDigits: maximumFractionDigits + leadingZerosCount,
49
+ })
50
+
51
+ return parts.formatToParts(input as Intl.StringNumericLiteral).map(replaceFractionZeros).join('')
52
+ }
@@ -0,0 +1,22 @@
1
+ import type { Numberish, NumberString, Percentage } from './types'
2
+ import { isBigInt, isNumber, isString } from '../core'
3
+ import { SPECIAL_NUMBER_STRINGS } from './constants'
4
+
5
+ // eslint-disable-next-line security/detect-unsafe-regex -- anchored regex with no backtracking risk on bounded input
6
+ const NUMERIC_PATTERN = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/iu
7
+
8
+ export const isSpecialNumberString = (value: string) => SPECIAL_NUMBER_STRINGS.has(value)
9
+
10
+ export function isNumberString<TStrict extends boolean = true>(value: string): value is NumberString<TStrict> {
11
+ if (isSpecialNumberString(value)) {
12
+ return true
13
+ }
14
+
15
+ return NUMERIC_PATTERN.test(value)
16
+ }
17
+
18
+ export const isNumberish = <TStrict extends boolean = true>(input: unknown): input is Numberish<TStrict> => (
19
+ isNumber(input) || isBigInt(input) || (isString(input) && isNumberString(input))
20
+ )
21
+
22
+ export const isPercentage = (value: number): value is Percentage => value >= 0 && value <= 100
@@ -0,0 +1,10 @@
1
+ export * from './bigint-math'
2
+ export * from './constants'
3
+ export * from './conversions'
4
+ export * from './factories'
5
+ export * from './formats'
6
+ export * from './guards'
7
+ export * from './maths'
8
+ export * from './ranges'
9
+
10
+ export type * from './types'
@@ -0,0 +1,28 @@
1
+ import { transform } from '../functions'
2
+
3
+ export const sum = (array: number[]) => array.reduce((a, b) => a + b, 0)
4
+
5
+ export const avg = (array: number[]) => (array.length === 0 ? 0 : sum(array) / array.length)
6
+
7
+ export const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max)
8
+
9
+ export const roundTo = (value: number, decimals: number) => (
10
+ transform(10 ** decimals, (factor) => Math.round(value * factor) / factor)
11
+ )
12
+
13
+ export const lerp = (start: number, end: number, t: number) => start + (end - start) * t
14
+
15
+ export function median(array: number[]) {
16
+ if (array.length === 0) {
17
+ return 0
18
+ }
19
+
20
+ const sorted = [...array].toSorted((a, b) => a - b)
21
+ const mid = Math.floor(sorted.length / 2)
22
+
23
+ if (sorted.length % 2 === 0) {
24
+ return (sorted[mid - 1]! + sorted[mid]!) / 2
25
+ }
26
+
27
+ return sorted[mid]!
28
+ }
@@ -0,0 +1,17 @@
1
+ import { notNullish } from '../core'
2
+
3
+ export function isValidRange<T extends bigint | number>(start: T, end: T, inclusive = true, min?: T, max?: T) {
4
+ if (notNullish(min) && start < min) {
5
+ return false
6
+ }
7
+
8
+ if (notNullish(max) && end > max) {
9
+ return false
10
+ }
11
+
12
+ return inclusive ? start <= end : start < end
13
+ }
14
+
15
+ export const isInRange = <T extends bigint | number>(value: T, min: T, max: T, inclusive = true) => (
16
+ inclusive ? value >= min && value <= max : value > min && value < max
17
+ )
@@ -0,0 +1,7 @@
1
+ export type SpecialNumberString = '+Infinity' | '-Infinity' | 'Infinity' | 'NaN'
2
+
3
+ export type NumberString<TStrict extends boolean = false> = SpecialNumberString | (TStrict extends true ? `${number}` : string)
4
+
5
+ export type Numberish<TStrict extends boolean = false> = NumberString<TStrict> | bigint | number
6
+
7
+ export type Percentage = { __brand: 'Percentage' } & number
@@ -0,0 +1,76 @@
1
+ import type { AnyObject, DeepPartial } from './types'
2
+ import { isArray } from '../arrays'
3
+ import { unique } from '../arrays/set-operations'
4
+ import { isPlainObject } from './guards'
5
+
6
+ export type DeepMergeArrayMode = 'merge' | 'merge-dedupe' | 'replace'
7
+
8
+ export interface DeepMergeOptions {
9
+ arrayMode?: DeepMergeArrayMode
10
+ }
11
+
12
+ const DANGEROUS_KEYS = new Set(['__proto__', 'constructor', 'prototype'])
13
+
14
+ function mergeArrays(base: unknown[], override: unknown[], arrayMode: DeepMergeArrayMode): unknown[] {
15
+ if (arrayMode === 'replace') {
16
+ return override.map(deepCloneValue)
17
+ }
18
+
19
+ const merged = [...base, ...override]
20
+ const deduped = arrayMode === 'merge-dedupe' ? unique(merged) : merged
21
+
22
+ return deduped.map(deepCloneValue)
23
+ }
24
+
25
+ function deepCloneValue(value: unknown): unknown {
26
+ if (isPlainObject(value)) {
27
+ const cloned: Record<string, unknown> = {}
28
+
29
+ for (const key of Object.keys(value)) {
30
+ if (!DANGEROUS_KEYS.has(key)) {
31
+ cloned[key] = deepCloneValue(value[key])
32
+ }
33
+ }
34
+
35
+ return cloned
36
+ }
37
+
38
+ if (isArray(value)) {
39
+ return value.map(deepCloneValue)
40
+ }
41
+
42
+ return value
43
+ }
44
+
45
+ function mergeRecursive(base: Record<string, unknown>, override: Record<string, unknown>, arrayMode: DeepMergeArrayMode): Record<string, unknown> {
46
+ const result: Record<string, unknown> = {}
47
+
48
+ for (const key of Object.keys(base)) {
49
+ if (!DANGEROUS_KEYS.has(key)) {
50
+ result[key] = deepCloneValue(base[key])
51
+ }
52
+ }
53
+
54
+ for (const key of Object.keys(override)) {
55
+ if (DANGEROUS_KEYS.has(key)) {
56
+ continue
57
+ }
58
+
59
+ const baseVal = result[key]
60
+ const overrideVal = override[key]
61
+
62
+ if (isPlainObject(baseVal) && isPlainObject(overrideVal)) {
63
+ result[key] = mergeRecursive(baseVal, overrideVal, arrayMode)
64
+ } else if (isArray(baseVal) && isArray(overrideVal)) {
65
+ result[key] = mergeArrays(baseVal, overrideVal, arrayMode)
66
+ } else {
67
+ result[key] = deepCloneValue(overrideVal)
68
+ }
69
+ }
70
+
71
+ return result
72
+ }
73
+
74
+ export const deepMerge = <T extends AnyObject>(base: T, override: DeepPartial<T>, { arrayMode = 'replace' }: DeepMergeOptions = {}): T => (
75
+ mergeRecursive(base, override as Record<string, unknown>, arrayMode) as T
76
+ )
@@ -0,0 +1,21 @@
1
+ import type { AnyObject, UnknownObject } from './types'
2
+ import { isArray } from '../arrays'
3
+ import { toString } from '../core'
4
+
5
+ export const isObject = (value: unknown): value is AnyObject => value !== null && typeof value === 'object' && !isArray(value)
6
+
7
+ export const isPlainObject = (value: unknown): value is UnknownObject => {
8
+ if (toString(value) !== '[object Object]') {
9
+ return false
10
+ }
11
+
12
+ const proto = Object.getPrototypeOf(value)
13
+
14
+ return proto === null || proto === Object.prototype
15
+ }
16
+
17
+ export const isEmptyObject = (value: AnyObject) => Object.keys(value).length === 0
18
+
19
+ export const isKeyOf = <T extends AnyObject>(obj: T, name: PropertyKey): name is keyof T => name in obj
20
+
21
+ export const isKeysOf = <T extends PropertyKey>(data: AnyObject, ...keys: T[]): data is Record<T, unknown> => keys.every((key) => isKeyOf(data, key))
@@ -0,0 +1,5 @@
1
+ export * from './deep-merge'
2
+ export * from './guards'
3
+ export * from './transformations'
4
+
5
+ export type * from './types'
@@ -0,0 +1,34 @@
1
+ import type { AnyObject, FilterPredicate } from './types'
2
+ import { isNullish, type Nullish } from '../core'
3
+
4
+ export const entries = <O extends AnyObject>(obj: O) => Object.entries(obj) as Array<[keyof O, O[keyof O]]>
5
+
6
+ export const filter = <O extends AnyObject>(obj: O, predicate: FilterPredicate<O, keyof O>): Partial<O> => (
7
+ Object.fromEntries(entries(obj).filter(([key, value], index) => predicate(key, value, index))) as Partial<O>
8
+ )
9
+
10
+ export const filterByValue = <O extends AnyObject>(obj: O, predicate: (value: O[keyof O]) => boolean) => filter(obj, (_, value) => predicate(value))
11
+
12
+ export const pick = <O extends AnyObject, K extends keyof O>(obj: O, ...keys: K[]) => {
13
+ const set = new Set<PropertyKey>(keys)
14
+
15
+ return filter(obj, (key) => set.has(key)) as Pick<O, K>
16
+ }
17
+
18
+ export const omit = <O extends AnyObject, K extends keyof O>(object: O, ...keys: K[]) => {
19
+ const set = new Set<PropertyKey>(keys)
20
+
21
+ return filter(object, (key) => !set.has(key)) as Omit<O, K>
22
+ }
23
+
24
+ export const map = <K extends PropertyKey, V, NK extends PropertyKey, NV>(obj: Record<K, V>, fn: (k: K, v: V, i: number) => [NK, NV]) => (
25
+ Object.fromEntries(entries(obj).map(([k, v], i) => fn(k, v, i))) as Record<NK, NV>
26
+ )
27
+
28
+ export function resolveOptions<T extends AnyObject>(options: Nullish<T | boolean>, defaultValue: T | false): T | false {
29
+ if (options === false) {
30
+ return false
31
+ }
32
+
33
+ return isNullish(options) || options === true ? defaultValue : options
34
+ }
@@ -0,0 +1,33 @@
1
+ import type { Primitive } from '../core'
2
+
3
+ export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
4
+
5
+ export type RequiredBy<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>
6
+
7
+ export type Mutable<T> = { -readonly [K in keyof T]: T[K] }
8
+
9
+ export type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T
10
+
11
+ export type DeepReadonly<T> = T extends Primitive ? T : T extends Array<infer U> ? ReadonlyArray<DeepReadonly<U>> : { readonly [K in keyof T]: DeepReadonly<T[K]> }
12
+
13
+ export type KeysOfType<T, V> = { [K in keyof T]-?: T[K] extends V ? K : never }[keyof T]
14
+
15
+ export type StringKeys<T> = Extract<keyof T, string>
16
+
17
+ export type Dictionary<T = unknown> = Record<string, T>
18
+
19
+ export type DiscriminateUnion<T, K extends keyof T, V extends T[K]> = T extends Record<K, V> ? T : never
20
+
21
+ export type AnyObject = Record<string, any>
22
+
23
+ export type UnknownObject = Record<string, unknown>
24
+
25
+ export type Constructor<T> = new (...args: any[]) => T
26
+
27
+ export type ClassMethods<T> = { [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never }[keyof T]
28
+
29
+ export type ClassMethodArgs<T, M extends ClassMethods<T>> = T[M] extends (...args: infer A) => any ? A : never
30
+
31
+ export type ClassMethodReturn<T, M extends ClassMethods<T>> = T[M] extends (...args: any[]) => infer R ? R : never
32
+
33
+ export type FilterPredicate<O, K extends keyof O> = (key: K, value: O[K], index: number) => boolean
@@ -0,0 +1,37 @@
1
+ import { createAbortError, ensureError, type Errorable } from '../errors'
2
+
3
+ export function abortable<T>(promise: Promise<T>, signal?: AbortSignal, error?: Errorable): Promise<T> {
4
+ if (!signal) {
5
+ return promise
6
+ }
7
+
8
+ const createError = () => (error ? ensureError(error) : (signal.reason ?? createAbortError()))
9
+
10
+ if (signal.aborted) {
11
+ return Promise.reject(createError())
12
+ }
13
+
14
+ return new Promise<T>((resolve, reject) => {
15
+ let isSettled = false
16
+ let onAbort: () => void
17
+
18
+ const cleanup = (afterCleanup?: () => void) => {
19
+ if (!isSettled) {
20
+ isSettled = true
21
+ signal.removeEventListener('abort', onAbort)
22
+ afterCleanup?.()
23
+ }
24
+ }
25
+
26
+ onAbort = () => {
27
+ cleanup(() => reject(createError()))
28
+ }
29
+
30
+ signal.addEventListener('abort', onAbort)
31
+
32
+ promise.then(
33
+ (value) => cleanup(() => resolve(value)),
34
+ (error_) => cleanup(() => reject(error_)),
35
+ )
36
+ })
37
+ }
@@ -0,0 +1,18 @@
1
+ import type { Awaitable } from './types'
2
+
3
+ export const pTap = <T>(fn: (value: T) => Awaitable<unknown>) => async (value: T): Promise<T> => {
4
+ return Promise.resolve(fn(value)).then(() => value)
5
+ }
6
+
7
+ pTap.catch = (fn: (error: unknown) => Awaitable<unknown>) => async (error: unknown): Promise<never> => {
8
+ await fn(error)
9
+ throw error
10
+ }
11
+
12
+ export async function tryCatchAsync<T>(fn: () => Awaitable<T>, fallback: (error: unknown) => Awaitable<T>) {
13
+ try {
14
+ return await fn()
15
+ } catch (error) {
16
+ return await fallback(error)
17
+ }
18
+ }
@@ -0,0 +1,131 @@
1
+ import { combineSignals, createAbortController, createAbortError, type Errorable } from '../errors'
2
+
3
+ export interface DeferredPromiseOptions<T> {
4
+ onCallbackError?: (error: unknown) => void
5
+ onReject?: (reason: unknown) => void
6
+ onResolve?: (value: PromiseLike<T> | T) => void
7
+ onSettle?: () => void
8
+ signal?: AbortSignal
9
+ synchronousCallbacks?: boolean
10
+ }
11
+
12
+ export interface DeferredPromise<T> extends Promise<T> {
13
+ isPending: boolean
14
+ isRejected: boolean
15
+ isResolved: boolean
16
+ isSettled: boolean
17
+ reject: (reason?: unknown) => void
18
+ resolve: (value: PromiseLike<T> | T) => void
19
+ }
20
+
21
+ export function cleanupAbortSignal(signal: AbortSignal | undefined, abortHandler: (() => void) | undefined) {
22
+ if (abortHandler) {
23
+ signal?.removeEventListener('abort', abortHandler)
24
+ }
25
+ }
26
+
27
+ export function setupAbortSignal(signal: AbortSignal | undefined, onAbort: () => void) {
28
+ const abortHandler = () => onAbort()
29
+
30
+ if (signal?.aborted) {
31
+ onAbort()
32
+ } else {
33
+ signal?.addEventListener('abort', abortHandler)
34
+ }
35
+
36
+ return abortHandler
37
+ }
38
+
39
+ export function invokeSettleCallback(cb: () => void, onSettle: (() => void) | undefined, onCallbackError: ((error: unknown) => void) | undefined, synchronousCallbacks: boolean) {
40
+ const callback = () => {
41
+ try {
42
+ cb()
43
+ } catch (error) {
44
+ onCallbackError?.(error)
45
+ }
46
+
47
+ try {
48
+ onSettle?.()
49
+ } catch (error) {
50
+ onCallbackError?.(error)
51
+ }
52
+ }
53
+
54
+ if (synchronousCallbacks) {
55
+ callback()
56
+ } else {
57
+ queueMicrotask(callback)
58
+ }
59
+ }
60
+
61
+ export function createDeferred<T>({ onCallbackError, onReject, onResolve, onSettle, signal, synchronousCallbacks = false }: DeferredPromiseOptions<T> = {}): DeferredPromise<T> {
62
+ let resolveFn: (value: PromiseLike<T> | T) => void
63
+ let rejectFn: (reason?: unknown) => void
64
+ let abortHandler: (() => void) | undefined
65
+
66
+ let isSettled = false
67
+ let isResolved = false
68
+ let isRejected = false
69
+
70
+ const promise = <DeferredPromise<T>> new Promise<T>((resolve, reject) => {
71
+ resolveFn = resolve
72
+ rejectFn = reject
73
+ })
74
+
75
+ const afterSettle = (cb: () => void) => {
76
+ cleanupAbortSignal(signal, abortHandler)
77
+ invokeSettleCallback(cb, onSettle, onCallbackError, synchronousCallbacks)
78
+ }
79
+
80
+ Object.defineProperty(promise, 'isSettled', { enumerable: true, get: () => isSettled })
81
+ Object.defineProperty(promise, 'isPending', { enumerable: true, get: () => !isSettled })
82
+ Object.defineProperty(promise, 'isResolved', { enumerable: true, get: () => isResolved })
83
+ Object.defineProperty(promise, 'isRejected', { enumerable: true, get: () => isRejected })
84
+
85
+ promise.resolve = (value: PromiseLike<T> | T) => {
86
+ if (isSettled) {
87
+ return
88
+ }
89
+
90
+ isSettled = true
91
+ isResolved = true
92
+
93
+ resolveFn(value)
94
+ afterSettle(() => onResolve?.(value))
95
+ }
96
+
97
+ promise.reject = (reason?: unknown) => {
98
+ if (isSettled) {
99
+ return
100
+ }
101
+
102
+ isSettled = true
103
+ isRejected = true
104
+
105
+ rejectFn(reason)
106
+ afterSettle(() => onReject?.(reason))
107
+ }
108
+
109
+ abortHandler = setupAbortSignal(signal, () => {
110
+ promise.reject(signal?.reason ?? createAbortError())
111
+ })
112
+
113
+ return promise
114
+ }
115
+
116
+ export interface DeferredPromiseWithTimeoutOptions<T> extends DeferredPromiseOptions<T> {
117
+ error?: Errorable
118
+ }
119
+
120
+ export const createDeferredWithTimeout = <T>(ms: number, { error, signal, ...options }: DeferredPromiseWithTimeoutOptions<T> = {}) => {
121
+ const timeoutController = createAbortController(ms, error)
122
+
123
+ return createDeferred<T>({
124
+ ...options,
125
+ onSettle() {
126
+ timeoutController.abort()
127
+ options.onSettle?.()
128
+ },
129
+ signal: combineSignals(signal, timeoutController.signal),
130
+ })
131
+ }
@@ -0,0 +1,8 @@
1
+ import { isFunction } from '../functions'
2
+ import { isObject } from '../objects'
3
+
4
+ export const isPromiseLike = <T>(value: unknown): value is PromiseLike<T> => isObject(value) && isFunction(value.then)
5
+
6
+ export const isPromise = <T>(value: unknown): value is Promise<T> => (
7
+ isObject(value) && isFunction(value.then) && isFunction(value.catch) && isFunction(value.finally)
8
+ )
@@ -0,0 +1,10 @@
1
+ export * from './abortable'
2
+ export * from './compositions'
3
+ export * from './deferred'
4
+ export * from './guards'
5
+ export * from './pipe'
6
+ export * from './poll'
7
+ export * from './retry'
8
+ export * from './timers'
9
+
10
+ export type * from './types'