rubico 2.0.1 → 2.1.0

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 (340) hide show
  1. package/README.md +8 -8
  2. package/Transducer.js +28 -0
  3. package/Transducer.test.js +134 -97
  4. package/_internal/reducerTryCatch.js +55 -0
  5. package/dist/Transducer.es.js +28 -1
  6. package/dist/Transducer.es.min.js +2 -2
  7. package/dist/Transducer.js +28 -1
  8. package/dist/Transducer.min.js +2 -2
  9. package/dist/Transducer.mjs +28 -1
  10. package/dist/__.es.js +1 -1
  11. package/dist/__.es.min.js +1 -1
  12. package/dist/__.js +1 -1
  13. package/dist/__.min.js +1 -1
  14. package/dist/__.mjs +1 -1
  15. package/dist/all.es.js +1 -1
  16. package/dist/all.es.min.js +1 -1
  17. package/dist/all.js +1 -1
  18. package/dist/all.min.js +1 -1
  19. package/dist/all.mjs +1 -1
  20. package/dist/always.es.js +1 -1
  21. package/dist/always.es.min.js +1 -1
  22. package/dist/always.js +1 -1
  23. package/dist/always.min.js +1 -1
  24. package/dist/always.mjs +1 -1
  25. package/dist/and.es.js +1 -1
  26. package/dist/and.es.min.js +1 -1
  27. package/dist/and.js +1 -1
  28. package/dist/and.min.js +1 -1
  29. package/dist/and.mjs +1 -1
  30. package/dist/assign.es.js +1 -1
  31. package/dist/assign.es.min.js +1 -1
  32. package/dist/assign.js +1 -1
  33. package/dist/assign.min.js +1 -1
  34. package/dist/assign.mjs +1 -1
  35. package/dist/compose.es.js +1 -1
  36. package/dist/compose.es.min.js +1 -1
  37. package/dist/compose.js +1 -1
  38. package/dist/compose.min.js +1 -1
  39. package/dist/compose.mjs +1 -1
  40. package/dist/curry.es.js +1 -1
  41. package/dist/curry.es.min.js +1 -1
  42. package/dist/curry.js +1 -1
  43. package/dist/curry.min.js +1 -1
  44. package/dist/curry.mjs +1 -1
  45. package/dist/eq.es.js +1 -1
  46. package/dist/eq.es.min.js +1 -1
  47. package/dist/eq.js +1 -1
  48. package/dist/eq.min.js +1 -1
  49. package/dist/eq.mjs +1 -1
  50. package/dist/every.es.js +1 -1
  51. package/dist/every.es.min.js +1 -1
  52. package/dist/every.js +1 -1
  53. package/dist/every.min.js +1 -1
  54. package/dist/every.mjs +1 -1
  55. package/dist/filter.es.js +1 -1
  56. package/dist/filter.es.min.js +1 -1
  57. package/dist/filter.js +1 -1
  58. package/dist/filter.min.js +1 -1
  59. package/dist/filter.mjs +1 -1
  60. package/dist/flatMap.es.js +1 -1
  61. package/dist/flatMap.es.min.js +1 -1
  62. package/dist/flatMap.js +1 -1
  63. package/dist/flatMap.min.js +1 -1
  64. package/dist/flatMap.mjs +1 -1
  65. package/dist/forEach.es.js +1 -1
  66. package/dist/forEach.es.min.js +1 -1
  67. package/dist/forEach.js +1 -1
  68. package/dist/forEach.min.js +1 -1
  69. package/dist/forEach.mjs +1 -1
  70. package/dist/get.es.js +1 -1
  71. package/dist/get.es.min.js +1 -1
  72. package/dist/get.js +1 -1
  73. package/dist/get.min.js +1 -1
  74. package/dist/get.mjs +1 -1
  75. package/dist/gt.es.js +1 -1
  76. package/dist/gt.es.min.js +1 -1
  77. package/dist/gt.js +1 -1
  78. package/dist/gt.min.js +1 -1
  79. package/dist/gt.mjs +1 -1
  80. package/dist/gte.es.js +1 -1
  81. package/dist/gte.es.min.js +1 -1
  82. package/dist/gte.js +1 -1
  83. package/dist/gte.min.js +1 -1
  84. package/dist/gte.mjs +1 -1
  85. package/dist/lt.es.js +1 -1
  86. package/dist/lt.es.min.js +1 -1
  87. package/dist/lt.js +1 -1
  88. package/dist/lt.min.js +1 -1
  89. package/dist/lt.mjs +1 -1
  90. package/dist/lte.es.js +1 -1
  91. package/dist/lte.es.min.js +1 -1
  92. package/dist/lte.js +1 -1
  93. package/dist/lte.min.js +1 -1
  94. package/dist/lte.mjs +1 -1
  95. package/dist/map.es.js +1 -1
  96. package/dist/map.es.min.js +1 -1
  97. package/dist/map.js +1 -1
  98. package/dist/map.min.js +1 -1
  99. package/dist/map.mjs +1 -1
  100. package/dist/not.es.js +1 -1
  101. package/dist/not.es.min.js +1 -1
  102. package/dist/not.js +1 -1
  103. package/dist/not.min.js +1 -1
  104. package/dist/not.mjs +1 -1
  105. package/dist/omit.es.js +1 -1
  106. package/dist/omit.es.min.js +1 -1
  107. package/dist/omit.js +1 -1
  108. package/dist/omit.min.js +1 -1
  109. package/dist/omit.mjs +1 -1
  110. package/dist/or.es.js +1 -1
  111. package/dist/or.es.min.js +1 -1
  112. package/dist/or.js +1 -1
  113. package/dist/or.min.js +1 -1
  114. package/dist/or.mjs +1 -1
  115. package/dist/pick.es.js +1 -1
  116. package/dist/pick.es.min.js +1 -1
  117. package/dist/pick.js +1 -1
  118. package/dist/pick.min.js +1 -1
  119. package/dist/pick.mjs +1 -1
  120. package/dist/pipe.es.js +1 -1
  121. package/dist/pipe.es.min.js +1 -1
  122. package/dist/pipe.js +1 -1
  123. package/dist/pipe.min.js +1 -1
  124. package/dist/pipe.mjs +1 -1
  125. package/dist/reduce.es.js +1 -1
  126. package/dist/reduce.es.min.js +1 -1
  127. package/dist/reduce.js +1 -1
  128. package/dist/reduce.min.js +1 -1
  129. package/dist/reduce.mjs +1 -1
  130. package/dist/rubico.es.js +1 -1
  131. package/dist/rubico.es.min.js +1 -1
  132. package/dist/rubico.global.js +1 -1
  133. package/dist/rubico.global.min.js +1 -1
  134. package/dist/rubico.js +1 -1
  135. package/dist/rubico.min.js +1 -1
  136. package/dist/rubico.mjs +1 -1
  137. package/dist/set.es.js +1 -1
  138. package/dist/set.es.min.js +1 -1
  139. package/dist/set.js +1 -1
  140. package/dist/set.min.js +1 -1
  141. package/dist/set.mjs +1 -1
  142. package/dist/some.es.js +1 -1
  143. package/dist/some.es.min.js +1 -1
  144. package/dist/some.js +1 -1
  145. package/dist/some.min.js +1 -1
  146. package/dist/some.mjs +1 -1
  147. package/dist/switchCase.es.js +1 -1
  148. package/dist/switchCase.es.min.js +1 -1
  149. package/dist/switchCase.js +1 -1
  150. package/dist/switchCase.min.js +1 -1
  151. package/dist/switchCase.mjs +1 -1
  152. package/dist/tap.es.js +1 -1
  153. package/dist/tap.es.min.js +1 -1
  154. package/dist/tap.js +1 -1
  155. package/dist/tap.min.js +1 -1
  156. package/dist/tap.mjs +1 -1
  157. package/dist/thunkify.es.js +1 -1
  158. package/dist/thunkify.es.min.js +1 -1
  159. package/dist/thunkify.js +1 -1
  160. package/dist/thunkify.min.js +1 -1
  161. package/dist/thunkify.mjs +1 -1
  162. package/dist/transform.es.js +1 -1
  163. package/dist/transform.es.min.js +1 -1
  164. package/dist/transform.js +1 -1
  165. package/dist/transform.min.js +1 -1
  166. package/dist/transform.mjs +1 -1
  167. package/dist/tryCatch.es.js +1 -1
  168. package/dist/tryCatch.es.min.js +1 -1
  169. package/dist/tryCatch.js +1 -1
  170. package/dist/tryCatch.min.js +1 -1
  171. package/dist/tryCatch.mjs +1 -1
  172. package/dist/x/append.es.js +1 -1
  173. package/dist/x/append.es.min.js +1 -1
  174. package/dist/x/append.js +1 -1
  175. package/dist/x/append.min.js +1 -1
  176. package/dist/x/append.mjs +1 -1
  177. package/dist/x/callProp.es.js +1 -1
  178. package/dist/x/callProp.es.min.js +1 -1
  179. package/dist/x/callProp.js +1 -1
  180. package/dist/x/callProp.min.js +1 -1
  181. package/dist/x/callProp.mjs +1 -1
  182. package/dist/x/defaultsDeep.es.js +1 -1
  183. package/dist/x/defaultsDeep.es.min.js +1 -1
  184. package/dist/x/defaultsDeep.js +1 -1
  185. package/dist/x/defaultsDeep.min.js +1 -1
  186. package/dist/x/defaultsDeep.mjs +1 -1
  187. package/dist/x/differenceWith.es.js +1 -1
  188. package/dist/x/differenceWith.es.min.js +1 -1
  189. package/dist/x/differenceWith.js +1 -1
  190. package/dist/x/differenceWith.min.js +1 -1
  191. package/dist/x/differenceWith.mjs +1 -1
  192. package/dist/x/filterOut.es.js +1 -1
  193. package/dist/x/filterOut.es.min.js +1 -1
  194. package/dist/x/filterOut.js +1 -1
  195. package/dist/x/filterOut.min.js +1 -1
  196. package/dist/x/filterOut.mjs +1 -1
  197. package/dist/x/find.es.js +1 -1
  198. package/dist/x/find.es.min.js +1 -1
  199. package/dist/x/find.js +1 -1
  200. package/dist/x/find.min.js +1 -1
  201. package/dist/x/find.mjs +1 -1
  202. package/dist/x/findIndex.es.js +1 -1
  203. package/dist/x/findIndex.es.min.js +1 -1
  204. package/dist/x/findIndex.js +1 -1
  205. package/dist/x/findIndex.min.js +1 -1
  206. package/dist/x/findIndex.mjs +1 -1
  207. package/dist/x/first.es.js +1 -1
  208. package/dist/x/first.es.min.js +1 -1
  209. package/dist/x/first.js +1 -1
  210. package/dist/x/first.min.js +1 -1
  211. package/dist/x/first.mjs +1 -1
  212. package/dist/x/flatten.es.js +1 -1
  213. package/dist/x/flatten.es.min.js +1 -1
  214. package/dist/x/flatten.js +1 -1
  215. package/dist/x/flatten.min.js +1 -1
  216. package/dist/x/flatten.mjs +1 -1
  217. package/dist/x/groupBy.es.js +1 -1
  218. package/dist/x/groupBy.es.min.js +1 -1
  219. package/dist/x/groupBy.js +1 -1
  220. package/dist/x/groupBy.min.js +1 -1
  221. package/dist/x/groupBy.mjs +1 -1
  222. package/dist/x/has.es.js +1 -1
  223. package/dist/x/has.es.min.js +1 -1
  224. package/dist/x/has.js +1 -1
  225. package/dist/x/has.min.js +1 -1
  226. package/dist/x/has.mjs +1 -1
  227. package/dist/x/identity.es.js +1 -1
  228. package/dist/x/identity.es.min.js +1 -1
  229. package/dist/x/identity.js +1 -1
  230. package/dist/x/identity.min.js +1 -1
  231. package/dist/x/identity.mjs +1 -1
  232. package/dist/x/includes.es.js +1 -1
  233. package/dist/x/includes.es.min.js +1 -1
  234. package/dist/x/includes.js +1 -1
  235. package/dist/x/includes.min.js +1 -1
  236. package/dist/x/includes.mjs +1 -1
  237. package/dist/x/isDeepEqual.es.js +1 -1
  238. package/dist/x/isDeepEqual.es.min.js +1 -1
  239. package/dist/x/isDeepEqual.js +1 -1
  240. package/dist/x/isDeepEqual.min.js +1 -1
  241. package/dist/x/isDeepEqual.mjs +1 -1
  242. package/dist/x/isEmpty.es.js +1 -1
  243. package/dist/x/isEmpty.es.min.js +1 -1
  244. package/dist/x/isEmpty.js +1 -1
  245. package/dist/x/isEmpty.min.js +1 -1
  246. package/dist/x/isEmpty.mjs +1 -1
  247. package/dist/x/isEqual.es.js +1 -1
  248. package/dist/x/isEqual.es.min.js +1 -1
  249. package/dist/x/isEqual.js +1 -1
  250. package/dist/x/isEqual.min.js +1 -1
  251. package/dist/x/isEqual.mjs +1 -1
  252. package/dist/x/isFunction.es.js +1 -1
  253. package/dist/x/isFunction.es.min.js +1 -1
  254. package/dist/x/isFunction.js +1 -1
  255. package/dist/x/isFunction.min.js +1 -1
  256. package/dist/x/isFunction.mjs +1 -1
  257. package/dist/x/isIn.es.js +1 -1
  258. package/dist/x/isIn.es.min.js +1 -1
  259. package/dist/x/isIn.js +1 -1
  260. package/dist/x/isIn.min.js +1 -1
  261. package/dist/x/isIn.mjs +1 -1
  262. package/dist/x/isObject.es.js +1 -1
  263. package/dist/x/isObject.es.min.js +1 -1
  264. package/dist/x/isObject.js +1 -1
  265. package/dist/x/isObject.min.js +1 -1
  266. package/dist/x/isObject.mjs +1 -1
  267. package/dist/x/isString.es.js +1 -1
  268. package/dist/x/isString.es.min.js +1 -1
  269. package/dist/x/isString.js +1 -1
  270. package/dist/x/isString.min.js +1 -1
  271. package/dist/x/isString.mjs +1 -1
  272. package/dist/x/keys.es.js +1 -1
  273. package/dist/x/keys.es.min.js +1 -1
  274. package/dist/x/keys.js +1 -1
  275. package/dist/x/keys.min.js +1 -1
  276. package/dist/x/keys.mjs +1 -1
  277. package/dist/x/last.es.js +1 -1
  278. package/dist/x/last.es.min.js +1 -1
  279. package/dist/x/last.js +1 -1
  280. package/dist/x/last.min.js +1 -1
  281. package/dist/x/last.mjs +1 -1
  282. package/dist/x/maxBy.es.js +1 -1
  283. package/dist/x/maxBy.es.min.js +1 -1
  284. package/dist/x/maxBy.js +1 -1
  285. package/dist/x/maxBy.min.js +1 -1
  286. package/dist/x/maxBy.mjs +1 -1
  287. package/dist/x/noop.es.js +1 -1
  288. package/dist/x/noop.es.min.js +1 -1
  289. package/dist/x/noop.js +1 -1
  290. package/dist/x/noop.min.js +1 -1
  291. package/dist/x/noop.mjs +1 -1
  292. package/dist/x/pluck.es.js +1 -1
  293. package/dist/x/pluck.es.min.js +1 -1
  294. package/dist/x/pluck.js +1 -1
  295. package/dist/x/pluck.min.js +1 -1
  296. package/dist/x/pluck.mjs +1 -1
  297. package/dist/x/prepend.es.js +1 -1
  298. package/dist/x/prepend.es.min.js +1 -1
  299. package/dist/x/prepend.js +1 -1
  300. package/dist/x/prepend.min.js +1 -1
  301. package/dist/x/prepend.mjs +1 -1
  302. package/dist/x/size.es.js +1 -1
  303. package/dist/x/size.es.min.js +1 -1
  304. package/dist/x/size.js +1 -1
  305. package/dist/x/size.min.js +1 -1
  306. package/dist/x/size.mjs +1 -1
  307. package/dist/x/trace.es.js +1 -1
  308. package/dist/x/trace.es.min.js +1 -1
  309. package/dist/x/trace.js +1 -1
  310. package/dist/x/trace.min.js +1 -1
  311. package/dist/x/trace.mjs +1 -1
  312. package/dist/x/unionWith.es.js +1 -1
  313. package/dist/x/unionWith.es.min.js +1 -1
  314. package/dist/x/unionWith.js +1 -1
  315. package/dist/x/unionWith.min.js +1 -1
  316. package/dist/x/unionWith.mjs +1 -1
  317. package/dist/x/uniq.es.js +1 -1
  318. package/dist/x/uniq.es.min.js +1 -1
  319. package/dist/x/uniq.js +1 -1
  320. package/dist/x/uniq.min.js +1 -1
  321. package/dist/x/uniq.mjs +1 -1
  322. package/dist/x/unless.es.js +1 -1
  323. package/dist/x/unless.es.min.js +1 -1
  324. package/dist/x/unless.js +1 -1
  325. package/dist/x/unless.min.js +1 -1
  326. package/dist/x/unless.mjs +1 -1
  327. package/dist/x/values.es.js +1 -1
  328. package/dist/x/values.es.min.js +1 -1
  329. package/dist/x/values.js +1 -1
  330. package/dist/x/values.min.js +1 -1
  331. package/dist/x/values.mjs +1 -1
  332. package/dist/x/when.es.js +1 -1
  333. package/dist/x/when.es.min.js +1 -1
  334. package/dist/x/when.js +1 -1
  335. package/dist/x/when.min.js +1 -1
  336. package/dist/x/when.mjs +1 -1
  337. package/dist-test.js +1 -1
  338. package/es.js +1 -1
  339. package/index.js +1 -1
  340. package/package.json +1 -1
package/README.md CHANGED
@@ -69,7 +69,7 @@ import `rubico` in the browser.
69
69
  <script src="https://unpkg.com/rubico/dist/pipe.min.js"></script>
70
70
 
71
71
  <!-- import an operator from rubico/x -->
72
- <script src="https://unpkg.com/rubico/dist/x/defaultsDeep.js"></script>
72
+ <script src="https://unpkg.com/rubico/dist/x/defaultsDeep.min.js"></script>
73
73
 
74
74
  <!-- import rubico's Transducer module -->
75
75
  <script src="https://unpkg.com/rubico/dist/Transducer.min.js"></script>
@@ -89,7 +89,7 @@ When you import this library, you obtain the freedom that comes from having thos
89
89
 
90
90
  # Introduction
91
91
 
92
- rubico is a library for async-enabled functional programming in JavaScript that supports a simple and composable functional style in asynchronous environments. The core exports a small number of functions that can be grouped into categories for programming operations.
92
+ rubico is a library for async-enabled functional programming in JavaScript. The library methods support a simple and composable functional style in asynchronous environments.
93
93
 
94
94
  ```javascript
95
95
  const {
@@ -122,7 +122,7 @@ const {
122
122
  } = rubico
123
123
  ```
124
124
 
125
- With async-enabled, or [a]synchronous, functional programming, functions provided to the rubico operators may be asynchronous and return a Promise. Any promises provided to the operators in argument position are also resolved before continuing with the operation.
125
+ With async-enabled, or [a]synchronous, functional programming, functions provided to the rubico methods may be asynchronous and return a Promise. Any promises in argument position are also resolved before continuing with the operation.
126
126
 
127
127
  ```javascript [playground]
128
128
  const helloPromise = Promise.resolve('hello')
@@ -136,7 +136,7 @@ pipe(helloPromise, [ // helloPromise is resolved for 'hello'
136
136
  ])
137
137
  ```
138
138
 
139
- Most operators support two kinds of API: one eager and one tacit. With the eager API, the operator consumes the data as the first argument followed by the common arguments, executing eagerly with one call. With the tacit API, the operator takes the common arguments without the data argument, returning a lazily evaluated operator that executes once called with the data argument. Operators having both an eager and tacit API supports a natural and composable code style.
139
+ Most methods support both an eager and a tacit API. The eager API takes all required arguments and executes at once, while its tacit API takes only the non-data arguments and executes lazily, returning a function that expects the data arguments. This dual API supports a natural and composable code style.
140
140
 
141
141
  ```javascript [playground]
142
142
  const myObj = { a: 1, b: 2, c: 3 }
@@ -153,7 +153,7 @@ console.log(myDuplicatedSquaredObject)
153
153
  // { a: [1, 1], b: [4, 4], c: [9, 9] }
154
154
  ```
155
155
 
156
- The rubico operators are versatile and act on a wide range of vanilla JavaScript types to create declarative, extensible, and async-enabled function compositions. The same operator `map` can act on an array and also act on a `Map` data structure.
156
+ The rubico methods are versatile and act on a wide range of vanilla JavaScript types to create declarative, extensible, and async-enabled function compositions. The same operator `map` can act on an array and also a `Map` data structure.
157
157
 
158
158
  ```javascript [playground]
159
159
  const { pipe, tap, map, filter } = rubico
@@ -206,7 +206,7 @@ pipe(todoIDs, [
206
206
  ])
207
207
  ```
208
208
 
209
- rubico also offers transducers in its `Transducer` module. You can consume these transducers with the `transform` and `compose` operators. Due to the way transducers are implemented, you should use `compose` over `pipe` to chain a left-to-right composition of transducers.
209
+ rubico offers transducers in its `Transducer` module. You can consume these transducers with the `transform` and `compose` methods. You should use `compose` over `pipe` to chain a left-to-right composition of transducers.
210
210
 
211
211
  ```javascript [playground]
212
212
  const isOdd = number => number % 2 == 1
@@ -230,12 +230,12 @@ pipe(generateNumbers(), [
230
230
  ])
231
231
  ```
232
232
 
233
- For advanced asynchronous use cases, check out the property functions on some of the operators like `map`, e.g.
233
+ For advanced asynchronous use cases, some of the methods have property functions that have different asynchronous behavior, e.g.
234
234
  * `map` - apply a mapper function concurrently
235
235
  * `map.pool` - apply a mapper function concurrently with a concurrency limit
236
236
  * `map.series` - apply a mapper function serially
237
237
 
238
- For more advanced functions, please visit `rubico/x`. You can find the full documentation at [rubico.land/docs](https://rubico.land/docs).
238
+ For more functions beyond the core methods, please visit `rubico/x`. You can find the full documentation at [rubico.land/docs](https://rubico.land/docs).
239
239
 
240
240
  # Contributing
241
241
  Your feedback and contributions are welcome. If you have a suggestion, please raise an issue. Prior to that, please search through the issues first in case your suggestion has been made already. If you decide to work on an issue, or feel like taking initiative and contributing anything at all, feel free to create a pull request and I will get back to you shortly.
package/Transducer.js CHANGED
@@ -3,7 +3,9 @@ const reducerMap = require('./_internal/reducerMap')
3
3
  const reducerFilter = require('./_internal/reducerFilter')
4
4
  const reducerFlatMap = require('./_internal/reducerFlatMap')
5
5
  const reducerForEach = require('./_internal/reducerForEach')
6
+ const reducerTryCatch = require('./_internal/reducerTryCatch')
6
7
  const curry2 = require('./_internal/curry2')
8
+ const curry3 = require('./_internal/curry3')
7
9
  const __ = require('./_internal/placeholder')
8
10
 
9
11
  /**
@@ -155,8 +157,34 @@ Transducer.forEach = function transducerForEach(func) {
155
157
  return curry2(reducerForEach, __, func)
156
158
  }
157
159
 
160
+ /**
161
+ * @name Transducer.passthrough
162
+ *
163
+ * @synopsis
164
+ * ```coffeescript [specscript]
165
+ * type Reducer = (accumulator any, item any)=>(nextAccumulator Promise|any)
166
+ * type Transducer = Reducer=>Reducer
167
+ *
168
+ * Transducer.passthrough(func function) -> passthroughTransducer Transducer
169
+ * ```
170
+ */
158
171
  Transducer.passthrough = function transducerPassthrough(reducer) {
159
172
  return reducer
160
173
  }
161
174
 
175
+ /**
176
+ * @name Transducer.tryCatch
177
+ *
178
+ * @synopsis
179
+ * ```coffeescript [specscript]
180
+ * type Reducer = (accumulator any, item any)=>(nextAccumulator Promise|any)
181
+ * type Transducer = Reducer=>Reducer
182
+ *
183
+ * Transducer.tryCatch(func function) -> tryCatchTransducer Transducer
184
+ * ```
185
+ */
186
+ Transducer.tryCatch = function transducerTryCatch(transducerTryer, catcher) {
187
+ return curry3(reducerTryCatch, __, transducerTryer, catcher)
188
+ }
189
+
162
190
  module.exports = Transducer
@@ -1,117 +1,154 @@
1
- const assert = require('assert')
1
+ require('./global')
2
2
  const Transducer = require('./Transducer')
3
- const compose = require('./compose')
4
- const reduce = require('./reduce')
5
- const transform = require('./transform')
3
+ const assert = require('assert')
6
4
 
7
5
  describe('Transducer', () => {
8
6
  const ade = assert.deepEqual
9
7
  const ase = assert.strictEqual
10
8
  const aok = assert.ok
11
9
 
12
- describe('integration: transducers from Transducer.map, Transducer.filter, Transducer.flatMap', () => {
13
- const concat = (y, xi) => y.concat(xi)
14
- const add = (y, xi) => y + xi
15
- const isOdd = number => number % 2 == 1
10
+ const concat = (y, xi) => y.concat(xi)
11
+ const add = (y, xi) => y + xi
12
+ const isOdd = number => number % 2 == 1
16
13
 
17
- it('reduce with sync transduced reducers', async () => {
18
- const squareOdds = compose([
19
- Transducer.filter(isOdd),
20
- Transducer.map(x => x ** 2),
21
- ])
22
- ade(
23
- reduce(squareOdds(concat), [])([1, 2, 3, 4, 5]),
24
- [1, 9, 25],
25
- )
26
- ade(
27
- reduce(squareOdds((y, xi) => y.add(xi)), new Set())([1, 2, 3, 4, 5]),
28
- new Set([1, 9, 25]),
29
- )
30
- const appendAlphas = compose([
31
- Transducer.map(x => `${x}a`),
32
- Transducer.map(x => `${x}b`),
33
- Transducer.map(x => `${x}c`),
34
- ])
35
- ase(
36
- reduce(appendAlphas(add), '')('123'),
37
- '1abc2abc3abc',
38
- )
39
- ade(
40
- reduce(appendAlphas(concat), [])('123'),
41
- ['1abc', '2abc', '3abc'],
42
- )
43
- })
14
+ it('reduce with sync transduced reducers', async () => {
15
+ const squareOdds = compose([
16
+ Transducer.filter(isOdd),
17
+ Transducer.map(x => x ** 2),
18
+ ])
19
+ ade(
20
+ reduce(squareOdds(concat), [])([1, 2, 3, 4, 5]),
21
+ [1, 9, 25],
22
+ )
23
+ ade(
24
+ reduce(squareOdds((y, xi) => y.add(xi)), new Set())([1, 2, 3, 4, 5]),
25
+ new Set([1, 9, 25]),
26
+ )
27
+ const appendAlphas = compose([
28
+ Transducer.map(x => `${x}a`),
29
+ Transducer.map(x => `${x}b`),
30
+ Transducer.map(x => `${x}c`),
31
+ ])
32
+ ase(
33
+ reduce(appendAlphas(add), '')('123'),
34
+ '1abc2abc3abc',
35
+ )
36
+ ade(
37
+ reduce(appendAlphas(concat), [])('123'),
38
+ ['1abc', '2abc', '3abc'],
39
+ )
40
+ })
44
41
 
45
- it('reduce with an async transduced reducer', async () => {
46
- const hosWithHey = compose([
47
- Transducer.filter(async x => x === 'ho'),
48
- Transducer.map(x => Promise.resolve(`${x}hey`)),
49
- ])
50
- const hihos = { a: 'hi', b: 'ho', c: 'hi', d: 'ho', e: 'hi', f: 'ho' }
51
- aok(reduce(hosWithHey(add), '')(hihos) instanceof Promise),
52
- aok(reduce(hosWithHey(concat), [])(hihos) instanceof Promise),
53
- ase(
54
- await reduce(hosWithHey(add), '')(hihos),
55
- 'hoheyhoheyhohey',
56
- )
57
- ade(
58
- await reduce(hosWithHey(concat), [])(hihos),
59
- ['hohey', 'hohey', 'hohey'],
60
- )
61
- })
42
+ it('reduce with an async transduced reducer', async () => {
43
+ const hosWithHey = compose([
44
+ Transducer.filter(async x => x === 'ho'),
45
+ Transducer.map(x => Promise.resolve(`${x}hey`)),
46
+ ])
47
+ const hihos = { a: 'hi', b: 'ho', c: 'hi', d: 'ho', e: 'hi', f: 'ho' }
48
+ aok(reduce(hosWithHey(add), '')(hihos) instanceof Promise),
49
+ aok(reduce(hosWithHey(concat), [])(hihos) instanceof Promise),
50
+ ase(
51
+ await reduce(hosWithHey(add), '')(hihos),
52
+ 'hoheyhoheyhohey',
53
+ )
54
+ ade(
55
+ await reduce(hosWithHey(concat), [])(hihos),
56
+ ['hohey', 'hohey', 'hohey'],
57
+ )
58
+ })
62
59
 
63
- it('flatMapping transducer', async () => {
64
- const createOddMultiplesSync = compose([
65
- Transducer.filter(isOdd),
66
- Transducer.flatMap(number => [number * 2, number * 3]),
67
- ])
60
+ it('transform with error handling on a transducer composition', async () => {
61
+ const caughtErrors = []
62
+ const numbers = [1, 2, 3, 4, 5]
63
+ const result = await transform(numbers, Transducer.tryCatch(compose([
64
+ Transducer.filter(number => number % 2 == 1),
65
+ Transducer.map(number => number ** 2),
66
+ Transducer.map(number => {
67
+ throw new Error(number)
68
+ }),
69
+ Transducer.map(number => number * 10), // should never reach here
70
+ ]), (error, item) => {
71
+ caughtErrors.push(error)
72
+ return item
73
+ }), [])
74
+ assert.equal(caughtErrors.length, 3)
75
+ assert.deepEqual(result, [1, 3, 5])
76
+ assert.deepEqual(caughtErrors.map(get('message')), ['1', '9', '25'])
77
+ })
68
78
 
69
- ase(
70
- reduce([1, 2, 3], createOddMultiplesSync(add), 0),
71
- 2 + 3 + 6 + 9,
72
- )
73
- ade(
74
- reduce([1, 2, 3], createOddMultiplesSync(concat), []),
75
- [2, 3, 6, 9],
76
- )
79
+ it('transform with error handling on a transducer in a composition', async () => {
80
+ const caughtErrors = []
81
+ const numbers = [1, 2, 3, 4, 5]
82
+ const result = await transform(numbers, compose([
83
+ Transducer.filter(number => number % 2 == 1),
84
+ Transducer.map(number => number ** 2),
85
+ Transducer.tryCatch(
86
+ Transducer.map(number => {
87
+ throw new Error(number)
88
+ }),
89
+ (error, item) => {
90
+ caughtErrors.push(error)
91
+ return item
92
+ },
93
+ ),
94
+ Transducer.map(number => number * 10), // should reach here with error handler
95
+ ]), [])
96
+ assert.equal(caughtErrors.length, 3)
97
+ assert.deepEqual(result, [10, 90, 250])
98
+ assert.deepEqual(caughtErrors.map(get('message')), ['1', '9', '25'])
99
+ })
77
100
 
78
- const createOddMultiplesAsync = compose([
79
- Transducer.filter(isOdd),
80
- Transducer.flatMap(async number => [number * 2, number * 3]),
81
- ])
101
+ it('flatMapping transducer', async () => {
102
+ const createOddMultiplesSync = compose([
103
+ Transducer.filter(isOdd),
104
+ Transducer.flatMap(number => [number * 2, number * 3]),
105
+ ])
82
106
 
83
- const p1 = reduce([1, 2, 3], createOddMultiplesAsync(add), 0)
84
- aok(p1 instanceof Promise)
85
- const p2 = reduce([1, 2, 3], createOddMultiplesAsync(concat), [])
86
- aok(p2 instanceof Promise)
87
- await p1.then(result => {
88
- ase(result, 2 + 3 + 6 + 9)
89
- })
90
- await p2.then(result => {
91
- ade(result, [2, 3, 6, 9])
92
- })
93
- })
107
+ ase(
108
+ reduce([1, 2, 3], createOddMultiplesSync(add), 0),
109
+ 2 + 3 + 6 + 9,
110
+ )
111
+ ade(
112
+ reduce([1, 2, 3], createOddMultiplesSync(concat), []),
113
+ [2, 3, 6, 9],
114
+ )
94
115
 
95
- it('forEach transducer', async () => {
96
- let sum1 = 0
97
- reduce([1, 2, 3, 4, 5], Transducer.forEach(number => {
98
- sum1 += number
99
- })(() => {}), null)
100
- assert.equal(sum1, 15)
116
+ const createOddMultiplesAsync = compose([
117
+ Transducer.filter(isOdd),
118
+ Transducer.flatMap(async number => [number * 2, number * 3]),
119
+ ])
101
120
 
102
- let sum2 = 0
103
- await reduce([1, 2, 3, 4, 5], Transducer.forEach(async number => {
104
- sum2 += number
105
- })(() => {}), null)
106
- assert.equal(sum2, 15)
121
+ const p1 = reduce([1, 2, 3], createOddMultiplesAsync(add), 0)
122
+ aok(p1 instanceof Promise)
123
+ const p2 = reduce([1, 2, 3], createOddMultiplesAsync(concat), [])
124
+ aok(p2 instanceof Promise)
125
+ await p1.then(result => {
126
+ ase(result, 2 + 3 + 6 + 9)
107
127
  })
108
-
109
- it('passthrough transducer', async () => {
110
- assert.deepEqual(
111
- transform({ a: 1, b: 2, c: 3 }, Transducer.passthrough, []),
112
- [1, 2, 3],
113
- )
128
+ await p2.then(result => {
129
+ ade(result, [2, 3, 6, 9])
114
130
  })
115
131
  })
116
132
 
133
+ it('forEach transducer', async () => {
134
+ let sum1 = 0
135
+ reduce([1, 2, 3, 4, 5], Transducer.forEach(number => {
136
+ sum1 += number
137
+ })(() => {}), null)
138
+ assert.equal(sum1, 15)
139
+
140
+ let sum2 = 0
141
+ await reduce([1, 2, 3, 4, 5], Transducer.forEach(async number => {
142
+ sum2 += number
143
+ })(() => {}), null)
144
+ assert.equal(sum2, 15)
145
+ })
146
+
147
+ it('passthrough transducer', async () => {
148
+ assert.deepEqual(
149
+ transform({ a: 1, b: 2, c: 3 }, Transducer.passthrough, []),
150
+ [1, 2, 3],
151
+ )
152
+ })
153
+
117
154
  })
@@ -0,0 +1,55 @@
1
+ const isPromise = require('./isPromise')
2
+ const __ = require('./placeholder')
3
+ const curry5 = require('./curry5')
4
+ const curry2 = require('./curry2')
5
+
6
+ /**
7
+ * @name _reducerTryCatchErrorHandler
8
+ *
9
+ * @synopsis
10
+ * ```coffeescript [specscript]
11
+ * _reducerTryCatchErrorHandler(
12
+ * reducer function,
13
+ * error Error,
14
+ * accum any,
15
+ * item any,
16
+ * ) -> Promise|any
17
+ * ```
18
+ */
19
+ const _reducerTryCatchErrorHandler = function (
20
+ catcher, reducer, error, accum, item,
21
+ ) {
22
+ const c = catcher(error, item)
23
+ return isPromise(c) ? c.then(curry2(reducer, accum, __)) : reducer(accum, c)
24
+ }
25
+
26
+ /**
27
+ * @name reducerTryCatch
28
+ *
29
+ * @synopsis
30
+ * ```coffeescript [specscript]
31
+ * type Reducer = (accum any, item any)=>(nextAccumulator Promise|any)
32
+ *
33
+ * reducerTryCatch(
34
+ * reducer function,
35
+ * catcher function,
36
+ * ) -> errorHandlingReducer function
37
+ * ```
38
+ */
39
+ const reducerTryCatch = function (reducer, transducerTryer, catcher) {
40
+ const finalReducer = transducerTryer(reducer)
41
+ return function errorHandlingReducer(accum, item) {
42
+ try {
43
+ const ret = finalReducer(accum, item)
44
+ return isPromise(ret) ? ret.catch(curry5(
45
+ _reducerTryCatchErrorHandler, catcher, reducer, __, accum, item,
46
+ )) : ret
47
+ } catch (error) {
48
+ return _reducerTryCatchErrorHandler(
49
+ catcher, reducer, error, accum, item,
50
+ )
51
+ }
52
+ }
53
+ }
54
+
55
+ module.exports = reducerTryCatch
@@ -1,5 +1,5 @@
1
1
  /**
2
- * rubico v2.0.1
2
+ * rubico v2.1.0
3
3
  * https://github.com/a-synchronous/rubico
4
4
  * (c) 2019-2023 Richard Tong
5
5
  * rubico may be freely distributed under the MIT license.
@@ -456,6 +456,29 @@ const reducerForEach = (
456
456
  return reducer(result, item)
457
457
  }
458
458
 
459
+ const _reducerTryCatchErrorHandler = function (
460
+ catcher, reducer, error, accum, item,
461
+ ) {
462
+ const c = catcher(error, item)
463
+ return isPromise(c) ? c.then(curry2(reducer, accum, __)) : reducer(accum, c)
464
+ }
465
+
466
+ const reducerTryCatch = function (reducer, transducerTryer, catcher) {
467
+ const finalReducer = transducerTryer(reducer)
468
+ return function errorHandlingReducer(accum, item) {
469
+ try {
470
+ const ret = finalReducer(accum, item)
471
+ return isPromise(ret) ? ret.catch(curry5(
472
+ _reducerTryCatchErrorHandler, catcher, reducer, __, accum, item,
473
+ )) : ret
474
+ } catch (error) {
475
+ return _reducerTryCatchErrorHandler(
476
+ catcher, reducer, error, accum, item,
477
+ )
478
+ }
479
+ }
480
+ }
481
+
459
482
  const Transducer = {}
460
483
 
461
484
  Transducer.map = function transducerMap(mapper) {
@@ -478,4 +501,8 @@ Transducer.passthrough = function transducerPassthrough(reducer) {
478
501
  return reducer
479
502
  }
480
503
 
504
+ Transducer.tryCatch = function transducerTryCatch(transducerTryer, catcher) {
505
+ return curry3(reducerTryCatch, __, transducerTryer, catcher)
506
+ }
507
+
481
508
  export default Transducer
@@ -1,7 +1,7 @@
1
1
  /**
2
- * rubico v2.0.1
2
+ * rubico v2.1.0
3
3
  * https://github.com/a-synchronous/rubico
4
4
  * (c) 2019-2023 Richard Tong
5
5
  * rubico may be freely distributed under the MIT license.
6
6
  */
7
- const isPromise=r=>null!=r&&"function"==typeof r.then,funcConcat=(r,e)=>function(...n){const t=r(...n);return isPromise(t)?t.then(e):e(t)},__=Symbol.for("placeholder"),curry2ResolveArg0=(r,e)=>function(n){return r(n,e)},curry2ResolveArg1=(r,e)=>function(n){return r(e,n)},curry2=function(r,e,n){return e==__?curry2ResolveArg0(r,n):curry2ResolveArg1(r,e)},reducerMap=(r,e)=>function(n,t){const o=e(t);return isPromise(o)?o.then(curry2(r,n,__)):r(n,o)},curry3ResolveArg0=(r,e,n)=>function(t){return r(t,e,n)},curry3ResolveArg1=(r,e,n)=>function(t){return r(e,t,n)},curry3ResolveArg2=(r,e,n)=>function(t){return r(e,n,t)},curry3=function(r,e,n,t){return e==__?curry3ResolveArg0(r,n,t):n==__?curry3ResolveArg1(r,e,t):curry3ResolveArg2(r,e,n)},thunkify2=(r,e,n)=>function(){return r(e,n)},thunkConditional=(r,e,n)=>r?e():n(),always=r=>function(){return r},reducerFilter=(r,e)=>function(n,t){const o=e(t);return isPromise(o)?o.then(curry3(thunkConditional,__,thunkify2(r,n,t),(c=n,function(){return c}))):o?r(n,t):n;var c},isArray=Array.isArray,objectValues=Object.values,objectProto=Object.prototype,nativeObjectToString=objectProto.toString,objectToString=r=>nativeObjectToString.call(r),generatorFunctionTag="[object GeneratorFunction]",isGeneratorFunction=r=>objectToString(r)==generatorFunctionTag,asyncGeneratorFunctionTag="[object AsyncGeneratorFunction]",isAsyncGeneratorFunction=r=>objectToString(r)==asyncGeneratorFunctionTag,iteratorReduceAsync=async function(r,e,n){let t=r.next();if(t.done)return n;for(;!t.done;)n=e(n,t.value),isPromise(n)&&(n=await n),t=r.next();return n},iteratorReduce=function(r,e,n){let t=r.next();if(t.done)return n;for(void 0===n&&(n=t.value,t=r.next());!t.done;){if(n=e(n,t.value),isPromise(n))return n.then(curry3(iteratorReduceAsync,r,e,__));t=r.next()}return n},asyncIteratorReduce=async function(r,e,n){let t=await r.next();if(t.done)return n;for(void 0===n&&(n=t.value,t=await r.next());!t.done;)n=await e(n,t.value),t=await r.next();return n},symbolIterator=Symbol.iterator,symbolAsyncIterator=Symbol.asyncIterator,curryArgs3ResolveArgs0=(r,e,n)=>function(...t){return r(t,e,n)},curryArgs3ResolveArgs1=(r,e,n)=>function(...t){return r(e,t,n)},curryArgs3ResolveArgs2=(r,e,n)=>function(...t){return r(e,n,t)},curryArgs3=function(r,e,n,t){return e==__?curryArgs3ResolveArgs0(r,n,t):n==__?curryArgs3ResolveArgs1(r,e,t):curryArgs3ResolveArgs2(r,e,n)},curry4ResolveArg0=(r,e,n,t)=>function(o){return r(o,e,n,t)},curry4ResolveArg1=(r,e,n,t)=>function(o){return r(e,o,n,t)},curry4ResolveArg2=(r,e,n,t)=>function(o){return r(e,n,o,t)},curry4ResolveArg3=(r,e,n,t)=>function(o){return r(e,n,t,o)},curry4=function(r,e,n,t,o){return e==__?curry4ResolveArg0(r,n,t,o):n==__?curry4ResolveArg1(r,e,t,o):t==__?curry4ResolveArg2(r,e,n,o):curry4ResolveArg3(r,e,n,t)},arrayReduceAsync=async function(r,e,n,t){const o=r.length;for(;++t<o;)n=e(n,r[t],t,r),isPromise(n)&&(n=await n);return n},arrayReduce=function(r,e,n){const t=r.length;let o=-1;for(void 0===n&&(n=r[++o]);++o<t;)if(n=e(n,r[o],o,r),isPromise(n))return n.then(curry4(arrayReduceAsync,r,e,__,o));return n},curry5ResolveArg0=(r,e,n,t,o)=>function(c){return r(c,e,n,t,o)},curry5ResolveArg1=(r,e,n,t,o)=>function(c){return r(e,c,n,t,o)},curry5ResolveArg2=(r,e,n,t,o)=>function(c){return r(e,n,c,t,o)},curry5ResolveArg3=(r,e,n,t,o)=>function(c){return r(e,n,t,c,o)},curry5ResolveArg4=(r,e,n,t,o)=>function(c){return r(e,n,t,o,c)},curry5=function(r,e,n,t,o,c){return e==__?curry5ResolveArg0(r,n,t,o,c):n==__?curry5ResolveArg1(r,e,t,o,c):t==__?curry5ResolveArg2(r,e,n,o,c):o==__?curry5ResolveArg3(r,e,n,t,c):curry5ResolveArg4(r,e,n,t,o)},objectKeys=Object.keys,objectReduceAsync=async function(r,e,n,t,o){const c=t.length;for(;++o<c;){const c=t[o];n=e(n,r[c],c,r),isPromise(n)&&(n=await n)}return n},objectReduce=function(r,e,n){const t=objectKeys(r),o=t.length;let c=-1;for(void 0===n&&(n=r[t[++c]]);++c<o;){const o=t[c];if(n=e(n,r[o],o,r),isPromise(n))return n.then((u=objectReduceAsync,s=e,y=__,a=t,f=c,(i=r)==__?curry5ResolveArg0(u,s,y,a,f):s==__?curry5ResolveArg1(u,i,y,a,f):y==__?curry5ResolveArg2(u,i,s,a,f):a==__?curry5ResolveArg3(u,i,s,y,f):curry5ResolveArg4(u,i,s,y,a)))}var u,i,s,y,a,f;return n},mapReduceAsync=async function(r,e,n,t){for(const[o,c]of t)n=e(n,c,o,r),isPromise(n)&&(n=await n);return n},mapReduce=function(r,e,n){const t=r.entries();if(void 0===n){const r=t.next();if(r.done)return n;n=r.value[1]}for(const[o,c]of t)if(n=e(n,c,o,r),isPromise(n))return n.then(curry4(mapReduceAsync,r,e,__,t));return n},reducerConcat=(r,e)=>function(n,t){const o=r(n,t);return isPromise(o)?o.then(curry2(e,__,t)):e(o,t)},genericReduce=function(r,e,n){return isArray(r)?arrayReduce(r,e,n):null==r?void 0===n?curry2(e,r,__):e(n,r):r.constructor==Map?mapReduce(r,e,n):"function"==typeof r[symbolIterator]?iteratorReduce(r[symbolIterator](),e,n):"function"==typeof r[symbolAsyncIterator]?asyncIteratorReduce(r[symbolAsyncIterator](),e,n):"function"==typeof r.reduce?r.reduce(e,n):"function"==typeof r.chain?r.chain(curry2(e,n,__)):"function"==typeof r.flatMap?r.flatMap(curry2(e,n,__)):r.constructor==Object?objectReduce(r,e,n):void 0===n?curry2(e,r,__):e(n,r)},reducerFlatMap=(r,e)=>function(n,t){const o=e(t);return isPromise(o)?o.then(curry3(genericReduce,__,r,n)):genericReduce(o,r,n)},reducerForEach=(r,e)=>function(n,t){const o=e(t);return isPromise(o)?o.then(thunkify2(r,n,t)):r(n,t)},Transducer={map:function(r){return curry2(reducerMap,__,r)},filter:function(r){return curry2(reducerFilter,__,r)},flatMap:function(r){return curry2(reducerFlatMap,__,r)},forEach:function(r){return curry2(reducerForEach,__,r)},passthrough:function(r){return r}};export default Transducer;
7
+ const isPromise=r=>null!=r&&"function"==typeof r.then,funcConcat=(r,e)=>function(...n){const t=r(...n);return isPromise(t)?t.then(e):e(t)},__=Symbol.for("placeholder"),curry2ResolveArg0=(r,e)=>function(n){return r(n,e)},curry2ResolveArg1=(r,e)=>function(n){return r(e,n)},curry2=function(r,e,n){return e==__?curry2ResolveArg0(r,n):curry2ResolveArg1(r,e)},reducerMap=(r,e)=>function(n,t){const c=e(t);return isPromise(c)?c.then(curry2(r,n,__)):r(n,c)},curry3ResolveArg0=(r,e,n)=>function(t){return r(t,e,n)},curry3ResolveArg1=(r,e,n)=>function(t){return r(e,t,n)},curry3ResolveArg2=(r,e,n)=>function(t){return r(e,n,t)},curry3=function(r,e,n,t){return e==__?curry3ResolveArg0(r,n,t):n==__?curry3ResolveArg1(r,e,t):curry3ResolveArg2(r,e,n)},thunkify2=(r,e,n)=>function(){return r(e,n)},thunkConditional=(r,e,n)=>r?e():n(),always=r=>function(){return r},reducerFilter=(r,e)=>function(n,t){const c=e(t);return isPromise(c)?c.then(curry3(thunkConditional,__,thunkify2(r,n,t),(o=n,function(){return o}))):c?r(n,t):n;var o},isArray=Array.isArray,objectValues=Object.values,objectProto=Object.prototype,nativeObjectToString=objectProto.toString,objectToString=r=>nativeObjectToString.call(r),generatorFunctionTag="[object GeneratorFunction]",isGeneratorFunction=r=>objectToString(r)==generatorFunctionTag,asyncGeneratorFunctionTag="[object AsyncGeneratorFunction]",isAsyncGeneratorFunction=r=>objectToString(r)==asyncGeneratorFunctionTag,iteratorReduceAsync=async function(r,e,n){let t=r.next();if(t.done)return n;for(;!t.done;)n=e(n,t.value),isPromise(n)&&(n=await n),t=r.next();return n},iteratorReduce=function(r,e,n){let t=r.next();if(t.done)return n;for(void 0===n&&(n=t.value,t=r.next());!t.done;){if(n=e(n,t.value),isPromise(n))return n.then(curry3(iteratorReduceAsync,r,e,__));t=r.next()}return n},asyncIteratorReduce=async function(r,e,n){let t=await r.next();if(t.done)return n;for(void 0===n&&(n=t.value,t=await r.next());!t.done;)n=await e(n,t.value),t=await r.next();return n},symbolIterator=Symbol.iterator,symbolAsyncIterator=Symbol.asyncIterator,curryArgs3ResolveArgs0=(r,e,n)=>function(...t){return r(t,e,n)},curryArgs3ResolveArgs1=(r,e,n)=>function(...t){return r(e,t,n)},curryArgs3ResolveArgs2=(r,e,n)=>function(...t){return r(e,n,t)},curryArgs3=function(r,e,n,t){return e==__?curryArgs3ResolveArgs0(r,n,t):n==__?curryArgs3ResolveArgs1(r,e,t):curryArgs3ResolveArgs2(r,e,n)},curry4ResolveArg0=(r,e,n,t)=>function(c){return r(c,e,n,t)},curry4ResolveArg1=(r,e,n,t)=>function(c){return r(e,c,n,t)},curry4ResolveArg2=(r,e,n,t)=>function(c){return r(e,n,c,t)},curry4ResolveArg3=(r,e,n,t)=>function(c){return r(e,n,t,c)},curry4=function(r,e,n,t,c){return e==__?curry4ResolveArg0(r,n,t,c):n==__?curry4ResolveArg1(r,e,t,c):t==__?curry4ResolveArg2(r,e,n,c):curry4ResolveArg3(r,e,n,t)},arrayReduceAsync=async function(r,e,n,t){const c=r.length;for(;++t<c;)n=e(n,r[t],t,r),isPromise(n)&&(n=await n);return n},arrayReduce=function(r,e,n){const t=r.length;let c=-1;for(void 0===n&&(n=r[++c]);++c<t;)if(n=e(n,r[c],c,r),isPromise(n))return n.then(curry4(arrayReduceAsync,r,e,__,c));return n},curry5ResolveArg0=(r,e,n,t,c)=>function(o){return r(o,e,n,t,c)},curry5ResolveArg1=(r,e,n,t,c)=>function(o){return r(e,o,n,t,c)},curry5ResolveArg2=(r,e,n,t,c)=>function(o){return r(e,n,o,t,c)},curry5ResolveArg3=(r,e,n,t,c)=>function(o){return r(e,n,t,o,c)},curry5ResolveArg4=(r,e,n,t,c)=>function(o){return r(e,n,t,c,o)},curry5=function(r,e,n,t,c,o){return e==__?curry5ResolveArg0(r,n,t,c,o):n==__?curry5ResolveArg1(r,e,t,c,o):t==__?curry5ResolveArg2(r,e,n,c,o):c==__?curry5ResolveArg3(r,e,n,t,o):curry5ResolveArg4(r,e,n,t,c)},objectKeys=Object.keys,objectReduceAsync=async function(r,e,n,t,c){const o=t.length;for(;++c<o;){const o=t[c];n=e(n,r[o],o,r),isPromise(n)&&(n=await n)}return n},objectReduce=function(r,e,n){const t=objectKeys(r),c=t.length;let o=-1;for(void 0===n&&(n=r[t[++o]]);++o<c;){const c=t[o];if(n=e(n,r[c],c,r),isPromise(n))return n.then(curry5(objectReduceAsync,r,e,__,t,o))}return n},mapReduceAsync=async function(r,e,n,t){for(const[c,o]of t)n=e(n,o,c,r),isPromise(n)&&(n=await n);return n},mapReduce=function(r,e,n){const t=r.entries();if(void 0===n){const r=t.next();if(r.done)return n;n=r.value[1]}for(const[c,o]of t)if(n=e(n,o,c,r),isPromise(n))return n.then(curry4(mapReduceAsync,r,e,__,t));return n},reducerConcat=(r,e)=>function(n,t){const c=r(n,t);return isPromise(c)?c.then(curry2(e,__,t)):e(c,t)},genericReduce=function(r,e,n){return isArray(r)?arrayReduce(r,e,n):null==r?void 0===n?curry2(e,r,__):e(n,r):r.constructor==Map?mapReduce(r,e,n):"function"==typeof r[symbolIterator]?iteratorReduce(r[symbolIterator](),e,n):"function"==typeof r[symbolAsyncIterator]?asyncIteratorReduce(r[symbolAsyncIterator](),e,n):"function"==typeof r.reduce?r.reduce(e,n):"function"==typeof r.chain?r.chain(curry2(e,n,__)):"function"==typeof r.flatMap?r.flatMap(curry2(e,n,__)):r.constructor==Object?objectReduce(r,e,n):void 0===n?curry2(e,r,__):e(n,r)},reducerFlatMap=(r,e)=>function(n,t){const c=e(t);return isPromise(c)?c.then(curry3(genericReduce,__,r,n)):genericReduce(c,r,n)},reducerForEach=(r,e)=>function(n,t){const c=e(t);return isPromise(c)?c.then(thunkify2(r,n,t)):r(n,t)},_reducerTryCatchErrorHandler=function(r,e,n,t,c){const o=r(n,c);return isPromise(o)?o.then(curry2(e,t,__)):e(t,o)},reducerTryCatch=function(r,e,n){const t=e(r);return function(e,c){try{const o=t(e,c);return isPromise(o)?o.catch(curry5(_reducerTryCatchErrorHandler,n,r,__,e,c)):o}catch(t){return _reducerTryCatchErrorHandler(n,r,t,e,c)}}},Transducer={map:function(r){return curry2(reducerMap,__,r)},filter:function(r){return curry2(reducerFilter,__,r)},flatMap:function(r){return curry2(reducerFlatMap,__,r)},forEach:function(r){return curry2(reducerForEach,__,r)},passthrough:function(r){return r},tryCatch:function(r,e){return curry3(reducerTryCatch,__,r,e)}};export default Transducer;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * rubico v2.0.1
2
+ * rubico v2.1.0
3
3
  * https://github.com/a-synchronous/rubico
4
4
  * (c) 2019-2023 Richard Tong
5
5
  * rubico may be freely distributed under the MIT license.
@@ -462,6 +462,29 @@ const reducerForEach = (
462
462
  return reducer(result, item)
463
463
  }
464
464
 
465
+ const _reducerTryCatchErrorHandler = function (
466
+ catcher, reducer, error, accum, item,
467
+ ) {
468
+ const c = catcher(error, item)
469
+ return isPromise(c) ? c.then(curry2(reducer, accum, __)) : reducer(accum, c)
470
+ }
471
+
472
+ const reducerTryCatch = function (reducer, transducerTryer, catcher) {
473
+ const finalReducer = transducerTryer(reducer)
474
+ return function errorHandlingReducer(accum, item) {
475
+ try {
476
+ const ret = finalReducer(accum, item)
477
+ return isPromise(ret) ? ret.catch(curry5(
478
+ _reducerTryCatchErrorHandler, catcher, reducer, __, accum, item,
479
+ )) : ret
480
+ } catch (error) {
481
+ return _reducerTryCatchErrorHandler(
482
+ catcher, reducer, error, accum, item,
483
+ )
484
+ }
485
+ }
486
+ }
487
+
465
488
  const Transducer = {}
466
489
 
467
490
  Transducer.map = function transducerMap(mapper) {
@@ -484,5 +507,9 @@ Transducer.passthrough = function transducerPassthrough(reducer) {
484
507
  return reducer
485
508
  }
486
509
 
510
+ Transducer.tryCatch = function transducerTryCatch(transducerTryer, catcher) {
511
+ return curry3(reducerTryCatch, __, transducerTryer, catcher)
512
+ }
513
+
487
514
  return Transducer
488
515
  }())))
@@ -1,8 +1,8 @@
1
1
  /**
2
- * rubico v2.0.1
2
+ * rubico v2.1.0
3
3
  * https://github.com/a-synchronous/rubico
4
4
  * (c) 2019-2023 Richard Tong
5
5
  * rubico may be freely distributed under the MIT license.
6
6
  */
7
7
 
8
- !function(n,t){"object"==typeof module?module.exports=t:"function"==typeof define?define((()=>t)):n.Transducer=t}("object"==typeof globalThis?globalThis:this,function(){"use strict";const n=n=>null!=n&&"function"==typeof n.then,t=Symbol.for("placeholder"),r=function(n,r,e){return r==t?((n,t)=>function(r){return n(r,t)})(n,e):((n,t)=>function(r){return n(t,r)})(n,r)},e=(e,o)=>function(u,c){const f=o(c);return n(f)?f.then(r(e,u,t)):e(u,f)},o=function(n,r,e,o){return r==t?((n,t,r)=>function(e){return n(e,t,r)})(n,e,o):e==t?((n,t,r)=>function(e){return n(t,e,r)})(n,r,o):((n,t,r)=>function(e){return n(t,r,e)})(n,r,e)},u=(n,t,r)=>function(){return n(t,r)},c=(n,t,r)=>n?t():r(),f=(r,e)=>function(f,i){const a=e(i);return n(a)?a.then(o(c,t,u(r,f,i),(s=f,function(){return s}))):a?r(f,i):f;var s},i=Array.isArray,a=(Object.values,Object.prototype.toString,async function(t,r,e){let o=t.next();if(o.done)return e;for(;!o.done;)e=r(e,o.value),n(e)&&(e=await e),o=t.next();return e}),s=Symbol.iterator,l=Symbol.asyncIterator,d=function(n,r,e,o,u){return r==t?((n,t,r,e)=>function(o){return n(o,t,r,e)})(n,e,o,u):e==t?((n,t,r,e)=>function(o){return n(t,o,r,e)})(n,r,o,u):o==t?((n,t,r,e)=>function(o){return n(t,r,o,e)})(n,r,e,u):((n,t,r,e)=>function(o){return n(t,r,e,o)})(n,r,e,o)},h=async function(t,r,e,o){const u=t.length;for(;++o<u;)e=r(e,t[o],o,t),n(e)&&(e=await e);return e},y=Object.keys,p=async function(t,r,e,o,u){const c=o.length;for(;++u<c;){const c=o[u];e=r(e,t[c],c,t),n(e)&&(e=await e)}return e},v=async function(t,r,e,o){for(const[u,c]of o)e=r(e,c,u,t),n(e)&&(e=await e);return e},b=function(e,u,c){return i(e)?function(r,e,o){const u=r.length;let c=-1;for(void 0===o&&(o=r[++c]);++c<u;)if(o=e(o,r[c],c,r),n(o))return o.then(d(h,r,e,t,c));return o}(e,u,c):null==e?void 0===c?r(u,e,t):u(c,e):e.constructor==Map?function(r,e,o){const u=r.entries();if(void 0===o){const n=u.next();if(n.done)return o;o=n.value[1]}for(const[c,f]of u)if(o=e(o,f,c,r),n(o))return o.then(d(v,r,e,t,u));return o}(e,u,c):"function"==typeof e[s]?function(r,e,u){let c=r.next();if(c.done)return u;for(void 0===u&&(u=c.value,c=r.next());!c.done;){if(u=e(u,c.value),n(u))return u.then(o(a,r,e,t));c=r.next()}return u}(e[s](),u,c):"function"==typeof e[l]?async function(n,t,r){let e=await n.next();if(e.done)return r;for(void 0===r&&(r=e.value,e=await n.next());!e.done;)r=await t(r,e.value),e=await n.next();return r}(e[l](),u,c):"function"==typeof e.reduce?e.reduce(u,c):"function"==typeof e.chain?e.chain(r(u,c,t)):"function"==typeof e.flatMap?e.flatMap(r(u,c,t)):e.constructor==Object?function(r,e,o){const u=y(r),c=u.length;let f=-1;for(void 0===o&&(o=r[u[++f]]);++f<c;){const c=u[f];if(o=e(o,r[c],c,r),n(o))return o.then((i=p,s=e,l=t,d=u,h=f,(a=r)==t?((n,t,r,e,o)=>function(u){return n(u,t,r,e,o)})(i,s,l,d,h):s==t?((n,t,r,e,o)=>function(u){return n(t,u,r,e,o)})(i,a,l,d,h):l==t?((n,t,r,e,o)=>function(u){return n(t,r,u,e,o)})(i,a,s,d,h):d==t?((n,t,r,e,o)=>function(u){return n(t,r,e,u,o)})(i,a,s,l,h):((n,t,r,e,o)=>function(u){return n(t,r,e,o,u)})(i,a,s,l,d)))}var i,a,s,l,d,h;return o}(e,u,c):void 0===c?r(u,e,t):u(c,e)},x=(r,e)=>function(u,c){const f=e(c);return n(f)?f.then(o(b,t,r,u)):b(f,r,u)},g=(t,r)=>function(e,o){const c=r(o);return n(c)?c.then(u(t,e,o)):t(e,o)},w={map:function(n){return r(e,t,n)},filter:function(n){return r(f,t,n)},flatMap:function(n){return r(x,t,n)},forEach:function(n){return r(g,t,n)},passthrough:function(n){return n}};return w}());
8
+ !function(n,t){"object"==typeof module?module.exports=t:"function"==typeof define?define((()=>t)):n.Transducer=t}("object"==typeof globalThis?globalThis:this,function(){"use strict";const n=n=>null!=n&&"function"==typeof n.then,t=Symbol.for("placeholder"),r=function(n,r,e){return r==t?((n,t)=>function(r){return n(r,t)})(n,e):((n,t)=>function(r){return n(t,r)})(n,r)},e=(e,o)=>function(u,c){const f=o(c);return n(f)?f.then(r(e,u,t)):e(u,f)},o=function(n,r,e,o){return r==t?((n,t,r)=>function(e){return n(e,t,r)})(n,e,o):e==t?((n,t,r)=>function(e){return n(t,e,r)})(n,r,o):((n,t,r)=>function(e){return n(t,r,e)})(n,r,e)},u=(n,t,r)=>function(){return n(t,r)},c=(n,t,r)=>n?t():r(),f=(r,e)=>function(f,i){const a=e(i);return n(a)?a.then(o(c,t,u(r,f,i),(s=f,function(){return s}))):a?r(f,i):f;var s},i=Array.isArray,a=(Object.values,Object.prototype.toString,async function(t,r,e){let o=t.next();if(o.done)return e;for(;!o.done;)e=r(e,o.value),n(e)&&(e=await e),o=t.next();return e}),s=Symbol.iterator,l=Symbol.asyncIterator,h=function(n,r,e,o,u){return r==t?((n,t,r,e)=>function(o){return n(o,t,r,e)})(n,e,o,u):e==t?((n,t,r,e)=>function(o){return n(t,o,r,e)})(n,r,o,u):o==t?((n,t,r,e)=>function(o){return n(t,r,o,e)})(n,r,e,u):((n,t,r,e)=>function(o){return n(t,r,e,o)})(n,r,e,o)},y=async function(t,r,e,o){const u=t.length;for(;++o<u;)e=r(e,t[o],o,t),n(e)&&(e=await e);return e},d=function(n,r,e,o,u,c){return r==t?((n,t,r,e,o)=>function(u){return n(u,t,r,e,o)})(n,e,o,u,c):e==t?((n,t,r,e,o)=>function(u){return n(t,u,r,e,o)})(n,r,o,u,c):o==t?((n,t,r,e,o)=>function(u){return n(t,r,u,e,o)})(n,r,e,u,c):u==t?((n,t,r,e,o)=>function(u){return n(t,r,e,u,o)})(n,r,e,o,c):((n,t,r,e,o)=>function(u){return n(t,r,e,o,u)})(n,r,e,o,u)},p=Object.keys,v=async function(t,r,e,o,u){const c=o.length;for(;++u<c;){const c=o[u];e=r(e,t[c],c,t),n(e)&&(e=await e)}return e},b=async function(t,r,e,o){for(const[u,c]of o)e=r(e,c,u,t),n(e)&&(e=await e);return e},x=function(e,u,c){return i(e)?function(r,e,o){const u=r.length;let c=-1;for(void 0===o&&(o=r[++c]);++c<u;)if(o=e(o,r[c],c,r),n(o))return o.then(h(y,r,e,t,c));return o}(e,u,c):null==e?void 0===c?r(u,e,t):u(c,e):e.constructor==Map?function(r,e,o){const u=r.entries();if(void 0===o){const n=u.next();if(n.done)return o;o=n.value[1]}for(const[c,f]of u)if(o=e(o,f,c,r),n(o))return o.then(h(b,r,e,t,u));return o}(e,u,c):"function"==typeof e[s]?function(r,e,u){let c=r.next();if(c.done)return u;for(void 0===u&&(u=c.value,c=r.next());!c.done;){if(u=e(u,c.value),n(u))return u.then(o(a,r,e,t));c=r.next()}return u}(e[s](),u,c):"function"==typeof e[l]?async function(n,t,r){let e=await n.next();if(e.done)return r;for(void 0===r&&(r=e.value,e=await n.next());!e.done;)r=await t(r,e.value),e=await n.next();return r}(e[l](),u,c):"function"==typeof e.reduce?e.reduce(u,c):"function"==typeof e.chain?e.chain(r(u,c,t)):"function"==typeof e.flatMap?e.flatMap(r(u,c,t)):e.constructor==Object?function(r,e,o){const u=p(r),c=u.length;let f=-1;for(void 0===o&&(o=r[u[++f]]);++f<c;){const c=u[f];if(o=e(o,r[c],c,r),n(o))return o.then(d(v,r,e,t,u,f))}return o}(e,u,c):void 0===c?r(u,e,t):u(c,e)},g=(r,e)=>function(u,c){const f=e(c);return n(f)?f.then(o(x,t,r,u)):x(f,r,u)},w=(t,r)=>function(e,o){const c=r(o);return n(c)?c.then(u(t,e,o)):t(e,o)},j=function(e,o,u,c,f){const i=e(u,f);return n(i)?i.then(r(o,c,t)):o(c,i)},m=function(r,e,o){const u=e(r);return function(e,c){try{const f=u(e,c);return n(f)?f.catch(d(j,o,r,t,e,c)):f}catch(n){return j(o,r,n,e,c)}}},M={map:function(n){return r(e,t,n)},filter:function(n){return r(f,t,n)},flatMap:function(n){return r(g,t,n)},forEach:function(n){return r(w,t,n)},passthrough:function(n){return n},tryCatch:function(n,r){return o(m,t,n,r)}};return M}());
@@ -1,5 +1,5 @@
1
1
  /**
2
- * rubico v2.0.1
2
+ * rubico v2.1.0
3
3
  * https://github.com/a-synchronous/rubico
4
4
  * (c) 2019-2023 Richard Tong
5
5
  * rubico may be freely distributed under the MIT license.
@@ -456,6 +456,29 @@ const reducerForEach = (
456
456
  return reducer(result, item)
457
457
  }
458
458
 
459
+ const _reducerTryCatchErrorHandler = function (
460
+ catcher, reducer, error, accum, item,
461
+ ) {
462
+ const c = catcher(error, item)
463
+ return isPromise(c) ? c.then(curry2(reducer, accum, __)) : reducer(accum, c)
464
+ }
465
+
466
+ const reducerTryCatch = function (reducer, transducerTryer, catcher) {
467
+ const finalReducer = transducerTryer(reducer)
468
+ return function errorHandlingReducer(accum, item) {
469
+ try {
470
+ const ret = finalReducer(accum, item)
471
+ return isPromise(ret) ? ret.catch(curry5(
472
+ _reducerTryCatchErrorHandler, catcher, reducer, __, accum, item,
473
+ )) : ret
474
+ } catch (error) {
475
+ return _reducerTryCatchErrorHandler(
476
+ catcher, reducer, error, accum, item,
477
+ )
478
+ }
479
+ }
480
+ }
481
+
459
482
  const Transducer = {}
460
483
 
461
484
  Transducer.map = function transducerMap(mapper) {
@@ -478,4 +501,8 @@ Transducer.passthrough = function transducerPassthrough(reducer) {
478
501
  return reducer
479
502
  }
480
503
 
504
+ Transducer.tryCatch = function transducerTryCatch(transducerTryer, catcher) {
505
+ return curry3(reducerTryCatch, __, transducerTryer, catcher)
506
+ }
507
+
481
508
  export default Transducer
package/dist/__.es.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * rubico v2.0.1
2
+ * rubico v2.1.0
3
3
  * https://github.com/a-synchronous/rubico
4
4
  * (c) 2019-2023 Richard Tong
5
5
  * rubico may be freely distributed under the MIT license.
package/dist/__.es.min.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * rubico v2.0.1
2
+ * rubico v2.1.0
3
3
  * https://github.com/a-synchronous/rubico
4
4
  * (c) 2019-2023 Richard Tong
5
5
  * rubico may be freely distributed under the MIT license.
package/dist/__.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * rubico v2.0.1
2
+ * rubico v2.1.0
3
3
  * https://github.com/a-synchronous/rubico
4
4
  * (c) 2019-2023 Richard Tong
5
5
  * rubico may be freely distributed under the MIT license.