ts-data-forge 3.2.0 → 3.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (426) hide show
  1. package/README.md +45 -21
  2. package/dist/array/impl/array-utils-creation.d.mts +116 -0
  3. package/dist/array/impl/array-utils-creation.d.mts.map +1 -0
  4. package/dist/array/impl/array-utils-creation.mjs +110 -0
  5. package/dist/array/impl/array-utils-creation.mjs.map +1 -0
  6. package/dist/array/impl/array-utils-element-access.d.mts +61 -0
  7. package/dist/array/impl/array-utils-element-access.d.mts.map +1 -0
  8. package/dist/array/impl/array-utils-element-access.mjs +66 -0
  9. package/dist/array/impl/array-utils-element-access.mjs.map +1 -0
  10. package/dist/array/impl/array-utils-iterators.d.mts +59 -0
  11. package/dist/array/impl/array-utils-iterators.d.mts.map +1 -0
  12. package/dist/array/impl/array-utils-iterators.mjs +104 -0
  13. package/dist/array/impl/array-utils-iterators.mjs.map +1 -0
  14. package/dist/array/impl/array-utils-modification.d.mts +154 -0
  15. package/dist/array/impl/array-utils-modification.d.mts.map +1 -0
  16. package/dist/array/impl/array-utils-modification.mjs +139 -0
  17. package/dist/array/impl/array-utils-modification.mjs.map +1 -0
  18. package/dist/array/impl/array-utils-reducing-value.d.mts +214 -0
  19. package/dist/array/impl/array-utils-reducing-value.d.mts.map +1 -0
  20. package/dist/array/impl/array-utils-reducing-value.mjs +160 -0
  21. package/dist/array/impl/array-utils-reducing-value.mjs.map +1 -0
  22. package/dist/array/impl/array-utils-search.d.mts +179 -0
  23. package/dist/array/impl/array-utils-search.d.mts.map +1 -0
  24. package/dist/array/impl/array-utils-search.mjs +153 -0
  25. package/dist/array/impl/array-utils-search.mjs.map +1 -0
  26. package/dist/array/impl/array-utils-set-op.d.mts +100 -0
  27. package/dist/array/impl/array-utils-set-op.d.mts.map +1 -0
  28. package/dist/array/impl/array-utils-set-op.mjs +137 -0
  29. package/dist/array/impl/array-utils-set-op.mjs.map +1 -0
  30. package/dist/array/impl/array-utils-size.d.mts +24 -0
  31. package/dist/array/impl/array-utils-size.d.mts.map +1 -0
  32. package/dist/array/impl/array-utils-size.mjs +28 -0
  33. package/dist/array/impl/array-utils-size.mjs.map +1 -0
  34. package/dist/array/impl/array-utils-slice-clamped.d.mts +18 -0
  35. package/dist/array/impl/array-utils-slice-clamped.d.mts.map +1 -0
  36. package/dist/array/impl/array-utils-slice-clamped.mjs +49 -0
  37. package/dist/array/impl/array-utils-slice-clamped.mjs.map +1 -0
  38. package/dist/array/impl/array-utils-slicing.d.mts +120 -0
  39. package/dist/array/impl/array-utils-slicing.d.mts.map +1 -0
  40. package/dist/array/impl/array-utils-slicing.mjs +140 -0
  41. package/dist/array/impl/array-utils-slicing.mjs.map +1 -0
  42. package/dist/array/impl/array-utils-transformation.d.mts +348 -0
  43. package/dist/array/impl/array-utils-transformation.d.mts.map +1 -0
  44. package/dist/array/impl/array-utils-transformation.mjs +331 -0
  45. package/dist/array/impl/array-utils-transformation.mjs.map +1 -0
  46. package/dist/array/impl/array-utils-validation.d.mts +149 -0
  47. package/dist/array/impl/array-utils-validation.d.mts.map +1 -0
  48. package/dist/array/impl/array-utils-validation.mjs +166 -0
  49. package/dist/array/impl/array-utils-validation.mjs.map +1 -0
  50. package/dist/array/impl/index.d.mts +13 -0
  51. package/dist/array/impl/index.d.mts.map +1 -0
  52. package/dist/array/impl/index.mjs +13 -0
  53. package/dist/array/impl/index.mjs.map +1 -0
  54. package/dist/array/index.d.mts +1 -1
  55. package/dist/array/index.d.mts.map +1 -1
  56. package/dist/array/index.mjs +2 -1
  57. package/dist/array/index.mjs.map +1 -1
  58. package/dist/collections/imap-mapped.d.mts +83 -253
  59. package/dist/collections/imap-mapped.d.mts.map +1 -1
  60. package/dist/collections/imap-mapped.mjs +33 -164
  61. package/dist/collections/imap-mapped.mjs.map +1 -1
  62. package/dist/collections/imap.d.mts +436 -163
  63. package/dist/collections/imap.d.mts.map +1 -1
  64. package/dist/collections/imap.mjs +74 -94
  65. package/dist/collections/imap.mjs.map +1 -1
  66. package/dist/collections/iset-mapped.d.mts +828 -345
  67. package/dist/collections/iset-mapped.d.mts.map +1 -1
  68. package/dist/collections/iset-mapped.mjs +200 -242
  69. package/dist/collections/iset-mapped.mjs.map +1 -1
  70. package/dist/collections/iset.d.mts +397 -205
  71. package/dist/collections/iset.d.mts.map +1 -1
  72. package/dist/collections/iset.mjs +102 -184
  73. package/dist/collections/iset.mjs.map +1 -1
  74. package/dist/collections/queue.d.mts +155 -135
  75. package/dist/collections/queue.d.mts.map +1 -1
  76. package/dist/collections/queue.mjs +55 -156
  77. package/dist/collections/queue.mjs.map +1 -1
  78. package/dist/collections/stack.d.mts +154 -154
  79. package/dist/collections/stack.d.mts.map +1 -1
  80. package/dist/collections/stack.mjs +54 -203
  81. package/dist/collections/stack.mjs.map +1 -1
  82. package/dist/entry-point.d.mts +3 -0
  83. package/dist/entry-point.d.mts.map +1 -0
  84. package/dist/entry-point.mjs +62 -0
  85. package/dist/entry-point.mjs.map +1 -0
  86. package/dist/expect-type.d.mts +43 -172
  87. package/dist/expect-type.d.mts.map +1 -1
  88. package/dist/expect-type.mjs +43 -172
  89. package/dist/expect-type.mjs.map +1 -1
  90. package/dist/functional/match.d.mts +35 -140
  91. package/dist/functional/match.d.mts.map +1 -1
  92. package/dist/functional/match.mjs.map +1 -1
  93. package/dist/functional/optional.d.mts +282 -160
  94. package/dist/functional/optional.d.mts.map +1 -1
  95. package/dist/functional/optional.mjs +131 -71
  96. package/dist/functional/optional.mjs.map +1 -1
  97. package/dist/functional/pipe.d.mts +59 -113
  98. package/dist/functional/pipe.d.mts.map +1 -1
  99. package/dist/functional/pipe.mjs.map +1 -1
  100. package/dist/functional/result.d.mts +433 -332
  101. package/dist/functional/result.d.mts.map +1 -1
  102. package/dist/functional/result.mjs +233 -239
  103. package/dist/functional/result.mjs.map +1 -1
  104. package/dist/globals.d.mts +12 -5
  105. package/dist/guard/has-key.d.mts +23 -74
  106. package/dist/guard/has-key.d.mts.map +1 -1
  107. package/dist/guard/has-key.mjs +23 -74
  108. package/dist/guard/has-key.mjs.map +1 -1
  109. package/dist/guard/is-non-empty-string.d.mts +20 -87
  110. package/dist/guard/is-non-empty-string.d.mts.map +1 -1
  111. package/dist/guard/is-non-empty-string.mjs +20 -87
  112. package/dist/guard/is-non-empty-string.mjs.map +1 -1
  113. package/dist/guard/is-non-null-object.d.mts +14 -84
  114. package/dist/guard/is-non-null-object.d.mts.map +1 -1
  115. package/dist/guard/is-non-null-object.mjs +14 -84
  116. package/dist/guard/is-non-null-object.mjs.map +1 -1
  117. package/dist/guard/is-primitive.d.mts +13 -126
  118. package/dist/guard/is-primitive.d.mts.map +1 -1
  119. package/dist/guard/is-primitive.mjs +13 -126
  120. package/dist/guard/is-primitive.mjs.map +1 -1
  121. package/dist/guard/is-record.d.mts +21 -132
  122. package/dist/guard/is-record.d.mts.map +1 -1
  123. package/dist/guard/is-record.mjs +21 -132
  124. package/dist/guard/is-record.mjs.map +1 -1
  125. package/dist/guard/is-type.d.mts +201 -238
  126. package/dist/guard/is-type.d.mts.map +1 -1
  127. package/dist/guard/is-type.mjs +201 -238
  128. package/dist/guard/is-type.mjs.map +1 -1
  129. package/dist/guard/key-is-in.d.mts +22 -139
  130. package/dist/guard/key-is-in.d.mts.map +1 -1
  131. package/dist/guard/key-is-in.mjs +22 -139
  132. package/dist/guard/key-is-in.mjs.map +1 -1
  133. package/dist/index.d.mts +0 -1
  134. package/dist/index.d.mts.map +1 -1
  135. package/dist/index.mjs +0 -1
  136. package/dist/index.mjs.map +1 -1
  137. package/dist/iterator/range.d.mts +29 -62
  138. package/dist/iterator/range.d.mts.map +1 -1
  139. package/dist/iterator/range.mjs.map +1 -1
  140. package/dist/json/json.d.mts +191 -121
  141. package/dist/json/json.d.mts.map +1 -1
  142. package/dist/json/json.mjs +238 -136
  143. package/dist/json/json.mjs.map +1 -1
  144. package/dist/number/branded-types/finite-number.d.mts +24 -156
  145. package/dist/number/branded-types/finite-number.d.mts.map +1 -1
  146. package/dist/number/branded-types/finite-number.mjs +27 -159
  147. package/dist/number/branded-types/finite-number.mjs.map +1 -1
  148. package/dist/number/branded-types/int.d.mts +122 -120
  149. package/dist/number/branded-types/int.d.mts.map +1 -1
  150. package/dist/number/branded-types/int.mjs +122 -120
  151. package/dist/number/branded-types/int.mjs.map +1 -1
  152. package/dist/number/branded-types/int16.d.mts +22 -30
  153. package/dist/number/branded-types/int16.d.mts.map +1 -1
  154. package/dist/number/branded-types/int16.mjs +22 -30
  155. package/dist/number/branded-types/int16.mjs.map +1 -1
  156. package/dist/number/branded-types/int32.d.mts +22 -31
  157. package/dist/number/branded-types/int32.d.mts.map +1 -1
  158. package/dist/number/branded-types/int32.mjs +22 -31
  159. package/dist/number/branded-types/int32.mjs.map +1 -1
  160. package/dist/number/branded-types/non-negative-finite-number.d.mts +28 -36
  161. package/dist/number/branded-types/non-negative-finite-number.d.mts.map +1 -1
  162. package/dist/number/branded-types/non-negative-finite-number.mjs +31 -39
  163. package/dist/number/branded-types/non-negative-finite-number.mjs.map +1 -1
  164. package/dist/number/branded-types/non-negative-int16.d.mts +24 -34
  165. package/dist/number/branded-types/non-negative-int16.d.mts.map +1 -1
  166. package/dist/number/branded-types/non-negative-int16.mjs +24 -34
  167. package/dist/number/branded-types/non-negative-int16.mjs.map +1 -1
  168. package/dist/number/branded-types/non-negative-int32.d.mts +26 -35
  169. package/dist/number/branded-types/non-negative-int32.d.mts.map +1 -1
  170. package/dist/number/branded-types/non-negative-int32.mjs +26 -35
  171. package/dist/number/branded-types/non-negative-int32.mjs.map +1 -1
  172. package/dist/number/branded-types/non-zero-finite-number.d.mts +22 -37
  173. package/dist/number/branded-types/non-zero-finite-number.d.mts.map +1 -1
  174. package/dist/number/branded-types/non-zero-finite-number.mjs +25 -40
  175. package/dist/number/branded-types/non-zero-finite-number.mjs.map +1 -1
  176. package/dist/number/branded-types/non-zero-int.d.mts +15 -30
  177. package/dist/number/branded-types/non-zero-int.d.mts.map +1 -1
  178. package/dist/number/branded-types/non-zero-int.mjs +15 -30
  179. package/dist/number/branded-types/non-zero-int.mjs.map +1 -1
  180. package/dist/number/branded-types/non-zero-int16.d.mts +27 -35
  181. package/dist/number/branded-types/non-zero-int16.d.mts.map +1 -1
  182. package/dist/number/branded-types/non-zero-int16.mjs +27 -35
  183. package/dist/number/branded-types/non-zero-int16.mjs.map +1 -1
  184. package/dist/number/branded-types/non-zero-int32.d.mts +29 -36
  185. package/dist/number/branded-types/non-zero-int32.d.mts.map +1 -1
  186. package/dist/number/branded-types/non-zero-int32.mjs +29 -36
  187. package/dist/number/branded-types/non-zero-int32.mjs.map +1 -1
  188. package/dist/number/branded-types/non-zero-safe-int.d.mts +37 -38
  189. package/dist/number/branded-types/non-zero-safe-int.d.mts.map +1 -1
  190. package/dist/number/branded-types/non-zero-safe-int.mjs +39 -40
  191. package/dist/number/branded-types/non-zero-safe-int.mjs.map +1 -1
  192. package/dist/number/branded-types/non-zero-uint16.d.mts +24 -35
  193. package/dist/number/branded-types/non-zero-uint16.d.mts.map +1 -1
  194. package/dist/number/branded-types/non-zero-uint16.mjs +24 -35
  195. package/dist/number/branded-types/non-zero-uint16.mjs.map +1 -1
  196. package/dist/number/branded-types/non-zero-uint32.d.mts +24 -35
  197. package/dist/number/branded-types/non-zero-uint32.d.mts.map +1 -1
  198. package/dist/number/branded-types/non-zero-uint32.mjs +24 -35
  199. package/dist/number/branded-types/non-zero-uint32.mjs.map +1 -1
  200. package/dist/number/branded-types/positive-finite-number.d.mts +26 -40
  201. package/dist/number/branded-types/positive-finite-number.d.mts.map +1 -1
  202. package/dist/number/branded-types/positive-finite-number.mjs +29 -43
  203. package/dist/number/branded-types/positive-finite-number.mjs.map +1 -1
  204. package/dist/number/branded-types/positive-int.d.mts +133 -123
  205. package/dist/number/branded-types/positive-int.d.mts.map +1 -1
  206. package/dist/number/branded-types/positive-int.mjs +133 -123
  207. package/dist/number/branded-types/positive-int.mjs.map +1 -1
  208. package/dist/number/branded-types/positive-int16.d.mts +24 -35
  209. package/dist/number/branded-types/positive-int16.d.mts.map +1 -1
  210. package/dist/number/branded-types/positive-int16.mjs +24 -35
  211. package/dist/number/branded-types/positive-int16.mjs.map +1 -1
  212. package/dist/number/branded-types/positive-int32.d.mts +24 -35
  213. package/dist/number/branded-types/positive-int32.d.mts.map +1 -1
  214. package/dist/number/branded-types/positive-int32.mjs +24 -35
  215. package/dist/number/branded-types/positive-int32.mjs.map +1 -1
  216. package/dist/number/branded-types/positive-safe-int.d.mts +159 -33
  217. package/dist/number/branded-types/positive-safe-int.d.mts.map +1 -1
  218. package/dist/number/branded-types/positive-safe-int.mjs +160 -34
  219. package/dist/number/branded-types/positive-safe-int.mjs.map +1 -1
  220. package/dist/number/branded-types/positive-uint16.d.mts +24 -35
  221. package/dist/number/branded-types/positive-uint16.d.mts.map +1 -1
  222. package/dist/number/branded-types/positive-uint16.mjs +24 -35
  223. package/dist/number/branded-types/positive-uint16.mjs.map +1 -1
  224. package/dist/number/branded-types/positive-uint32.d.mts +26 -36
  225. package/dist/number/branded-types/positive-uint32.d.mts.map +1 -1
  226. package/dist/number/branded-types/positive-uint32.mjs +26 -36
  227. package/dist/number/branded-types/positive-uint32.mjs.map +1 -1
  228. package/dist/number/branded-types/safe-int.d.mts +140 -99
  229. package/dist/number/branded-types/safe-int.d.mts.map +1 -1
  230. package/dist/number/branded-types/safe-int.mjs +142 -101
  231. package/dist/number/branded-types/safe-int.mjs.map +1 -1
  232. package/dist/number/branded-types/safe-uint.d.mts +24 -33
  233. package/dist/number/branded-types/safe-uint.d.mts.map +1 -1
  234. package/dist/number/branded-types/safe-uint.mjs +25 -34
  235. package/dist/number/branded-types/safe-uint.mjs.map +1 -1
  236. package/dist/number/branded-types/uint.d.mts +121 -30
  237. package/dist/number/branded-types/uint.d.mts.map +1 -1
  238. package/dist/number/branded-types/uint.mjs +121 -30
  239. package/dist/number/branded-types/uint.mjs.map +1 -1
  240. package/dist/number/branded-types/uint16.d.mts +26 -34
  241. package/dist/number/branded-types/uint16.d.mts.map +1 -1
  242. package/dist/number/branded-types/uint16.mjs +26 -34
  243. package/dist/number/branded-types/uint16.mjs.map +1 -1
  244. package/dist/number/branded-types/uint32.d.mts +26 -68
  245. package/dist/number/branded-types/uint32.d.mts.map +1 -1
  246. package/dist/number/branded-types/uint32.mjs +26 -68
  247. package/dist/number/branded-types/uint32.mjs.map +1 -1
  248. package/dist/number/enum/int8.d.mts +37 -101
  249. package/dist/number/enum/int8.d.mts.map +1 -1
  250. package/dist/number/enum/int8.mjs +39 -170
  251. package/dist/number/enum/int8.mjs.map +1 -1
  252. package/dist/number/enum/uint8.d.mts +45 -55
  253. package/dist/number/enum/uint8.d.mts.map +1 -1
  254. package/dist/number/enum/uint8.mjs +46 -155
  255. package/dist/number/enum/uint8.mjs.map +1 -1
  256. package/dist/number/num.d.mts +145 -206
  257. package/dist/number/num.d.mts.map +1 -1
  258. package/dist/number/num.mjs +143 -199
  259. package/dist/number/num.mjs.map +1 -1
  260. package/dist/number/refined-number-utils.d.mts +97 -21
  261. package/dist/number/refined-number-utils.d.mts.map +1 -1
  262. package/dist/number/refined-number-utils.mjs +91 -20
  263. package/dist/number/refined-number-utils.mjs.map +1 -1
  264. package/dist/object/object.d.mts +126 -208
  265. package/dist/object/object.d.mts.map +1 -1
  266. package/dist/object/object.mjs +68 -102
  267. package/dist/object/object.mjs.map +1 -1
  268. package/dist/others/cast-mutable.d.mts +12 -88
  269. package/dist/others/cast-mutable.d.mts.map +1 -1
  270. package/dist/others/cast-mutable.mjs +13 -89
  271. package/dist/others/cast-mutable.mjs.map +1 -1
  272. package/dist/others/cast-readonly.d.mts +12 -168
  273. package/dist/others/cast-readonly.d.mts.map +1 -1
  274. package/dist/others/cast-readonly.mjs +13 -169
  275. package/dist/others/cast-readonly.mjs.map +1 -1
  276. package/dist/others/if-then.d.mts +6 -83
  277. package/dist/others/if-then.d.mts.map +1 -1
  278. package/dist/others/if-then.mjs +6 -83
  279. package/dist/others/if-then.mjs.map +1 -1
  280. package/dist/others/map-nullable.d.mts +12 -136
  281. package/dist/others/map-nullable.d.mts.map +1 -1
  282. package/dist/others/map-nullable.mjs.map +1 -1
  283. package/dist/others/memoize-function.d.mts +14 -157
  284. package/dist/others/memoize-function.d.mts.map +1 -1
  285. package/dist/others/memoize-function.mjs +14 -157
  286. package/dist/others/memoize-function.mjs.map +1 -1
  287. package/dist/others/tuple.d.mts +33 -151
  288. package/dist/others/tuple.d.mts.map +1 -1
  289. package/dist/others/tuple.mjs +33 -151
  290. package/dist/others/tuple.mjs.map +1 -1
  291. package/dist/others/unknown-to-string.d.mts +11 -125
  292. package/dist/others/unknown-to-string.d.mts.map +1 -1
  293. package/dist/others/unknown-to-string.mjs +14 -127
  294. package/dist/others/unknown-to-string.mjs.map +1 -1
  295. package/dist/promise/promise.d.mts +33 -20
  296. package/dist/promise/promise.d.mts.map +1 -1
  297. package/dist/promise/promise.mjs +34 -21
  298. package/dist/promise/promise.mjs.map +1 -1
  299. package/dist/types.d.mts +1 -1
  300. package/package.json +54 -50
  301. package/src/array/impl/array-utils-creation.mts +192 -0
  302. package/src/array/{array-utils-creation.test.mts → impl/array-utils-creation.test.mts} +121 -72
  303. package/src/array/impl/array-utils-element-access.mts +115 -0
  304. package/src/array/impl/array-utils-element-access.test.mts +151 -0
  305. package/src/array/impl/array-utils-iterators.mts +79 -0
  306. package/src/array/impl/array-utils-iterators.test.mts +98 -0
  307. package/src/array/impl/array-utils-modification.mts +434 -0
  308. package/src/array/{array-utils-modification.test.mts → impl/array-utils-modification.test.mts} +41 -28
  309. package/src/array/{array-utils-overload-type-error.test.mts → impl/array-utils-overload-type-error.test.mts} +33 -33
  310. package/src/array/impl/array-utils-reducing-value.mts +551 -0
  311. package/src/array/{array-utils-reducing-value.test.mts → impl/array-utils-reducing-value.test.mts} +45 -50
  312. package/src/array/impl/array-utils-search.mts +509 -0
  313. package/src/array/impl/array-utils-search.test.mts +346 -0
  314. package/src/array/impl/array-utils-set-op.mts +166 -0
  315. package/src/array/{array-utils-set-op.test.mts → impl/array-utils-set-op.test.mts} +42 -35
  316. package/src/array/impl/array-utils-size.mts +30 -0
  317. package/src/array/impl/array-utils-size.test.mts +9 -0
  318. package/src/array/impl/array-utils-slice-clamped.mts +51 -0
  319. package/src/array/{array-utils-slice-clamped.test.mts → impl/array-utils-slice-clamped.test.mts} +12 -12
  320. package/src/array/impl/array-utils-slicing.mts +275 -0
  321. package/src/array/impl/array-utils-slicing.test.mts +158 -0
  322. package/src/array/impl/array-utils-transformation.mts +746 -0
  323. package/src/array/{array-utils-transformation.test.mts → impl/array-utils-transformation.test.mts} +662 -889
  324. package/src/array/impl/array-utils-validation.mts +241 -0
  325. package/src/array/{array-utils-validation.test.mts → impl/array-utils-validation.test.mts} +194 -107
  326. package/src/array/{array.test.mts → impl/array.test.mts} +2 -2
  327. package/src/array/impl/index.mts +12 -0
  328. package/src/array/index.mts +1 -1
  329. package/src/collections/imap-mapped.mts +99 -265
  330. package/src/collections/imap.mts +477 -174
  331. package/src/collections/imap.test.mts +12 -19
  332. package/src/collections/iset-mapped.mts +892 -358
  333. package/src/collections/iset.mts +429 -213
  334. package/src/collections/queue.mts +174 -200
  335. package/src/collections/stack.mts +172 -245
  336. package/src/collections/stack.test.mts +9 -1
  337. package/src/entry-point.mts +2 -0
  338. package/src/expect-type.mts +43 -172
  339. package/src/functional/match.mts +35 -145
  340. package/src/functional/optional.mts +285 -163
  341. package/src/functional/optional.test.mts +4 -1
  342. package/src/functional/pipe.mts +60 -113
  343. package/src/functional/result.mts +452 -351
  344. package/src/functional/result.test.mts +9 -2
  345. package/src/globals.d.mts +12 -5
  346. package/src/guard/has-key.mts +23 -74
  347. package/src/guard/is-non-empty-string.mts +20 -87
  348. package/src/guard/is-non-null-object.mts +14 -84
  349. package/src/guard/is-non-null-object.test.mts +1 -1
  350. package/src/guard/is-primitive.mts +13 -126
  351. package/src/guard/is-primitive.test.mts +1 -1
  352. package/src/guard/is-record.mts +21 -132
  353. package/src/guard/is-record.test.mts +0 -1
  354. package/src/guard/is-type.mts +201 -238
  355. package/src/guard/is-type.test.mts +7 -7
  356. package/src/guard/key-is-in.mts +22 -139
  357. package/src/index.mts +0 -1
  358. package/src/iterator/range.mts +29 -62
  359. package/src/json/json.mts +202 -134
  360. package/src/json/json.test.mts +1 -3
  361. package/src/number/branded-types/finite-number.mts +27 -159
  362. package/src/number/branded-types/int.mts +122 -120
  363. package/src/number/branded-types/int16.mts +22 -30
  364. package/src/number/branded-types/int16.test.mts +24 -24
  365. package/src/number/branded-types/int32.mts +22 -31
  366. package/src/number/branded-types/int32.test.mts +39 -39
  367. package/src/number/branded-types/non-negative-finite-number.mts +31 -39
  368. package/src/number/branded-types/non-negative-int16.mts +24 -34
  369. package/src/number/branded-types/non-negative-int16.test.mts +16 -16
  370. package/src/number/branded-types/non-negative-int32.mts +26 -35
  371. package/src/number/branded-types/non-negative-int32.test.mts +30 -30
  372. package/src/number/branded-types/non-zero-finite-number.mts +25 -40
  373. package/src/number/branded-types/non-zero-int.mts +15 -30
  374. package/src/number/branded-types/non-zero-int16.mts +27 -35
  375. package/src/number/branded-types/non-zero-int16.test.mts +26 -26
  376. package/src/number/branded-types/non-zero-int32.mts +29 -36
  377. package/src/number/branded-types/non-zero-int32.test.mts +45 -42
  378. package/src/number/branded-types/non-zero-safe-int.mts +39 -40
  379. package/src/number/branded-types/non-zero-uint16.mts +24 -35
  380. package/src/number/branded-types/non-zero-uint16.test.mts +16 -16
  381. package/src/number/branded-types/non-zero-uint32.mts +24 -35
  382. package/src/number/branded-types/non-zero-uint32.test.mts +28 -28
  383. package/src/number/branded-types/positive-finite-number.mts +29 -43
  384. package/src/number/branded-types/positive-int.mts +134 -124
  385. package/src/number/branded-types/positive-int16.mts +24 -35
  386. package/src/number/branded-types/positive-int16.test.mts +14 -14
  387. package/src/number/branded-types/positive-int32.mts +24 -35
  388. package/src/number/branded-types/positive-int32.test.mts +26 -26
  389. package/src/number/branded-types/positive-safe-int.mts +160 -34
  390. package/src/number/branded-types/positive-uint16.mts +24 -35
  391. package/src/number/branded-types/positive-uint16.test.mts +16 -16
  392. package/src/number/branded-types/positive-uint32.mts +26 -36
  393. package/src/number/branded-types/positive-uint32.test.mts +31 -28
  394. package/src/number/branded-types/safe-int.mts +142 -101
  395. package/src/number/branded-types/safe-uint.mts +25 -34
  396. package/src/number/branded-types/uint.mts +121 -30
  397. package/src/number/branded-types/uint16.mts +26 -34
  398. package/src/number/branded-types/uint16.test.mts +16 -16
  399. package/src/number/branded-types/uint32.mts +26 -68
  400. package/src/number/branded-types/uint32.test.mts +28 -28
  401. package/src/number/enum/int8.mts +39 -170
  402. package/src/number/enum/uint8.mts +46 -155
  403. package/src/number/num.mts +157 -212
  404. package/src/number/num.test.mts +4 -4
  405. package/src/number/refined-number-utils.mts +109 -26
  406. package/src/object/object.mts +130 -212
  407. package/src/object/object.test.mts +29 -0
  408. package/src/others/cast-mutable.mts +13 -89
  409. package/src/others/cast-mutable.test.mts +80 -0
  410. package/src/others/cast-readonly.mts +13 -169
  411. package/src/others/if-then.mts +6 -83
  412. package/src/others/map-nullable.mts +12 -136
  413. package/src/others/map-nullable.test.mts +6 -6
  414. package/src/others/memoize-function.mts +14 -157
  415. package/src/others/tuple.mts +33 -151
  416. package/src/others/unknown-to-string.mts +15 -127
  417. package/src/others/unknown-to-string.test.mts +14 -2
  418. package/src/promise/promise.mts +34 -21
  419. package/src/promise/promise.test.mts +43 -0
  420. package/dist/array/array-utils.d.mts +0 -2956
  421. package/dist/array/array-utils.d.mts.map +0 -1
  422. package/dist/array/array-utils.mjs +0 -1838
  423. package/dist/array/array-utils.mjs.map +0 -1
  424. package/src/array/array-utils-search.test.mts +0 -169
  425. package/src/array/array-utils-slicing.test.mts +0 -274
  426. package/src/array/array-utils.mts +0 -4834
@@ -1,84 +1,170 @@
1
1
  import { asUint32 } from '../number/index.mjs';
2
2
 
3
3
  /**
4
- * Interface for an immutable set with custom element mapping and O(1) membership testing.
4
+ * Interface for an immutable set with custom element mapping and membership
5
+ * testing.
5
6
  *
6
- * ISetMapped allows you to use complex objects as set elements by providing transformation functions
7
- * that convert between your custom element type `K` and a primitive `MapSetKeyType` `KM` that can
8
- * be efficiently stored in JavaScript's native Set. This enables high-performance set operations
9
- * on complex elements while maintaining type safety and immutability.
7
+ * ISetMapped allows you to use complex objects as set elements by providing
8
+ * transformation functions that convert between your custom element type `K`
9
+ * and a primitive `MapSetKeyType` `KM` that can be efficiently stored in
10
+ * JavaScript's native Set. This enables set operations on complex elements
11
+ * while maintaining type safety and immutability.
10
12
  *
11
13
  * **Key Features:**
12
- * - **Custom Element Types**: Use any type as set elements by providing `toKey`/`fromKey` functions
13
- * - **O(1) Performance**: Maintains O(1) average-case performance for membership testing and mutations
14
+ *
15
+ * - **Custom Element Types**: Use any type as set elements by providing
16
+ * `toKey`/`fromKey` functions
14
17
  * - **Immutable**: All operations return new instances, preserving immutability
15
- * - **Set Operations**: Full support for union, intersection, difference, subset/superset checks
18
+ * - **Set Operations**: Full support for union, intersection, difference,
19
+ * subset/superset checks
16
20
  * - **Type Safe**: Full TypeScript support with generic element types
17
21
  *
18
22
  * **Performance Characteristics:**
19
- * - has/add/delete: O(1) average case (plus element transformation overhead)
20
- * - Set operations (union, intersection, difference): O(n)
23
+ *
24
+ * - has: O(1) average case (plus element transformation overhead)
25
+ * - add/delete: O(n) due to copying for immutability (plus element
26
+ * transformation overhead)
27
+ * - set operations (union, intersection, difference): O(n)
21
28
  * - map/filter operations: O(n)
22
- * - Iteration: O(n) (plus element transformation overhead)
29
+ * - iteration: O(n) (plus element transformation overhead)
23
30
  *
24
31
  * @template K The type of the custom elements in the set.
25
32
  * @template KM The type of the mapped primitive keys (string, number, etc.).
26
- *
27
- * @example
28
- * ```typescript
29
- * // Example with complex object elements
30
- * type User = { id: number; department: string; email: string };
31
- *
32
- * // Define transformation functions
33
- * const userToKey = (user: User): string => `${user.department}:${user.id}`;
34
- * const keyToUser = (key: string): User => {
35
- * const [department, idStr] = key.split(':');
36
- * // In practice, you might fetch from a cache or reconstruct more robustly
37
- * return { id: Number(idStr), department, email: `user${idStr}@${department}.com` };
38
- * };
39
- *
40
- * declare const activeUsers: ISetMapped<User, string>;
41
- *
42
- * // All operations work with the complex element type
43
- * const user: User = { id: 123, department: "engineering", email: "alice@engineering.com" };
44
- * const hasUser = activeUsers.has(user); // O(1)
45
- * const withNewUser = activeUsers.add(user); // O(1) - returns new ISetMapped
46
- * const withoutUser = activeUsers.delete(user); // O(1) - returns new ISetMapped
47
- * ```
48
33
  */
49
34
  type ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{
50
35
  /**
51
36
  * Creates a new ISetMapped instance.
37
+ *
52
38
  * @param iterable An iterable of elements.
53
39
  * @param toKey A function that converts an element of type `K` to `KM`.
54
- * @param fromKey A function that converts a mapped key of type `KM` back to `K`.
40
+ * @param fromKey A function that converts a mapped key of type `KM` back to
41
+ * `K`.
55
42
  */
56
43
  new (iterable: Iterable<K>, toKey: (a: K) => KM, fromKey: (k: KM) => K): void;
57
44
 
58
45
  // Getting information
59
- /** The number of elements in the set. */
46
+
47
+ /**
48
+ * The number of elements in the set.
49
+ *
50
+ * @example
51
+ *
52
+ * ```ts
53
+ * type Point = Readonly<{ x: number; tag: string }>;
54
+ *
55
+ * const toKey = (point: Point) => JSON.stringify(point);
56
+ *
57
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
58
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
59
+ *
60
+ * const points: readonly Point[] = [
61
+ * { x: 1, tag: 'a' },
62
+ * { x: 2, tag: 'b' },
63
+ * ];
64
+ *
65
+ * const set = ISetMapped.create<Point, string>(points, toKey, fromKey);
66
+ *
67
+ * assert(set.size === 2);
68
+ * ```
69
+ */
60
70
  size: SizeType.Arr;
61
71
 
62
- /** Checks if the set is empty. */
72
+ /**
73
+ * Checks if the set is empty.
74
+ *
75
+ * @example
76
+ *
77
+ * ```ts
78
+ * type Point = Readonly<{ x: number; tag: string }>;
79
+ *
80
+ * const toKey = (point: Point) => JSON.stringify(point);
81
+ *
82
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
83
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
84
+ *
85
+ * const empty = ISetMapped.create<Point, string>([], toKey, fromKey);
86
+ * const points = ISetMapped.create<Point, string>(
87
+ * [{ x: 1, tag: 'a' }],
88
+ * toKey,
89
+ * fromKey,
90
+ * );
91
+ *
92
+ * assert.ok(empty.isEmpty);
93
+ * assert.notOk(points.isEmpty);
94
+ * ```
95
+ */
63
96
  isEmpty: boolean;
64
97
 
65
98
  /**
66
99
  * Checks if an element exists in the set.
100
+ *
101
+ * @example
102
+ *
103
+ * ```ts
104
+ * type Point = Readonly<{ x: number; tag: string }>;
105
+ *
106
+ * const toKey = (point: Point) => JSON.stringify(point);
107
+ *
108
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
109
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
110
+ *
111
+ * const set = ISetMapped.create<Point, string>(
112
+ * [{ x: 1, tag: 'a' }],
113
+ * toKey,
114
+ * fromKey,
115
+ * );
116
+ *
117
+ * assert.ok(set.has({ x: 1, tag: 'a' }));
118
+ * assert.notOk(set.has({ x: 2, tag: 'b' }));
119
+ * ```
120
+ *
67
121
  * @param key The element to check.
68
122
  * @returns `true` if the element exists, `false` otherwise.
69
123
  */
70
124
  has: (key: K) => boolean;
71
125
 
72
126
  // Reducing a value
127
+
73
128
  /**
74
129
  * Checks if all elements in the set satisfy a predicate.
130
+ *
131
+ * @example
132
+ *
133
+ * ```ts
134
+ * type Point = Readonly<{ x: number; tag: string }>;
135
+ *
136
+ * const toKey = (point: Point) => JSON.stringify(point);
137
+ *
138
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
139
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
140
+ *
141
+ * const set = ISetMapped.create<Point, string>(
142
+ * [
143
+ * { x: 2, tag: 'even' },
144
+ * { x: 4, tag: 'even' },
145
+ * ],
146
+ * toKey,
147
+ * fromKey,
148
+ * );
149
+ *
150
+ * const allEven = set.every((point) => point.x % 2 === 0);
151
+ * const narrowed = set.every(
152
+ * (point): point is Readonly<{ x: 2 | 4; tag: 'even' }> => point.x % 2 === 0,
153
+ * );
154
+ *
155
+ * assert.ok(allEven);
156
+ * assert.ok(narrowed);
157
+ * ```
158
+ *
75
159
  * @param predicate A function to test each element.
76
160
  * @returns `true` if all elements satisfy the predicate, `false` otherwise.
77
161
  */
78
162
  every: ((predicate: (key: K) => boolean) => boolean) &
79
163
  /**
80
- * Checks if all elements in the set satisfy a type predicate.
81
- * Narrows the type of elements in the set if the predicate returns true for all elements.
164
+ * Checks if all elements in the set satisfy a type predicate. Narrows the
165
+ * type of elements in the set if the predicate returns true for all
166
+ * elements.
167
+ *
82
168
  * @template L The narrowed type of the elements.
83
169
  * @param predicate A type predicate function.
84
170
  * @returns `true` if all elements satisfy the predicate, `false` otherwise.
@@ -86,28 +172,150 @@ type ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{
86
172
  (<L extends K>(
87
173
  predicate: (key: K) => key is L,
88
174
  ) => this is ISetMapped<L, KM>);
175
+
89
176
  /**
90
177
  * Checks if at least one element in the set satisfies a predicate.
178
+ *
179
+ * @example
180
+ *
181
+ * ```ts
182
+ * type Point = Readonly<{ x: number; tag: string }>;
183
+ *
184
+ * const toKey = (point: Point) => JSON.stringify(point);
185
+ *
186
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
187
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
188
+ *
189
+ * const set = ISetMapped.create<Point, string>(
190
+ * [
191
+ * { x: 1, tag: 'a' },
192
+ * { x: 5, tag: 'b' },
193
+ * ],
194
+ * toKey,
195
+ * fromKey,
196
+ * );
197
+ *
198
+ * assert.ok(set.some((point) => point.x > 4));
199
+ * assert.notOk(set.some((point) => point.x > 10));
200
+ * ```
201
+ *
91
202
  * @param predicate A function to test each element.
92
- * @returns `true` if at least one element satisfies the predicate, `false` otherwise.
203
+ * @returns `true` if at least one element satisfies the predicate, `false`
204
+ * otherwise.
93
205
  */
94
206
  some: (predicate: (key: K) => boolean) => boolean;
95
207
 
96
208
  // Mutation
209
+
97
210
  /**
98
211
  * Adds an element to the set.
212
+ *
213
+ * @example
214
+ *
215
+ * ```ts
216
+ * type Point = Readonly<{ x: number; tag: string }>;
217
+ *
218
+ * const toKey = (point: Point) => JSON.stringify(point);
219
+ *
220
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
221
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
222
+ *
223
+ * const base = ISetMapped.create<Point, string>(
224
+ * [{ x: 1, tag: 'a' }],
225
+ * toKey,
226
+ * fromKey,
227
+ * );
228
+ *
229
+ * const withNew = base.add({ x: 2, tag: 'b' });
230
+ * const unchanged = base.add({ x: 1, tag: 'a' });
231
+ *
232
+ * assert.deepStrictEqual(Array.from(withNew), [
233
+ * { x: 1, tag: 'a' },
234
+ * { x: 2, tag: 'b' },
235
+ * ]);
236
+ * assert(unchanged === base);
237
+ * ```
238
+ *
99
239
  * @param key The element to add.
100
240
  * @returns A new ISetMapped instance with the element added.
101
241
  */
102
242
  add: (key: K) => ISetMapped<K, KM>;
243
+
103
244
  /**
104
245
  * Deletes an element from the set.
246
+ *
247
+ * @example
248
+ *
249
+ * ```ts
250
+ * type Point = Readonly<{ x: number; tag: string }>;
251
+ *
252
+ * const toKey = (point: Point) => JSON.stringify(point);
253
+ *
254
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
255
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
256
+ *
257
+ * const base = ISetMapped.create<Point, string>(
258
+ * [
259
+ * { x: 1, tag: 'a' },
260
+ * { x: 2, tag: 'b' },
261
+ * ],
262
+ * toKey,
263
+ * fromKey,
264
+ * );
265
+ *
266
+ * const withoutSecond = base.delete({ x: 2, tag: 'b' });
267
+ * const unchanged = base.delete({ x: 3, tag: 'c' });
268
+ *
269
+ * assert.deepStrictEqual(Array.from(withoutSecond), [{ x: 1, tag: 'a' }]);
270
+ * assert(unchanged === base);
271
+ * ```
272
+ *
105
273
  * @param key The element to delete.
106
274
  * @returns A new ISetMapped instance without the specified element.
107
275
  */
108
276
  delete: (key: K) => ISetMapped<K, KM>;
277
+
109
278
  /**
110
279
  * Applies a series of mutations to the set.
280
+ *
281
+ * @example
282
+ *
283
+ * ```ts
284
+ * type Point = Readonly<{ x: number; tag: string }>;
285
+ *
286
+ * const toKey = (point: Point) => JSON.stringify(point);
287
+ *
288
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
289
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
290
+ *
291
+ * const base = ISetMapped.create<Point, string>(
292
+ * [
293
+ * { x: 1, tag: 'a' },
294
+ * { x: 2, tag: 'b' },
295
+ * ],
296
+ * toKey,
297
+ * fromKey,
298
+ * );
299
+ *
300
+ * const actions: readonly Readonly<
301
+ * { type: 'add'; key: Point } | { type: 'delete'; key: Point }
302
+ * >[] = [
303
+ * { type: 'add', key: { x: 3, tag: 'c' } },
304
+ * { type: 'delete', key: { x: 1, tag: 'a' } },
305
+ * ];
306
+ *
307
+ * const mutated = base.withMutations(actions);
308
+ *
309
+ * assert.deepStrictEqual(Array.from(mutated), [
310
+ * { x: 2, tag: 'b' },
311
+ * { x: 3, tag: 'c' },
312
+ * ]);
313
+ * assert.deepStrictEqual(Array.from(base), [
314
+ * { x: 1, tag: 'a' },
315
+ * { x: 2, tag: 'b' },
316
+ * ]);
317
+ * ```
318
+ *
111
319
  * @param actions An array of mutation actions (add or delete).
112
320
  * @returns A new ISetMapped instance with all mutations applied.
113
321
  */
@@ -118,114 +326,538 @@ type ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{
118
326
  ) => ISetMapped<K, KM>;
119
327
 
120
328
  // Sequence algorithms
329
+
121
330
  /**
122
- * Maps the elements of the set to new elements.
123
- * Note: The element type `K` cannot be changed because `toKey` and `fromKey` would become unusable if the mapped type `KM` changes.
124
- * @param mapFn A function that maps an element to a new element of the same type `K`.
331
+ * Maps the elements of the set to new elements. Note: The element type `K`
332
+ * cannot be changed because `toKey` and `fromKey` would become unusable if
333
+ * the mapped type `KM` changes.
334
+ *
335
+ * @example
336
+ *
337
+ * ```ts
338
+ * type Point = Readonly<{ x: number; tag: string }>;
339
+ *
340
+ * const toKey = (point: Point) => JSON.stringify(point);
341
+ *
342
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
343
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
344
+ *
345
+ * const set = ISetMapped.create<Point, string>(
346
+ * [
347
+ * { x: 1, tag: 'a' },
348
+ * { x: 2, tag: 'b' },
349
+ * ],
350
+ * toKey,
351
+ * fromKey,
352
+ * );
353
+ *
354
+ * const shifted = set.map((point) => ({
355
+ * x: point.x + 10,
356
+ * tag: point.tag.toUpperCase(),
357
+ * }));
358
+ *
359
+ * assert.deepStrictEqual(Array.from(shifted), [
360
+ * { x: 11, tag: 'A' },
361
+ * { x: 12, tag: 'B' },
362
+ * ]);
363
+ * ```
364
+ *
365
+ * @param mapFn A function that maps an element to a new element of the same
366
+ * type `K`.
125
367
  * @returns A new ISetMapped instance with mapped elements.
126
368
  */
127
369
  map: (mapFn: (key: K) => K) => ISetMapped<K, KM>;
128
370
 
129
371
  /**
130
372
  * Filters the elements of the set based on a predicate.
373
+ *
374
+ * @example
375
+ *
376
+ * ```ts
377
+ * type Point = Readonly<{ x: number; tag: string }>;
378
+ *
379
+ * const toKey = (point: Point) => JSON.stringify(point);
380
+ *
381
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
382
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
383
+ *
384
+ * const set = ISetMapped.create<Point, string>(
385
+ * [
386
+ * { x: 1, tag: 'a' },
387
+ * { x: 2, tag: 'b' },
388
+ * { x: 3, tag: 'c' },
389
+ * ],
390
+ * toKey,
391
+ * fromKey,
392
+ * );
393
+ *
394
+ * const evenPoints = set.filter((point) => point.x % 2 === 0);
395
+ *
396
+ * assert.deepStrictEqual(Array.from(evenPoints), [{ x: 2, tag: 'b' }]);
397
+ * ```
398
+ *
131
399
  * @param predicate A function to test each element.
132
- * @returns A new ISetMapped instance with elements that satisfy the predicate.
400
+ * @returns A new ISetMapped instance with elements that satisfy the
401
+ * predicate.
133
402
  */
134
403
  filter: (predicate: (value: K) => boolean) => ISetMapped<K, KM>;
135
404
 
136
405
  /**
137
- * Filters the elements of the set by excluding elements for which the predicate returns true.
406
+ * Filters the elements of the set by excluding elements for which the
407
+ * predicate returns true.
408
+ *
409
+ * @example
410
+ *
411
+ * ```ts
412
+ * type Point = Readonly<{ x: number; tag: string }>;
413
+ *
414
+ * const toKey = (point: Point) => JSON.stringify(point);
415
+ *
416
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
417
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
418
+ *
419
+ * const set = ISetMapped.create<Point, string>(
420
+ * [
421
+ * { x: 1, tag: 'a' },
422
+ * { x: 2, tag: 'b' },
423
+ * ],
424
+ * toKey,
425
+ * fromKey,
426
+ * );
427
+ *
428
+ * const withoutEven = set.filterNot((point) => point.x % 2 === 0);
429
+ *
430
+ * assert.deepStrictEqual(Array.from(withoutEven), [{ x: 1, tag: 'a' }]);
431
+ * ```
432
+ *
138
433
  * @param predicate A function to test each element.
139
- * @returns A new ISetMapped instance with elements for which the predicate returned `false`.
434
+ * @returns A new ISetMapped instance with elements for which the predicate
435
+ * returned `false`.
140
436
  */
141
437
  filterNot: (predicate: (key: K) => boolean) => ISetMapped<K, KM>;
142
438
 
143
439
  // Side effects
440
+
144
441
  /**
145
442
  * Executes a callback function for each element in the set.
443
+ *
444
+ * @example
445
+ *
446
+ * ```ts
447
+ * type Point = Readonly<{ x: number; tag: string }>;
448
+ *
449
+ * const toKey = (point: Point) => JSON.stringify(point);
450
+ *
451
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
452
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
453
+ *
454
+ * const set = ISetMapped.create<Point, string>(
455
+ * [
456
+ * { x: 1, tag: 'a' },
457
+ * { x: 2, tag: 'b' },
458
+ * ],
459
+ * toKey,
460
+ * fromKey,
461
+ * );
462
+ *
463
+ * const collected: Point[] = [];
464
+ * for (const point of set) {
465
+ * collected.push(point);
466
+ * }
467
+ *
468
+ * assert.deepStrictEqual(collected, [
469
+ * { x: 1, tag: 'a' },
470
+ * { x: 2, tag: 'b' },
471
+ * ]);
472
+ * ```
473
+ *
146
474
  * @param callbackfn A function to execute for each element.
147
475
  */
148
476
  forEach: (callbackfn: (key: K) => void) => void;
149
477
 
150
478
  // Comparison
479
+
151
480
  /**
152
481
  * Checks if this set is a subset of another set.
482
+ *
483
+ * @example
484
+ *
485
+ * ```ts
486
+ * type Point = Readonly<{ x: number; tag: string }>;
487
+ *
488
+ * const toKey = (point: Point) => JSON.stringify(point);
489
+ *
490
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
491
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
492
+ *
493
+ * const subset = ISetMapped.create<Point, string>(
494
+ * [{ x: 1, tag: 'a' }],
495
+ * toKey,
496
+ * fromKey,
497
+ * );
498
+ * const superset = ISetMapped.create<Point, string>(
499
+ * [
500
+ * { x: 1, tag: 'a' },
501
+ * { x: 2, tag: 'b' },
502
+ * ],
503
+ * toKey,
504
+ * fromKey,
505
+ * );
506
+ *
507
+ * assert.ok(subset.isSubsetOf(superset));
508
+ * assert.notOk(superset.isSubsetOf(subset));
509
+ * ```
510
+ *
153
511
  * @param set The other set.
154
- * @returns `true` if this set is a subset of the other set, `false` otherwise.
512
+ * @returns `true` if this set is a subset of the other set, `false`
513
+ * otherwise.
155
514
  */
156
515
  isSubsetOf: (set: ISetMapped<K, KM>) => boolean;
516
+
157
517
  /**
158
518
  * Checks if this set is a superset of another set.
519
+ *
520
+ * @example
521
+ *
522
+ * ```ts
523
+ * type Point = Readonly<{ x: number; tag: string }>;
524
+ *
525
+ * const toKey = (point: Point) => JSON.stringify(point);
526
+ *
527
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
528
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
529
+ *
530
+ * const superset = ISetMapped.create<Point, string>(
531
+ * [
532
+ * { x: 1, tag: 'a' },
533
+ * { x: 2, tag: 'b' },
534
+ * ],
535
+ * toKey,
536
+ * fromKey,
537
+ * );
538
+ * const subset = ISetMapped.create<Point, string>(
539
+ * [{ x: 2, tag: 'b' }],
540
+ * toKey,
541
+ * fromKey,
542
+ * );
543
+ *
544
+ * assert.ok(superset.isSupersetOf(subset));
545
+ * assert.notOk(subset.isSupersetOf(superset));
546
+ * ```
547
+ *
159
548
  * @param set The other set.
160
- * @returns `true` if this set is a superset of the other set, `false` otherwise.
549
+ * @returns `true` if this set is a superset of the other set, `false`
550
+ * otherwise.
161
551
  */
162
552
  isSupersetOf: (set: ISetMapped<K, KM>) => boolean;
553
+
163
554
  /**
164
- * Returns a new set with elements that are in this set but not in another set.
555
+ * Returns a new set with elements that are in this set but not in another
556
+ * set.
557
+ *
558
+ * @example
559
+ *
560
+ * ```ts
561
+ * type Point = Readonly<{ x: number; tag: string }>;
562
+ *
563
+ * const toKey = (point: Point) => JSON.stringify(point);
564
+ *
565
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
566
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
567
+ *
568
+ * const left = ISetMapped.create<Point, string>(
569
+ * [
570
+ * { x: 1, tag: 'a' },
571
+ * { x: 2, tag: 'b' },
572
+ * { x: 3, tag: 'c' },
573
+ * ],
574
+ * toKey,
575
+ * fromKey,
576
+ * );
577
+ * const right = ISetMapped.create<Point, string>(
578
+ * [{ x: 2, tag: 'b' }],
579
+ * toKey,
580
+ * fromKey,
581
+ * );
582
+ *
583
+ * const difference = left.subtract(right);
584
+ *
585
+ * assert.deepStrictEqual(Array.from(difference), [
586
+ * { x: 1, tag: 'a' },
587
+ * { x: 3, tag: 'c' },
588
+ * ]);
589
+ * ```
590
+ *
165
591
  * @param set The other set.
166
592
  * @returns A new ISetMapped instance representing the set difference.
167
593
  */
168
594
  subtract: (set: ISetMapped<K, KM>) => ISetMapped<K, KM>;
595
+
169
596
  /**
170
- * Returns a new set with elements that are common to both this set and another set.
597
+ * Returns a new set with elements that are common to both this set and
598
+ * another set.
599
+ *
600
+ * @example
601
+ *
602
+ * ```ts
603
+ * type Point = Readonly<{ x: number; tag: string }>;
604
+ *
605
+ * const toKey = (point: Point) => JSON.stringify(point);
606
+ *
607
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
608
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
609
+ *
610
+ * const left = ISetMapped.create<Point, string>(
611
+ * [
612
+ * { x: 1, tag: 'a' },
613
+ * { x: 2, tag: 'b' },
614
+ * ],
615
+ * toKey,
616
+ * fromKey,
617
+ * );
618
+ * const right = ISetMapped.create<Point, string>(
619
+ * [{ x: 2, tag: 'b' }],
620
+ * toKey,
621
+ * fromKey,
622
+ * );
623
+ *
624
+ * const intersection = left.intersect(right);
625
+ *
626
+ * assert.deepStrictEqual(Array.from(intersection), [{ x: 2, tag: 'b' }]);
627
+ * ```
628
+ *
171
629
  * @param set The other set.
172
630
  * @returns A new ISetMapped instance representing the set intersection.
173
631
  */
174
632
  intersect: (set: ISetMapped<K, KM>) => ISetMapped<K, KM>;
633
+
175
634
  /**
176
635
  * Returns a new set with all elements from both this set and another set.
636
+ *
637
+ * @example
638
+ *
639
+ * ```ts
640
+ * type Point = Readonly<{ x: number; tag: string }>;
641
+ *
642
+ * const toKey = (point: Point) => JSON.stringify(point);
643
+ *
644
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
645
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
646
+ *
647
+ * const left = ISetMapped.create<Point, string>(
648
+ * [{ x: 1, tag: 'a' }],
649
+ * toKey,
650
+ * fromKey,
651
+ * );
652
+ * const right = ISetMapped.create<Point, string>(
653
+ * [{ x: 2, tag: 'b' }],
654
+ * toKey,
655
+ * fromKey,
656
+ * );
657
+ *
658
+ * const combined = left.union(right);
659
+ *
660
+ * assert.deepStrictEqual(Array.from(combined), [
661
+ * { x: 1, tag: 'a' },
662
+ * { x: 2, tag: 'b' },
663
+ * ]);
664
+ * ```
665
+ *
177
666
  * @param set The other set.
178
667
  * @returns A new ISetMapped instance representing the set union.
179
668
  */
180
669
  union: (set: ISetMapped<K, KM>) => ISetMapped<K, KM>;
181
670
 
182
671
  // Iterators
672
+
183
673
  /**
184
674
  * Returns an iterator for the elements in the set (alias for values).
675
+ *
676
+ * @example
677
+ *
678
+ * ```ts
679
+ * type Point = Readonly<{ x: number; tag: string }>;
680
+ *
681
+ * const toKey = (point: Point) => JSON.stringify(point);
682
+ *
683
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
684
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
685
+ *
686
+ * const set = ISetMapped.create<Point, string>(
687
+ * [
688
+ * { x: 1, tag: 'a' },
689
+ * { x: 2, tag: 'b' },
690
+ * ],
691
+ * toKey,
692
+ * fromKey,
693
+ * );
694
+ *
695
+ * assert.deepStrictEqual(Array.from(set.keys()), [
696
+ * { x: 1, tag: 'a' },
697
+ * { x: 2, tag: 'b' },
698
+ * ]);
699
+ * ```
700
+ *
185
701
  * @returns An iterable iterator of elements.
186
702
  */
187
703
  keys: () => IterableIterator<K>;
704
+
188
705
  /**
189
706
  * Returns an iterator for the elements in the set.
707
+ *
708
+ * @example
709
+ *
710
+ * ```ts
711
+ * type Point = Readonly<{ x: number; tag: string }>;
712
+ *
713
+ * const toKey = (point: Point) => JSON.stringify(point);
714
+ *
715
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
716
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
717
+ *
718
+ * const set = ISetMapped.create<Point, string>(
719
+ * [
720
+ * { x: 1, tag: 'a' },
721
+ * { x: 2, tag: 'b' },
722
+ * ],
723
+ * toKey,
724
+ * fromKey,
725
+ * );
726
+ *
727
+ * assert.deepStrictEqual(Array.from(set.values()), [
728
+ * { x: 1, tag: 'a' },
729
+ * { x: 2, tag: 'b' },
730
+ * ]);
731
+ * ```
732
+ *
190
733
  * @returns An iterable iterator of elements.
191
734
  */
192
735
  values: () => IterableIterator<K>;
736
+
193
737
  /**
194
738
  * Returns an iterator for the entries (element-element pairs) in the set.
739
+ *
740
+ * @example
741
+ *
742
+ * ```ts
743
+ * type Point = Readonly<{ x: number; tag: string }>;
744
+ *
745
+ * const toKey = (point: Point) => JSON.stringify(point);
746
+ *
747
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
748
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
749
+ *
750
+ * const set = ISetMapped.create<Point, string>(
751
+ * [
752
+ * { x: 1, tag: 'a' },
753
+ * { x: 2, tag: 'b' },
754
+ * ],
755
+ * toKey,
756
+ * fromKey,
757
+ * );
758
+ *
759
+ * assert.deepStrictEqual(Array.from(set.entries()), [
760
+ * [
761
+ * { x: 1, tag: 'a' },
762
+ * { x: 1, tag: 'a' },
763
+ * ],
764
+ * [
765
+ * { x: 2, tag: 'b' },
766
+ * { x: 2, tag: 'b' },
767
+ * ],
768
+ * ]);
769
+ * ```
770
+ *
195
771
  * @returns An iterable iterator of entries.
196
772
  */
197
773
  entries: () => IterableIterator<readonly [K, K]>;
198
774
 
199
775
  // Conversion
776
+
200
777
  /**
201
778
  * Converts the elements of the set to an array.
779
+ *
780
+ * @example
781
+ *
782
+ * ```ts
783
+ * type Point = Readonly<{ x: number; tag: string }>;
784
+ *
785
+ * const toKey = (point: Point) => JSON.stringify(point);
786
+ *
787
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
788
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
789
+ *
790
+ * const set = ISetMapped.create<Point, string>(
791
+ * [
792
+ * { x: 1, tag: 'a' },
793
+ * { x: 2, tag: 'b' },
794
+ * ],
795
+ * toKey,
796
+ * fromKey,
797
+ * );
798
+ *
799
+ * assert.deepStrictEqual(set.toArray(), [
800
+ * { x: 1, tag: 'a' },
801
+ * { x: 2, tag: 'b' },
802
+ * ]);
803
+ * ```
804
+ *
202
805
  * @returns A readonly array of elements.
203
806
  */
204
807
  toArray: () => readonly K[];
808
+
205
809
  /**
206
810
  * Returns the underlying readonly JavaScript Set of mapped keys.
811
+ *
812
+ * @example
813
+ *
814
+ * ```ts
815
+ * type Point = Readonly<{ x: number; tag: string }>;
816
+ *
817
+ * const toKey = (point: Point) => JSON.stringify(point);
818
+ *
819
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
820
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
821
+ *
822
+ * const set = ISetMapped.create<Point, string>(
823
+ * [{ x: 1, tag: 'a' }],
824
+ * toKey,
825
+ * fromKey,
826
+ * );
827
+ *
828
+ * const raw = set.toRawSet();
829
+ *
830
+ * assert.ok(is.set(raw));
831
+ * assert.ok(raw.has(toKey({ x: 1, tag: 'a' })));
832
+ * ```
833
+ *
207
834
  * @returns The raw ReadonlySet instance.
208
835
  */
209
836
  toRawSet: () => ReadonlySet<KM>;
210
837
  }>;
211
838
 
212
839
  /**
213
- * Represents an immutable set with custom element transformation and high-performance operations.
840
+ * Represents an immutable set with custom element transformation and
841
+ * high-performance operations.
214
842
  *
215
- * ISetMapped is a specialized persistent data structure that enables using complex objects as set elements
216
- * while maintaining the performance benefits of JavaScript's native Set. It achieves this by requiring
217
- * bidirectional transformation functions that convert between your custom element type and a primitive type
218
- * that can be efficiently stored and compared for uniqueness.
843
+ * ISetMapped is a specialized persistent data structure that enables using
844
+ * complex objects as set elements while maintaining the performance benefits of
845
+ * JavaScript's native Set. It achieves this by requiring bidirectional
846
+ * transformation functions that convert between your custom element type and a
847
+ * primitive type that can be efficiently stored and compared for uniqueness.
219
848
  *
220
849
  * **Key Features:**
850
+ *
221
851
  * - **Complex Elements**: Use objects, arrays, or any custom type as set elements
222
- * - **High Performance**: O(1) operations through efficient element transformation
223
852
  * - **Immutable**: All mutation operations return new instances
224
- * - **Type Safe**: Full TypeScript support with compile-time element type checking
225
- * - **Bidirectional**: Maintains ability to reconstruct original elements from mapped keys
853
+ * - **Type Safe**: Full TypeScript support with compile-time element type
854
+ * checking
855
+ * - **Bidirectional**: Maintains ability to reconstruct original elements from
856
+ * mapped keys
226
857
  * - **Set Algebra**: Complete support for mathematical set operations
227
858
  *
228
859
  * **Use Cases:**
860
+ *
229
861
  * - Sets of entities with complex identifiers
230
862
  * - Deduplication of objects based on specific properties
231
863
  * - Performance-critical sets with non-primitive elements
@@ -233,175 +865,60 @@ type ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{
233
865
  *
234
866
  * @template K The type of the custom elements in the set.
235
867
  * @template KM The type of the mapped primitive keys (string, number, etc.).
236
- *
237
- * @example
238
- * ```typescript
239
- * // Example: User management with composite identity
240
- * type User = { id: number; department: string; username: string; email: string };
241
- *
242
- * // Define bidirectional transformation functions
243
- * const userToKey = (user: User): string => `${user.department}:${user.id}`;
244
- * const keyToUser = (key: string): User => {
245
- * const [department, idStr] = key.split(':');
246
- * const id = Number(idStr);
247
- * // In practice, this might fetch from a user service or cache
248
- * return {
249
- * id,
250
- * department,
251
- * username: `user${id}`,
252
- * email: `user${id}@${department}.company.com`
253
- * };
254
- * };
255
- *
256
- * // Create a set with complex elements
257
- * let activeUsers = ISetMapped.create<User, string>([], userToKey, keyToUser);
258
- *
259
- * // Use complex objects as elements naturally
260
- * const alice: User = { id: 1, department: "engineering", username: "alice", email: "alice@engineering.company.com" };
261
- * const bob: User = { id: 2, department: "marketing", username: "bob", email: "bob@marketing.company.com" };
262
- * const charlie: User = { id: 3, department: "engineering", username: "charlie", email: "charlie@engineering.company.com" };
263
- *
264
- * activeUsers = activeUsers
265
- * .add(alice)
266
- * .add(bob)
267
- * .add(charlie);
268
- *
269
- * // All operations work with the original element type
270
- * console.log(activeUsers.has(alice)); // Output: true
271
- * console.log(activeUsers.size); // Output: 3
272
- *
273
- * // Set operations preserve element types
274
- * const engineeringUsers = ISetMapped.create<User, string>([alice, charlie], userToKey, keyToUser);
275
- * const marketingUsers = ISetMapped.create<User, string>([bob], userToKey, keyToUser);
276
- *
277
- * const allUsers = ISetMapped.union(engineeringUsers, marketingUsers);
278
- * const engineeringOnly = activeUsers.intersect(engineeringUsers);
279
- *
280
- * // Iteration preserves original element types
281
- * for (const user of engineeringOnly) {
282
- * console.log(`${user.username} works in ${user.department}`);
283
- * }
284
- * // Output:
285
- * // alice works in engineering
286
- * // charlie works in engineering
287
- *
288
- * // Functional transformations work seamlessly
289
- * const updatedUsers = activeUsers.map(user => ({
290
- * ...user,
291
- * email: user.email.replace('.company.com', '.example.com')
292
- * }));
293
- * ```
294
868
  */
295
869
  export type ISetMapped<K, KM extends MapSetKeyType> = Iterable<K> &
296
870
  Readonly<ISetMappedInterface<K, KM>>;
297
871
 
298
- /**
299
- * Provides utility functions for ISetMapped.
300
- */
872
+ /** Provides utility functions for ISetMapped. */
301
873
  export namespace ISetMapped {
302
874
  /**
303
- * Creates a new ISetMapped instance with custom element transformation functions.
875
+ * Creates a new ISetMapped instance with custom element transformation
876
+ * functions.
304
877
  *
305
- * This factory function creates an immutable set that can use complex objects as elements
306
- * by providing bidirectional transformation functions. The `toKey` function converts
307
- * your custom element type to a primitive type that can be efficiently stored, while
308
- * `fromKey` reconstructs the original element type for iteration and access.
878
+ * This factory function creates an immutable set that can use complex objects
879
+ * as elements by providing bidirectional transformation functions. The
880
+ * `toKey` function converts your custom element type to a primitive type that
881
+ * can be efficiently stored, while `fromKey` reconstructs the original
882
+ * element type for iteration and access.
309
883
  *
310
884
  * **Performance:** O(n) where n is the number of elements in the iterable.
311
885
  *
312
- * @template K The type of the custom elements.
313
- * @template KM The type of the mapped primitive keys.
314
- * @param iterable An iterable of elements using the custom element type.
315
- * @param toKey A function that converts a custom element `K` to a primitive key `KM`.
316
- * This function must be deterministic and produce unique values for unique elements.
317
- * @param fromKey A function that converts a primitive key `KM` back to the custom element `K`.
318
- * This should be the inverse of `toKey`.
319
- * @returns A new ISetMapped instance containing all unique elements from the iterable.
320
- *
321
886
  * @example
322
- * ```typescript
323
- * // Example 1: Product catalog with SKU-based identity
324
- * type Product = { sku: string; name: string; price: number; category: string };
325
- *
326
- * const productToKey = (product: Product): string => product.sku;
327
- * const keyToProduct = (sku: string): Product => {
328
- * // In practice, this might fetch from a product service or cache
329
- * return {
330
- * sku,
331
- * name: `Product ${sku}`,
332
- * price: 0,
333
- * category: "unknown"
334
- * };
335
- * };
336
- *
337
- * const productSet = ISetMapped.create<Product, string>(
338
- * [
339
- * { sku: "LAPTOP-001", name: "Gaming Laptop", price: 1299, category: "electronics" },
340
- * { sku: "MOUSE-002", name: "Wireless Mouse", price: 49, category: "accessories" },
341
- * { sku: "LAPTOP-001", name: "Gaming Laptop", price: 1299, category: "electronics" } // Duplicate SKU
342
- * ],
343
- * productToKey,
344
- * keyToProduct
345
- * );
346
887
  *
347
- * console.log(productSet.size); // Output: 2 (duplicate removed)
348
- * console.log(productSet.has({ sku: "LAPTOP-001", name: "Gaming Laptop", price: 1299, category: "electronics" })); // true
888
+ * ```ts
889
+ * type Point = Readonly<{ x: number; tag: string }>;
349
890
  *
350
- * // Example 2: Geographic locations with coordinate-based identity
351
- * type Location = { name: string; lat: number; lng: number; type: string };
891
+ * const toKey = (point: Point) => JSON.stringify(point);
352
892
  *
353
- * const locationToKey = (loc: Location): string => `${loc.lat.toFixed(6)},${loc.lng.toFixed(6)}`;
354
- * const keyToLocation = (key: string): Location => {
355
- * const [latStr, lngStr] = key.split(',');
356
- * return {
357
- * name: "Unknown Location",
358
- * lat: parseFloat(latStr),
359
- * lng: parseFloat(lngStr),
360
- * type: "point"
361
- * };
362
- * };
893
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
894
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
363
895
  *
364
- * const locationSet = ISetMapped.create<Location, string>(
896
+ * const set = ISetMapped.create<Point, string>(
365
897
  * [
366
- * { name: "Statue of Liberty", lat: 40.689247, lng: -74.044502, type: "monument" },
367
- * { name: "Empire State Building", lat: 40.748817, lng: -73.985428, type: "building" }
898
+ * { x: 1, tag: 'a' },
899
+ * { x: 1, tag: 'a' },
900
+ * { x: 2, tag: 'b' },
368
901
  * ],
369
- * locationToKey,
370
- * keyToLocation
371
- * );
372
- *
373
- * // Example 3: User entities with multi-part identity
374
- * type User = { id: number; tenant: string; email: string; active: boolean };
375
- *
376
- * const userToKey = (user: User): string => `${user.tenant}:${user.id}`;
377
- * const keyToUser = (key: string): User => {
378
- * const [tenant, idStr] = key.split(':');
379
- * return {
380
- * id: Number(idStr),
381
- * tenant,
382
- * email: `user${idStr}@${tenant}.com`,
383
- * active: true
384
- * };
385
- * };
386
- *
387
- * const userSet = ISetMapped.create<User, string>(
388
- * [],
389
- * userToKey,
390
- * keyToUser
391
- * )
392
- * .add({ id: 1, tenant: "acme", email: "alice@acme.com", active: true })
393
- * .add({ id: 2, tenant: "acme", email: "bob@acme.com", active: false });
394
- *
395
- * console.log(userSet.size); // Output: 2
396
- *
397
- * // Example 4: Empty set with type specification
398
- * const emptyProductSet = ISetMapped.create<Product, string>(
399
- * [],
400
- * productToKey,
401
- * keyToProduct
402
- * );
403
- * console.log(emptyProductSet.isEmpty); // Output: true
902
+ * toKey,
903
+ * fromKey,
904
+ * );
905
+ *
906
+ * assert.deepStrictEqual(Array.from(set), [
907
+ * { x: 1, tag: 'a' },
908
+ * { x: 2, tag: 'b' },
909
+ * ]);
404
910
  * ```
911
+ *
912
+ * @template K The type of the custom elements.
913
+ * @template KM The type of the mapped primitive keys.
914
+ * @param iterable An iterable of elements using the custom element type.
915
+ * @param toKey A function that converts a custom element `K` to a primitive
916
+ * key `KM`. This function must be deterministic and produce unique values
917
+ * for unique elements.
918
+ * @param fromKey A function that converts a primitive key `KM` back to the
919
+ * custom element `K`. This should be the inverse of `toKey`.
920
+ * @returns A new ISetMapped instance containing all unique elements from the
921
+ * iterable.
405
922
  */
406
923
  export const create = <K, KM extends MapSetKeyType>(
407
924
  iterable: Iterable<K>,
@@ -412,99 +929,56 @@ export namespace ISetMapped {
412
929
  /**
413
930
  * Checks if two ISetMapped instances are structurally equal.
414
931
  *
415
- * Two ISetMapped instances are considered equal if they have the same size and contain
416
- * exactly the same elements. The comparison is performed on the underlying mapped keys,
417
- * so the transformation functions themselves don't need to be identical. Elements are
418
- * compared based on their mapped key representations.
932
+ * Two ISetMapped instances are considered equal if they have the same size
933
+ * and contain exactly the same elements. The comparison is performed on the
934
+ * underlying mapped keys, so the transformation functions themselves don't
935
+ * need to be identical. Elements are compared based on their mapped key
936
+ * representations.
419
937
  *
420
938
  * **Performance:** O(n) where n is the size of the smaller set.
421
939
  *
422
- * @template K The type of the custom elements.
423
- * @template KM The type of the mapped primitive keys.
424
- * @param a The first ISetMapped instance to compare.
425
- * @param b The second ISetMapped instance to compare.
426
- * @returns `true` if the sets contain exactly the same elements, `false` otherwise.
427
- *
428
940
  * @example
429
- * ```typescript
430
- * // Example with coordinate-based elements
431
- * type Point = { x: number; y: number; label?: string };
432
- * const pointToKey = (p: Point): string => `${p.x},${p.y}`;
433
- * const keyToPoint = (s: string): Point => {
434
- * const [x, y] = s.split(',').map(Number);
435
- * return { x, y };
436
- * };
437
- *
438
- * const set1 = ISetMapped.create<Point, string>(
439
- * [{ x: 1, y: 2, label: "A" }, { x: 3, y: 4, label: "B" }],
440
- * pointToKey,
441
- * keyToPoint
442
- * );
443
- *
444
- * const set2 = ISetMapped.create<Point, string>(
445
- * [{ x: 3, y: 4, label: "Different" }, { x: 1, y: 2, label: "Labels" }], // Order doesn't matter
446
- * pointToKey,
447
- * keyToPoint
448
- * );
449
941
  *
450
- * const set3 = ISetMapped.create<Point, string>(
451
- * [{ x: 1, y: 2 }, { x: 5, y: 6 }], // Different point
452
- * pointToKey,
453
- * keyToPoint
454
- * );
942
+ * ```ts
943
+ * type Point = Readonly<{ x: number; tag: string }>;
455
944
  *
456
- * console.log(ISetMapped.equal(set1, set2)); // true (same coordinates, labels don't affect equality)
457
- * console.log(ISetMapped.equal(set1, set3)); // false (different coordinates)
945
+ * const toKey = (point: Point) => JSON.stringify(point);
458
946
  *
459
- * // Example with user entities
460
- * type User = { id: number; department: string; name: string };
461
- * const userToKey = (u: User): string => `${u.department}:${u.id}`;
462
- * const keyToUser = (k: string): User => {
463
- * const [department, idStr] = k.split(':');
464
- * return { id: Number(idStr), department, name: "" };
465
- * };
947
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
948
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
466
949
  *
467
- * const users1 = ISetMapped.create<User, string>(
950
+ * const first = ISetMapped.create<Point, string>(
468
951
  * [
469
- * { id: 1, department: "eng", name: "Alice" },
470
- * { id: 2, department: "sales", name: "Bob" }
952
+ * { x: 1, tag: 'a' },
953
+ * { x: 2, tag: 'b' },
471
954
  * ],
472
- * userToKey,
473
- * keyToUser
955
+ * toKey,
956
+ * fromKey,
474
957
  * );
475
- *
476
- * const users2 = ISetMapped.create<User, string>(
958
+ * const second = ISetMapped.create<Point, string>(
477
959
  * [
478
- * { id: 2, department: "sales", name: "Robert" }, // Different name, same identity
479
- * { id: 1, department: "eng", name: "Alicia" } // Different name, same identity
960
+ * { x: 2, tag: 'b' },
961
+ * { x: 1, tag: 'a' },
480
962
  * ],
481
- * userToKey,
482
- * keyToUser
963
+ * toKey,
964
+ * fromKey,
483
965
  * );
484
- *
485
- * console.log(ISetMapped.equal(users1, users2)); // true (same department:id combinations)
486
- *
487
- * // Empty sets
488
- * const empty1 = ISetMapped.create<Point, string>([], pointToKey, keyToPoint);
489
- * const empty2 = ISetMapped.create<Point, string>([], pointToKey, keyToPoint);
490
- * console.log(ISetMapped.equal(empty1, empty2)); // true
491
- *
492
- * // Sets with different transformation functions but same logical content
493
- * const alternativePointToKey = (p: Point): string => `(${p.x},${p.y})`; // Different format
494
- * const alternativeKeyToPoint = (s: string): Point => {
495
- * const match = s.match(/\((\d+),(\d+)\)/)!;
496
- * return { x: Number(match[1]), y: Number(match[2]) };
497
- * };
498
- *
499
- * const set4 = ISetMapped.create<Point, string>(
500
- * [{ x: 1, y: 2 }, { x: 3, y: 4 }],
501
- * alternativePointToKey,
502
- * alternativeKeyToPoint
966
+ * const third = ISetMapped.create<Point, string>(
967
+ * [{ x: 3, tag: 'c' }],
968
+ * toKey,
969
+ * fromKey,
503
970
  * );
504
971
  *
505
- * // This would be false because the underlying mapped keys are different
506
- * console.log(ISetMapped.equal(set1, set4)); // false
972
+ * assert.ok(ISetMapped.equal(first, second));
973
+ * assert.notOk(ISetMapped.equal(first, third));
507
974
  * ```
975
+ *
976
+ * @template K The type of the custom elements.
977
+ * @template KM The type of the mapped primitive keys.
978
+ * @param a The first ISetMapped instance to compare.
979
+ * @param b The second ISetMapped instance to compare.
980
+ * @returns `true` if the sets contain exactly the same elements, `false`
981
+ * otherwise.
508
982
  */
509
983
  export const equal = <K, KM extends MapSetKeyType>(
510
984
  a: ISetMapped<K, KM>,
@@ -513,36 +987,45 @@ export namespace ISetMapped {
513
987
 
514
988
  /**
515
989
  * Computes the difference between two ISetMapped instances.
516
- * @template K The type of the elements.
517
- * @template KM The type of the mapped keys.
518
- * @param oldSet The original set.
519
- * @param newSet The new set.
520
- * @returns An object containing sets of added and deleted elements.
990
+ *
521
991
  * @example
522
- * ```typescript
523
- * type Tag = { name: string };
524
- * const tagToKey = (t: Tag): string => t.name;
525
- * const keyToTag = (name: string): Tag => ({ name });
526
992
  *
527
- * const oldTags = ISetMapped.create<Tag, string>(
528
- * [{ name: "typescript" }, { name: "javascript" }],
529
- * tagToKey,
530
- * keyToTag
993
+ * ```ts
994
+ * type Point = Readonly<{ x: number; tag: string }>;
995
+ *
996
+ * const toKey = (point: Point) => JSON.stringify(point);
997
+ *
998
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
999
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
1000
+ *
1001
+ * const previous = ISetMapped.create<Point, string>(
1002
+ * [
1003
+ * { x: 1, tag: 'a' },
1004
+ * { x: 2, tag: 'b' },
1005
+ * ],
1006
+ * toKey,
1007
+ * fromKey,
531
1008
  * );
532
- * const newTags = ISetMapped.create<Tag, string>(
533
- * [{ name: "javascript" }, { name: "react" }, { name: "nextjs" }],
534
- * tagToKey,
535
- * keyToTag
1009
+ * const current = ISetMapped.create<Point, string>(
1010
+ * [
1011
+ * { x: 2, tag: 'b' },
1012
+ * { x: 3, tag: 'c' },
1013
+ * ],
1014
+ * toKey,
1015
+ * fromKey,
536
1016
  * );
537
1017
  *
538
- * const diffResult = ISetMapped.diff(oldTags, newTags);
539
- *
540
- * console.log("Deleted tags:", diffResult.deleted.toArray().map(t => t.name));
541
- * // Output: Deleted tags: ["typescript"]
1018
+ * const { added, deleted } = ISetMapped.diff(previous, current);
542
1019
  *
543
- * console.log("Added tags:", diffResult.added.toArray().map(t => t.name));
544
- * // Output: Added tags: ["react", "nextjs"]
1020
+ * assert.deepStrictEqual(Array.from(added), [{ x: 3, tag: 'c' }]);
1021
+ * assert.deepStrictEqual(Array.from(deleted), [{ x: 1, tag: 'a' }]);
545
1022
  * ```
1023
+ *
1024
+ * @template K The type of the elements.
1025
+ * @template KM The type of the mapped keys.
1026
+ * @param oldSet The original set.
1027
+ * @param newSet The new set.
1028
+ * @returns An object containing sets of added and deleted elements.
546
1029
  */
547
1030
  export const diff = <K, KM extends MapSetKeyType>(
548
1031
  oldSet: ISetMapped<K, KM>,
@@ -554,31 +1037,41 @@ export namespace ISetMapped {
554
1037
 
555
1038
  /**
556
1039
  * Computes the intersection of two ISetMapped instances.
557
- * @template K The type of the elements.
558
- * @template KM The type of the mapped keys.
559
- * @param a The first set.
560
- * @param b The second set.
561
- * @returns A new ISetMapped instance representing the intersection.
1040
+ *
562
1041
  * @example
563
- * ```typescript
564
- * type Permission = { id: string };
565
- * const permToKey = (p: Permission): string => p.id;
566
- * const keyToPerm = (id: string): Permission => ({ id });
567
1042
  *
568
- * const userPermissions = ISetMapped.create<Permission, string>(
569
- * [{ id: "read" }, { id: "write" }, { id: "delete" }],
570
- * permToKey,
571
- * keyToPerm
1043
+ * ```ts
1044
+ * type Point = Readonly<{ x: number; tag: string }>;
1045
+ *
1046
+ * const toKey = (point: Point) => JSON.stringify(point);
1047
+ *
1048
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
1049
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
1050
+ *
1051
+ * const left = ISetMapped.create<Point, string>(
1052
+ * [
1053
+ * { x: 1, tag: 'a' },
1054
+ * { x: 2, tag: 'b' },
1055
+ * ],
1056
+ * toKey,
1057
+ * fromKey,
572
1058
  * );
573
- * const rolePermissions = ISetMapped.create<Permission, string>(
574
- * [{ id: "read" }, { id: "comment" }, { id: "write" }],
575
- * permToKey,
576
- * keyToPerm
1059
+ * const right = ISetMapped.create<Point, string>(
1060
+ * [{ x: 2, tag: 'b' }],
1061
+ * toKey,
1062
+ * fromKey,
577
1063
  * );
578
1064
  *
579
- * const commonPermissions = ISetMapped.intersection(userPermissions, rolePermissions);
580
- * console.log(commonPermissions.toArray().map(p => p.id)); // Output: ["read", "write"]
1065
+ * const overlap = ISetMapped.intersection(left, right);
1066
+ *
1067
+ * assert.deepStrictEqual(Array.from(overlap), [{ x: 2, tag: 'b' }]);
581
1068
  * ```
1069
+ *
1070
+ * @template K The type of the elements.
1071
+ * @template KM The type of the mapped keys.
1072
+ * @param a The first set.
1073
+ * @param b The second set.
1074
+ * @returns A new ISetMapped instance representing the intersection.
582
1075
  */
583
1076
  export const intersection = <K, KM extends MapSetKeyType>(
584
1077
  a: ISetMapped<K, KM>,
@@ -587,33 +1080,41 @@ export namespace ISetMapped {
587
1080
 
588
1081
  /**
589
1082
  * Computes the union of two ISetMapped instances.
1083
+ *
1084
+ * @example
1085
+ *
1086
+ * ```ts
1087
+ * type Point = Readonly<{ x: number; tag: string }>;
1088
+ *
1089
+ * const toKey = (point: Point) => JSON.stringify(point);
1090
+ *
1091
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
1092
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
1093
+ *
1094
+ * const left = ISetMapped.create<Point, string>(
1095
+ * [{ x: 1, tag: 'a' }],
1096
+ * toKey,
1097
+ * fromKey,
1098
+ * );
1099
+ * const right = ISetMapped.create<Point, string>(
1100
+ * [{ x: 2, tag: 'b' }],
1101
+ * toKey,
1102
+ * fromKey,
1103
+ * );
1104
+ *
1105
+ * const combined = ISetMapped.union(left, right);
1106
+ *
1107
+ * assert.deepStrictEqual(Array.from(combined), [
1108
+ * { x: 1, tag: 'a' },
1109
+ * { x: 2, tag: 'b' },
1110
+ * ]);
1111
+ * ```
1112
+ *
590
1113
  * @template K The type of the elements.
591
1114
  * @template KM The type of the mapped keys.
592
1115
  * @param a The first set.
593
1116
  * @param b The second set.
594
1117
  * @returns A new ISetMapped instance representing the union.
595
- * @example
596
- * ```typescript
597
- * type FeatureFlag = { flagName: string };
598
- * const flagToKey = (f: FeatureFlag): string => f.flagName;
599
- * const keyToFlag = (name: string): FeatureFlag => ({ flagName: name });
600
- *
601
- * const setA = ISetMapped.create<FeatureFlag, string>(
602
- * [{ flagName: "newUI" }, { flagName: "betaFeature" }],
603
- * flagToKey,
604
- * keyToFlag
605
- * );
606
- * const setB = ISetMapped.create<FeatureFlag, string>(
607
- * [{ flagName: "betaFeature" }, { flagName: "darkMode" }],
608
- * flagToKey,
609
- * keyToFlag
610
- * );
611
- *
612
- * const combinedFlags = ISetMapped.union(setA, setB);
613
- * // The order might vary as sets are unordered internally.
614
- * console.log(combinedFlags.toArray().map(f => f.flagName).toSorted());
615
- * // Output: ["betaFeature", "darkMode", "newUI"]
616
- * ```
617
1118
  */
618
1119
  export const union = <K, KM extends MapSetKeyType>(
619
1120
  a: ISetMapped<K, KM>,
@@ -622,13 +1123,17 @@ export namespace ISetMapped {
622
1123
  }
623
1124
 
624
1125
  /**
625
- * Internal class implementation for ISetMapped providing immutable set operations with element transformation.
1126
+ * Internal class implementation for ISetMapped providing immutable set
1127
+ * operations with element transformation.
626
1128
  *
627
- * This class implements the ISetMapped interface by maintaining a JavaScript Set with primitive keys
628
- * internally while exposing an API that works with custom element types. The transformation between
629
- * custom and primitive elements is handled transparently through the provided `toKey` and `fromKey` functions.
1129
+ * This class implements the ISetMapped interface by maintaining a JavaScript
1130
+ * Set with primitive keys internally while exposing an API that works with
1131
+ * custom element types. The transformation between custom and primitive
1132
+ * elements is handled transparently through the provided `toKey` and `fromKey`
1133
+ * functions.
630
1134
  *
631
1135
  * **Implementation Details:**
1136
+ *
632
1137
  * - Uses ReadonlySet<KM> internally where KM is the primitive key type
633
1138
  * - Stores transformation functions for bidirectional element conversion
634
1139
  * - Implements copy-on-write semantics for efficiency
@@ -652,13 +1157,13 @@ class ISetMappedClass<K, KM extends MapSetKeyType>
652
1157
  * Constructs an ISetMappedClass instance with custom element transformation.
653
1158
  *
654
1159
  * @param iterable An iterable of elements using the custom element type K.
655
- * @param toKey A function that converts a custom element K to a primitive key KM.
656
- * Must be deterministic and produce unique values for unique elements.
657
- * @param fromKey A function that converts a primitive key KM back to the custom element K.
658
- * Should be the inverse of the toKey function.
1160
+ * @param toKey A function that converts a custom element K to a primitive key
1161
+ * KM. Must be deterministic and produce unique values for unique elements.
1162
+ * @param fromKey A function that converts a primitive key KM back to the
1163
+ * custom element K. Should be the inverse of the toKey function.
659
1164
  * @param showNotFoundMessage Whether to log warning messages when operations
660
- * are performed on non-existent elements. Useful for debugging.
661
- * Defaults to false for production use.
1165
+ * are performed on non-existent elements. Useful for debugging. Defaults to
1166
+ * false for production use.
662
1167
  * @internal Use ISetMapped.create() instead of calling this constructor directly.
663
1168
  */
664
1169
  constructor(
@@ -692,8 +1197,10 @@ class ISetMappedClass<K, KM extends MapSetKeyType>
692
1197
  every<L extends K>(
693
1198
  predicate: (key: K) => key is L,
694
1199
  ): this is ISetMapped<L, KM>;
1200
+
695
1201
  /** @inheritdoc */
696
1202
  every(predicate: (key: K) => boolean): boolean;
1203
+
697
1204
  /** @inheritdoc */
698
1205
  every(predicate: (key: K) => boolean): boolean {
699
1206
  for (const key of this.values()) {
@@ -845,6 +1352,33 @@ class ISetMappedClass<K, KM extends MapSetKeyType>
845
1352
  }
846
1353
 
847
1354
  /**
1355
+ * @example
1356
+ *
1357
+ * ```ts
1358
+ * type Point = Readonly<{ x: number; tag: string }>;
1359
+ *
1360
+ * const toKey = (point: Point) => JSON.stringify(point);
1361
+ *
1362
+ * // eslint-disable-next-line total-functions/no-unsafe-type-assertion
1363
+ * const fromKey = (key: string) => JSON.parse(key) as Point;
1364
+ *
1365
+ * const set = ISetMapped.create<Point, string>(
1366
+ * [
1367
+ * { x: 1, tag: 'a' },
1368
+ * { x: 2, tag: 'b' },
1369
+ * ],
1370
+ * toKey,
1371
+ * fromKey,
1372
+ * );
1373
+ *
1374
+ * const collected = Array.from(set);
1375
+ *
1376
+ * assert.deepStrictEqual(collected, [
1377
+ * { x: 1, tag: 'a' },
1378
+ * { x: 2, tag: 'b' },
1379
+ * ]);
1380
+ * ```
1381
+ *
848
1382
  * @inheritdoc
849
1383
  */
850
1384
  *[Symbol.iterator](): Iterator<K> {