rubico 2.8.5 → 2.10.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 (382) hide show
  1. package/README.md +2 -1
  2. package/_internal/FlatMappingAsyncIterator.js +41 -30
  3. package/_internal/LinkedList.js +54 -0
  4. package/_internal/LinkedList.test.js +34 -0
  5. package/_internal/MappingAsyncIterator.js +65 -15
  6. package/_internal/SerialMappingAsyncIterator.js +79 -0
  7. package/_internal/curryArity.js +3 -3
  8. package/_internal/iteratorFind.js +0 -2
  9. package/_internal/iteratorForEachSeries.js +1 -1
  10. package/_internal/objectFlatten.js +4 -1
  11. package/all.js +33 -59
  12. package/and.js +1 -1
  13. package/assign.js +14 -16
  14. package/compose.js +12 -13
  15. package/curry.js +1 -1
  16. package/dist/Transducer.es.js +1 -1
  17. package/dist/Transducer.es.min.js +1 -1
  18. package/dist/Transducer.js +1 -1
  19. package/dist/Transducer.min.js +1 -1
  20. package/dist/Transducer.mjs +1 -1
  21. package/dist/__.es.js +1 -1
  22. package/dist/__.es.min.js +1 -1
  23. package/dist/__.js +1 -1
  24. package/dist/__.min.js +1 -1
  25. package/dist/__.mjs +1 -1
  26. package/dist/all.es.js +1 -1
  27. package/dist/all.es.min.js +1 -1
  28. package/dist/all.js +1 -1
  29. package/dist/all.min.js +1 -1
  30. package/dist/all.mjs +1 -1
  31. package/dist/always.es.js +1 -1
  32. package/dist/always.es.min.js +1 -1
  33. package/dist/always.js +1 -1
  34. package/dist/always.min.js +1 -1
  35. package/dist/always.mjs +1 -1
  36. package/dist/and.es.js +1 -1
  37. package/dist/and.es.min.js +1 -1
  38. package/dist/and.js +1 -1
  39. package/dist/and.min.js +1 -1
  40. package/dist/and.mjs +1 -1
  41. package/dist/assign.es.js +1 -1
  42. package/dist/assign.es.min.js +1 -1
  43. package/dist/assign.js +1 -1
  44. package/dist/assign.min.js +1 -1
  45. package/dist/assign.mjs +1 -1
  46. package/dist/compose.es.js +1 -1
  47. package/dist/compose.es.min.js +1 -1
  48. package/dist/compose.js +1 -1
  49. package/dist/compose.min.js +1 -1
  50. package/dist/compose.mjs +1 -1
  51. package/dist/curry.es.js +4 -4
  52. package/dist/curry.es.min.js +2 -2
  53. package/dist/curry.js +4 -4
  54. package/dist/curry.min.js +2 -2
  55. package/dist/curry.mjs +4 -4
  56. package/dist/eq.es.js +1 -1
  57. package/dist/eq.es.min.js +1 -1
  58. package/dist/eq.js +1 -1
  59. package/dist/eq.min.js +1 -1
  60. package/dist/eq.mjs +1 -1
  61. package/dist/every.es.js +1 -1
  62. package/dist/every.es.min.js +1 -1
  63. package/dist/every.js +1 -1
  64. package/dist/every.min.js +1 -1
  65. package/dist/every.mjs +1 -1
  66. package/dist/filter.es.js +4 -4
  67. package/dist/filter.es.min.js +2 -2
  68. package/dist/filter.js +4 -4
  69. package/dist/filter.min.js +2 -2
  70. package/dist/filter.mjs +4 -4
  71. package/dist/flatMap.es.js +44 -28
  72. package/dist/flatMap.es.min.js +2 -2
  73. package/dist/flatMap.js +44 -28
  74. package/dist/flatMap.min.js +2 -2
  75. package/dist/flatMap.mjs +44 -28
  76. package/dist/forEach.es.js +6 -6
  77. package/dist/forEach.es.min.js +2 -2
  78. package/dist/forEach.js +6 -6
  79. package/dist/forEach.min.js +2 -2
  80. package/dist/forEach.mjs +6 -6
  81. package/dist/get.es.js +27 -3
  82. package/dist/get.es.min.js +2 -2
  83. package/dist/get.js +27 -3
  84. package/dist/get.min.js +2 -2
  85. package/dist/get.mjs +27 -3
  86. package/dist/gt.es.js +1 -1
  87. package/dist/gt.es.min.js +1 -1
  88. package/dist/gt.js +1 -1
  89. package/dist/gt.min.js +1 -1
  90. package/dist/gt.mjs +1 -1
  91. package/dist/gte.es.js +1 -1
  92. package/dist/gte.es.min.js +1 -1
  93. package/dist/gte.js +1 -1
  94. package/dist/gte.min.js +1 -1
  95. package/dist/gte.mjs +1 -1
  96. package/dist/lt.es.js +1 -1
  97. package/dist/lt.es.min.js +1 -1
  98. package/dist/lt.js +1 -1
  99. package/dist/lt.min.js +1 -1
  100. package/dist/lt.mjs +1 -1
  101. package/dist/lte.es.js +1 -1
  102. package/dist/lte.es.min.js +1 -1
  103. package/dist/lte.js +1 -1
  104. package/dist/lte.min.js +1 -1
  105. package/dist/lte.mjs +1 -1
  106. package/dist/map.es.js +190 -42
  107. package/dist/map.es.min.js +2 -2
  108. package/dist/map.js +190 -42
  109. package/dist/map.min.js +2 -2
  110. package/dist/map.mjs +190 -42
  111. package/dist/not.es.js +1 -1
  112. package/dist/not.es.min.js +1 -1
  113. package/dist/not.js +1 -1
  114. package/dist/not.min.js +1 -1
  115. package/dist/not.mjs +1 -1
  116. package/dist/omit.es.js +1 -1
  117. package/dist/omit.es.min.js +1 -1
  118. package/dist/omit.js +1 -1
  119. package/dist/omit.min.js +1 -1
  120. package/dist/omit.mjs +1 -1
  121. package/dist/or.es.js +1 -1
  122. package/dist/or.es.min.js +1 -1
  123. package/dist/or.js +1 -1
  124. package/dist/or.min.js +1 -1
  125. package/dist/or.mjs +1 -1
  126. package/dist/pick.es.js +1 -1
  127. package/dist/pick.es.min.js +1 -1
  128. package/dist/pick.js +1 -1
  129. package/dist/pick.min.js +1 -1
  130. package/dist/pick.mjs +1 -1
  131. package/dist/pipe.es.js +1 -1
  132. package/dist/pipe.es.min.js +1 -1
  133. package/dist/pipe.js +1 -1
  134. package/dist/pipe.min.js +1 -1
  135. package/dist/pipe.mjs +1 -1
  136. package/dist/reduce.es.js +1 -1
  137. package/dist/reduce.es.min.js +1 -1
  138. package/dist/reduce.js +1 -1
  139. package/dist/reduce.min.js +1 -1
  140. package/dist/reduce.mjs +1 -1
  141. package/dist/rubico.es.js +238 -83
  142. package/dist/rubico.es.min.js +2 -2
  143. package/dist/rubico.global.js +238 -83
  144. package/dist/rubico.global.min.js +2 -2
  145. package/dist/rubico.js +238 -83
  146. package/dist/rubico.min.js +2 -2
  147. package/dist/rubico.mjs +238 -83
  148. package/dist/set.es.js +1 -1
  149. package/dist/set.es.min.js +1 -1
  150. package/dist/set.js +1 -1
  151. package/dist/set.min.js +1 -1
  152. package/dist/set.mjs +1 -1
  153. package/dist/some.es.js +1 -1
  154. package/dist/some.es.min.js +1 -1
  155. package/dist/some.js +1 -1
  156. package/dist/some.min.js +1 -1
  157. package/dist/some.mjs +1 -1
  158. package/dist/switchCase.es.js +1 -1
  159. package/dist/switchCase.es.min.js +1 -1
  160. package/dist/switchCase.js +1 -1
  161. package/dist/switchCase.min.js +1 -1
  162. package/dist/switchCase.mjs +1 -1
  163. package/dist/tap.es.js +1 -1
  164. package/dist/tap.es.min.js +1 -1
  165. package/dist/tap.js +1 -1
  166. package/dist/tap.min.js +1 -1
  167. package/dist/tap.mjs +1 -1
  168. package/dist/thunkify.es.js +1 -1
  169. package/dist/thunkify.es.min.js +1 -1
  170. package/dist/thunkify.js +1 -1
  171. package/dist/thunkify.min.js +1 -1
  172. package/dist/thunkify.mjs +1 -1
  173. package/dist/transform.es.js +1 -1
  174. package/dist/transform.es.min.js +1 -1
  175. package/dist/transform.js +1 -1
  176. package/dist/transform.min.js +1 -1
  177. package/dist/transform.mjs +1 -1
  178. package/dist/tryCatch.es.js +1 -1
  179. package/dist/tryCatch.es.min.js +1 -1
  180. package/dist/tryCatch.js +1 -1
  181. package/dist/tryCatch.min.js +1 -1
  182. package/dist/tryCatch.mjs +1 -1
  183. package/dist/x/append.es.js +1 -1
  184. package/dist/x/append.es.min.js +1 -1
  185. package/dist/x/append.js +1 -1
  186. package/dist/x/append.min.js +1 -1
  187. package/dist/x/append.mjs +1 -1
  188. package/dist/x/callProp.es.js +1 -1
  189. package/dist/x/callProp.es.min.js +1 -1
  190. package/dist/x/callProp.js +1 -1
  191. package/dist/x/callProp.min.js +1 -1
  192. package/dist/x/callProp.mjs +1 -1
  193. package/dist/x/defaultsDeep.es.js +1 -1
  194. package/dist/x/defaultsDeep.es.min.js +1 -1
  195. package/dist/x/defaultsDeep.js +1 -1
  196. package/dist/x/defaultsDeep.min.js +1 -1
  197. package/dist/x/defaultsDeep.mjs +1 -1
  198. package/dist/x/differenceWith.es.js +1 -1
  199. package/dist/x/differenceWith.es.min.js +1 -1
  200. package/dist/x/differenceWith.js +1 -1
  201. package/dist/x/differenceWith.min.js +1 -1
  202. package/dist/x/differenceWith.mjs +1 -1
  203. package/dist/x/filterOut.es.js +4 -4
  204. package/dist/x/filterOut.es.min.js +2 -2
  205. package/dist/x/filterOut.js +4 -4
  206. package/dist/x/filterOut.min.js +2 -2
  207. package/dist/x/filterOut.mjs +4 -4
  208. package/dist/x/find.es.js +1 -3
  209. package/dist/x/find.es.min.js +1 -1
  210. package/dist/x/find.js +1 -3
  211. package/dist/x/find.min.js +1 -1
  212. package/dist/x/find.mjs +1 -3
  213. package/dist/x/findIndex.es.js +1 -1
  214. package/dist/x/findIndex.es.min.js +1 -1
  215. package/dist/x/findIndex.js +1 -1
  216. package/dist/x/findIndex.min.js +1 -1
  217. package/dist/x/findIndex.mjs +1 -1
  218. package/dist/x/first.es.js +1 -1
  219. package/dist/x/first.es.min.js +1 -1
  220. package/dist/x/first.js +1 -1
  221. package/dist/x/first.min.js +1 -1
  222. package/dist/x/first.mjs +1 -1
  223. package/dist/x/flatten.es.js +44 -28
  224. package/dist/x/flatten.es.min.js +2 -2
  225. package/dist/x/flatten.js +44 -28
  226. package/dist/x/flatten.min.js +2 -2
  227. package/dist/x/flatten.mjs +44 -28
  228. package/dist/x/groupBy.es.js +1 -1
  229. package/dist/x/groupBy.es.min.js +1 -1
  230. package/dist/x/groupBy.js +1 -1
  231. package/dist/x/groupBy.min.js +1 -1
  232. package/dist/x/groupBy.mjs +1 -1
  233. package/dist/x/has.es.js +1 -1
  234. package/dist/x/has.es.min.js +1 -1
  235. package/dist/x/has.js +1 -1
  236. package/dist/x/has.min.js +1 -1
  237. package/dist/x/has.mjs +1 -1
  238. package/dist/x/identity.es.js +1 -1
  239. package/dist/x/identity.es.min.js +1 -1
  240. package/dist/x/identity.js +1 -1
  241. package/dist/x/identity.min.js +1 -1
  242. package/dist/x/identity.mjs +1 -1
  243. package/dist/x/includes.es.js +1 -1
  244. package/dist/x/includes.es.min.js +1 -1
  245. package/dist/x/includes.js +1 -1
  246. package/dist/x/includes.min.js +1 -1
  247. package/dist/x/includes.mjs +1 -1
  248. package/dist/x/isDeepEqual.es.js +1 -1
  249. package/dist/x/isDeepEqual.es.min.js +1 -1
  250. package/dist/x/isDeepEqual.js +1 -1
  251. package/dist/x/isDeepEqual.min.js +1 -1
  252. package/dist/x/isDeepEqual.mjs +1 -1
  253. package/dist/x/isEmpty.es.js +1 -1
  254. package/dist/x/isEmpty.es.min.js +1 -1
  255. package/dist/x/isEmpty.js +1 -1
  256. package/dist/x/isEmpty.min.js +1 -1
  257. package/dist/x/isEmpty.mjs +1 -1
  258. package/dist/x/isEqual.es.js +1 -1
  259. package/dist/x/isEqual.es.min.js +1 -1
  260. package/dist/x/isEqual.js +1 -1
  261. package/dist/x/isEqual.min.js +1 -1
  262. package/dist/x/isEqual.mjs +1 -1
  263. package/dist/x/isFunction.es.js +1 -1
  264. package/dist/x/isFunction.es.min.js +1 -1
  265. package/dist/x/isFunction.js +1 -1
  266. package/dist/x/isFunction.min.js +1 -1
  267. package/dist/x/isFunction.mjs +1 -1
  268. package/dist/x/isIn.es.js +1 -1
  269. package/dist/x/isIn.es.min.js +1 -1
  270. package/dist/x/isIn.js +1 -1
  271. package/dist/x/isIn.min.js +1 -1
  272. package/dist/x/isIn.mjs +1 -1
  273. package/dist/x/isObject.es.js +1 -1
  274. package/dist/x/isObject.es.min.js +1 -1
  275. package/dist/x/isObject.js +1 -1
  276. package/dist/x/isObject.min.js +1 -1
  277. package/dist/x/isObject.mjs +1 -1
  278. package/dist/x/isString.es.js +1 -1
  279. package/dist/x/isString.es.min.js +1 -1
  280. package/dist/x/isString.js +1 -1
  281. package/dist/x/isString.min.js +1 -1
  282. package/dist/x/isString.mjs +1 -1
  283. package/dist/x/keys.es.js +1 -1
  284. package/dist/x/keys.es.min.js +1 -1
  285. package/dist/x/keys.js +1 -1
  286. package/dist/x/keys.min.js +1 -1
  287. package/dist/x/keys.mjs +1 -1
  288. package/dist/x/last.es.js +1 -1
  289. package/dist/x/last.es.min.js +1 -1
  290. package/dist/x/last.js +1 -1
  291. package/dist/x/last.min.js +1 -1
  292. package/dist/x/last.mjs +1 -1
  293. package/dist/x/maxBy.es.js +27 -23
  294. package/dist/x/maxBy.es.min.js +2 -2
  295. package/dist/x/maxBy.js +27 -23
  296. package/dist/x/maxBy.min.js +2 -2
  297. package/dist/x/maxBy.mjs +27 -23
  298. package/dist/x/noop.es.js +1 -1
  299. package/dist/x/noop.es.min.js +1 -1
  300. package/dist/x/noop.js +1 -1
  301. package/dist/x/noop.min.js +1 -1
  302. package/dist/x/noop.mjs +1 -1
  303. package/dist/x/pluck.es.js +194 -44
  304. package/dist/x/pluck.es.min.js +2 -2
  305. package/dist/x/pluck.js +194 -44
  306. package/dist/x/pluck.min.js +2 -2
  307. package/dist/x/pluck.mjs +194 -44
  308. package/dist/x/prepend.es.js +1 -1
  309. package/dist/x/prepend.es.min.js +1 -1
  310. package/dist/x/prepend.js +1 -1
  311. package/dist/x/prepend.min.js +1 -1
  312. package/dist/x/prepend.mjs +1 -1
  313. package/dist/x/size.es.js +1 -1
  314. package/dist/x/size.es.min.js +1 -1
  315. package/dist/x/size.js +1 -1
  316. package/dist/x/size.min.js +1 -1
  317. package/dist/x/size.mjs +1 -1
  318. package/dist/x/trace.es.js +1 -1
  319. package/dist/x/trace.es.min.js +1 -1
  320. package/dist/x/trace.js +1 -1
  321. package/dist/x/trace.min.js +1 -1
  322. package/dist/x/trace.mjs +1 -1
  323. package/dist/x/unionWith.es.js +1 -1
  324. package/dist/x/unionWith.es.min.js +1 -1
  325. package/dist/x/unionWith.js +1 -1
  326. package/dist/x/unionWith.min.js +1 -1
  327. package/dist/x/unionWith.mjs +1 -1
  328. package/dist/x/uniq.es.js +1 -1
  329. package/dist/x/uniq.es.min.js +1 -1
  330. package/dist/x/uniq.js +1 -1
  331. package/dist/x/uniq.min.js +1 -1
  332. package/dist/x/uniq.mjs +1 -1
  333. package/dist/x/unless.es.js +1 -1
  334. package/dist/x/unless.es.min.js +1 -1
  335. package/dist/x/unless.js +1 -1
  336. package/dist/x/unless.min.js +1 -1
  337. package/dist/x/unless.mjs +1 -1
  338. package/dist/x/values.es.js +1 -1
  339. package/dist/x/values.es.min.js +1 -1
  340. package/dist/x/values.js +1 -1
  341. package/dist/x/values.min.js +1 -1
  342. package/dist/x/values.mjs +1 -1
  343. package/dist/x/when.es.js +1 -1
  344. package/dist/x/when.es.min.js +1 -1
  345. package/dist/x/when.js +1 -1
  346. package/dist/x/when.min.js +1 -1
  347. package/dist/x/when.mjs +1 -1
  348. package/eq.js +2 -2
  349. package/es.js +238 -83
  350. package/every.js +2 -2
  351. package/filter.js +4 -4
  352. package/flatMap.js +61 -54
  353. package/forEach.js +33 -56
  354. package/get.js +49 -25
  355. package/gt.js +2 -2
  356. package/gte.js +2 -2
  357. package/index.js +238 -83
  358. package/lt.js +2 -2
  359. package/lte.js +2 -2
  360. package/map.js +115 -151
  361. package/monad/Mux.js +6 -4
  362. package/monad/PossiblePromise.js +6 -4
  363. package/monad/README.md +61 -40
  364. package/monad/Struct.js +6 -4
  365. package/not.js +1 -1
  366. package/omit.js +22 -19
  367. package/or.js +1 -1
  368. package/package.json +1 -1
  369. package/pick.js +14 -11
  370. package/pipe.js +18 -24
  371. package/reduce.js +1 -1
  372. package/set.js +17 -18
  373. package/some.js +2 -2
  374. package/switchCase.js +51 -43
  375. package/tap.js +17 -23
  376. package/transform.js +1 -1
  377. package/tryCatch.js +16 -24
  378. package/x/defaultsDeep.js +1 -1
  379. package/x/defaultsDeep.test.js +1 -1
  380. package/_internal/NextIteration.js +0 -12
  381. package/_internal/generatorFunctionFilter.js +0 -28
  382. package/_internal/iterationMap.js +0 -27
package/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
  ![rubico](https://raw.githubusercontent.com/a-synchronous/assets/master/rubico-logo.png)
3
3
  > a shallow river in northeastern Italy, just south of Ravenna
4
4
 
5
+ Source code: [GitHub](https://github.com/a-synchronous/rubico) |
5
6
  License: [CFOSS](https://cloutsworld.com/en-us/legal/license/cfoss)
6
7
 
7
8
  ![Node.js CI](https://github.com/a-synchronous/rubico/workflows/Node.js%20CI/badge.svg)
@@ -136,7 +137,7 @@ pipe(helloPromise, [ // helloPromise is resolved for 'hello'
136
137
  ])
137
138
  ```
138
139
 
139
- All Rubico operators support both eager and lazy APIs. The eager API takes all required arguments and executes at once, while the lazy API takes only the setup arguments and returns a function that only expects the data arguments. This dual API supports a natural and composable code style.
140
+ All Rubico operators support both eager and lazy interfaces. The eager interface takes all required arguments and executes at once, while the lazy interface takes only the setup arguments and returns a function that only expects the data arguments. This dual interface supports a natural and composable code style.
140
141
 
141
142
  ```javascript [playground]
142
143
  const myObj = { a: 1, b: 2, c: 3 }
@@ -22,8 +22,11 @@ const sleep = require('./sleep')
22
22
  * @muxing
23
23
  */
24
24
  const FlatMappingAsyncIterator = function (asyncIterator, flatMapper) {
25
- const buffer = [],
26
- promises = new Set()
25
+ const buffer = []
26
+ const promises = new Set()
27
+
28
+ let consumingAsyncIterator = false
29
+ let isAsyncIteratorDone = false
27
30
 
28
31
  return {
29
32
  isAsyncIteratorDone: false,
@@ -34,47 +37,55 @@ const FlatMappingAsyncIterator = function (asyncIterator, flatMapper) {
34
37
  return '[object FlatMappingAsyncIterator]'
35
38
  },
36
39
 
40
+ // _consumeAsyncIterator() -> Promise<>
41
+ async _consumeAsyncIterator() {
42
+ for await (const item of asyncIterator) {
43
+ const monad = flatMapper(item)
44
+ if (isPromise(monad)) {
45
+ const bufferLoading =
46
+ monad.then(curry3(genericReduce, __, arrayPush, buffer))
47
+ const promise = bufferLoading.then(() => promises.delete(promise))
48
+ promises.add(promise)
49
+ } else {
50
+ const bufferLoading = genericReduce(monad, arrayPush, buffer)
51
+ if (isPromise(bufferLoading)) {
52
+ const promise = bufferLoading.then(() => promises.delete(promise))
53
+ promises.add(promise)
54
+ }
55
+ }
56
+ }
57
+ isAsyncIteratorDone = true
58
+ },
59
+
37
60
  /**
38
- * @name FlatMappingAsyncIterator.prototype.next
61
+ * @name next
39
62
  *
40
63
  * @synopsis
41
64
  * ```coffeescript [specscript]
42
- * new FlatMappingAsyncIterator(
43
- * asyncIterator AsyncIterator, flatMapper function,
44
- * ).next() -> Promise<{ value, done }>
65
+ * next() -> Promise<{ value, done }>
45
66
  * ```
46
67
  */
47
68
  async next() {
48
- while (
49
- !this.isAsyncIteratorDone || buffer.length > 0 || promises.size > 0
50
- ) {
51
- if (!this.isAsyncIteratorDone) {
52
- const { value, done } = await asyncIterator.next()
53
- if (done) {
54
- this.isAsyncIteratorDone = done
55
- } else {
56
- const monad = flatMapper(value)
57
- if (isPromise(monad)) {
58
- const bufferLoading =
59
- monad.then(curry3(genericReduce, __, arrayPush, buffer))
60
- const promise = bufferLoading.then(() => promises.delete(promise))
61
- promises.add(promise)
62
- } else {
63
- const bufferLoading = genericReduce(monad, arrayPush, buffer)
64
- if (isPromise(bufferLoading)) {
65
- const promise = bufferLoading.then(() => promises.delete(promise))
66
- promises.add(promise)
67
- }
68
- }
69
- }
70
- }
69
+ if (!consumingAsyncIterator) {
70
+ this._consumeAsyncIterator()
71
+ consumingAsyncIterator = true
72
+ }
73
+
74
+ while (!isAsyncIteratorDone || promises.size > 0) {
71
75
  if (buffer.length > 0) {
72
76
  return { value: buffer.shift(), done: false }
73
77
  }
74
78
  if (promises.size > 0) {
75
- await promiseRace([sleep(1000), ...promises])
79
+ await promiseRace(promises)
80
+ } else {
81
+ await sleep(10)
76
82
  }
77
83
  }
84
+
85
+ if (buffer.length > 0) {
86
+ return { value: buffer.shift(), done: false }
87
+ }
88
+
78
89
  return { value: undefined, done: true }
79
90
  },
80
91
  }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @name LinkedList
3
+ *
4
+ * @docs
5
+ * ```coffeescript [specscript]
6
+ * new LinkedList() -> LinkedList
7
+ * ```
8
+ */
9
+ class LinkedList {
10
+ constructor() {
11
+ this.first = null
12
+ this.last = null
13
+ this.length = 0
14
+ }
15
+
16
+ // popFirst() -> firstValue any
17
+ popFirst() {
18
+ const first = this.first
19
+
20
+ if (first == null) {
21
+ return undefined
22
+ }
23
+
24
+ if (first.next) {
25
+ this.first = first.next
26
+ } else {
27
+ this.first = null
28
+ }
29
+
30
+ this.length -= 1
31
+
32
+ return first.value
33
+ }
34
+
35
+ // append(value any) -> undefined
36
+ append(value) {
37
+ const node = { value }
38
+ if (this.first == null) {
39
+ this.first = node
40
+ }
41
+
42
+ if (this.last == null) {
43
+ this.last = node
44
+ } else {
45
+ this.last.next = node
46
+ this.last = node
47
+ }
48
+
49
+ this.length += 1
50
+ }
51
+
52
+ }
53
+
54
+ module.exports = LinkedList
@@ -0,0 +1,34 @@
1
+ const LinkedList = require('./LinkedList')
2
+ const assert = require('assert')
3
+
4
+ describe('LinkedList', () => {
5
+ it('integration', async () => {
6
+ const ll = new LinkedList()
7
+
8
+ assert.strictEqual(ll.popFirst(), undefined)
9
+
10
+ ll.append('value1')
11
+ assert.strictEqual(ll.length, 1)
12
+
13
+ assert.strictEqual(ll.popFirst(), 'value1')
14
+ assert.strictEqual(ll.length, 0)
15
+ assert.strictEqual(ll.popFirst(), undefined)
16
+ assert.strictEqual(ll.length, 0)
17
+
18
+ ll.append('value1')
19
+ assert.strictEqual(ll.length, 1)
20
+ ll.append('value2')
21
+ assert.strictEqual(ll.length, 2)
22
+ ll.append('value3')
23
+ assert.strictEqual(ll.length, 3)
24
+
25
+ assert.strictEqual(ll.popFirst(), 'value1')
26
+ assert.strictEqual(ll.length, 2)
27
+ assert.strictEqual(ll.popFirst(), 'value2')
28
+ assert.strictEqual(ll.length, 1)
29
+ assert.strictEqual(ll.popFirst(), 'value3')
30
+ assert.strictEqual(ll.length, 0)
31
+ assert.strictEqual(ll.popFirst(), undefined)
32
+ assert.strictEqual(ll.length, 0)
33
+ })
34
+ })
@@ -1,6 +1,11 @@
1
- const NextIteration = require('./NextIteration')
1
+ const promiseRace = require('./promiseRace')
2
+ const __ = require('./placeholder')
3
+ const curry2 = require('./curry2')
2
4
  const isPromise = require('./isPromise')
5
+ const LinkedList = require('./LinkedList')
3
6
  const symbolAsyncIterator = require('./symbolAsyncIterator')
7
+ const arrayPush = require('./arrayPush')
8
+ const sleep = require('./sleep')
4
9
 
5
10
  /**
6
11
  * @name MappingAsyncIterator
@@ -15,20 +20,65 @@ const symbolAsyncIterator = require('./symbolAsyncIterator')
15
20
  * mappingAsyncIterator.next() -> Promise<{ value: any, done: boolean }>
16
21
  * ```
17
22
  */
18
- const MappingAsyncIterator = (asyncIterator, mapper) => ({
19
- [symbolAsyncIterator]() {
20
- return this
21
- },
22
- async next() {
23
- const iteration = await asyncIterator.next()
24
- if (iteration.done) {
25
- return iteration
26
- }
27
- const mapped = mapper(iteration.value)
28
- return isPromise(mapped)
29
- ? mapped.then(NextIteration)
30
- : { value: mapped, done: false }
23
+ const MappingAsyncIterator = (asyncIterator, mapper) => {
24
+ const buffer = new LinkedList()
25
+
26
+ let index = -1
27
+ let consumingAsyncIterator = false
28
+ let isAsyncIteratorDone = false
29
+
30
+ return {
31
+ [symbolAsyncIterator]() {
32
+ return this
33
+ },
34
+
35
+ // _consumeAsyncIterator() -> Promise<>
36
+ async _consumeAsyncIterator() {
37
+ for await (const item of asyncIterator) {
38
+ index += 1
39
+ const mappedItem = mapper(item)
40
+ buffer.append(mappedItem)
41
+ }
42
+ isAsyncIteratorDone = true
43
+ },
44
+
45
+ /**
46
+ * @name next
47
+ *
48
+ * @synopsis
49
+ * ```coffeescript [specscript]
50
+ * next() -> Promise<{ value, done }>
51
+ * ```
52
+ */
53
+ async next() {
54
+ if (!consumingAsyncIterator) {
55
+ this._consumeAsyncIterator()
56
+ consumingAsyncIterator = true
57
+ }
58
+
59
+ while (!isAsyncIteratorDone) {
60
+ if (buffer.length > 0) {
61
+ let value = buffer.popFirst()
62
+ if (isPromise(value)) {
63
+ value = await value
64
+ }
65
+ return { value, done: false }
66
+ }
67
+ await sleep(10)
68
+ }
69
+
70
+ if (buffer.length > 0) {
71
+ let value = buffer.popFirst()
72
+ if (isPromise(value)) {
73
+ value = await value
74
+ }
75
+ return { value, done: false }
76
+ }
77
+
78
+ return { value: undefined, done: true }
79
+ },
80
+
31
81
  }
32
- })
82
+ }
33
83
 
34
84
  module.exports = MappingAsyncIterator
@@ -0,0 +1,79 @@
1
+ const promiseRace = require('./promiseRace')
2
+ const __ = require('./placeholder')
3
+ const curry2 = require('./curry2')
4
+ const isPromise = require('./isPromise')
5
+ const LinkedList = require('./LinkedList')
6
+ const symbolAsyncIterator = require('./symbolAsyncIterator')
7
+ const arrayPush = require('./arrayPush')
8
+ const sleep = require('./sleep')
9
+
10
+ /**
11
+ * @name SerialMappingAsyncIterator
12
+ *
13
+ * @synopsis
14
+ * ```coffeescript [specscript]
15
+ * serialMappingAsyncIterator = new SerialMappingAsyncIterator(
16
+ * asyncIter AsyncIterator<T>,
17
+ * mapper T=>Promise|any,
18
+ * ) -> serialMappingAsyncIterator AsyncIterator
19
+ *
20
+ * serialMappingAsyncIterator.next() -> Promise<{ value: any, done: boolean }>
21
+ * ```
22
+ */
23
+ const SerialMappingAsyncIterator = (asyncIterator, mapper) => {
24
+ const buffer = new LinkedList()
25
+
26
+ let index = -1
27
+ let consumingAsyncIterator = false
28
+ let isAsyncIteratorDone = false
29
+
30
+ return {
31
+ [symbolAsyncIterator]() {
32
+ return this
33
+ },
34
+
35
+ // _consumeAsyncIterator() -> Promise<>
36
+ async _consumeAsyncIterator() {
37
+ for await (const item of asyncIterator) {
38
+ index += 1
39
+ let mappedItem = mapper(item)
40
+ if (isPromise(mappedItem)) {
41
+ mappedItem = await mappedItem
42
+ }
43
+ buffer.append(mappedItem)
44
+ }
45
+ isAsyncIteratorDone = true
46
+ },
47
+
48
+ /**
49
+ * @name next
50
+ *
51
+ * @synopsis
52
+ * ```coffeescript [specscript]
53
+ * next() -> Promise<{ value, done }>
54
+ * ```
55
+ */
56
+ async next() {
57
+ if (!consumingAsyncIterator) {
58
+ this._consumeAsyncIterator()
59
+ consumingAsyncIterator = true
60
+ }
61
+
62
+ while (!isAsyncIteratorDone) {
63
+ if (buffer.length > 0) {
64
+ return { value: buffer.popFirst(), done: false }
65
+ }
66
+ await sleep(10)
67
+ }
68
+
69
+ if (buffer.length > 0) {
70
+ return { value: buffer.popFirst(), done: false }
71
+ }
72
+
73
+ return { value: undefined, done: true }
74
+ },
75
+
76
+ }
77
+ }
78
+
79
+ module.exports = SerialMappingAsyncIterator
@@ -29,7 +29,7 @@ const _curryArity = (arity, func, context, args) => function curried(...curriedA
29
29
  curriedArgsIndex = -1,
30
30
  numCurriedPlaceholders = 0
31
31
 
32
- while (++argsIndex < argsLength) {
32
+ while ((argsIndex += 1) < argsLength) {
33
33
  const arg = args[argsIndex]
34
34
  if (arg == __ && (curriedArgsIndex += 1) < curriedArgsLength) {
35
35
  const curriedArg = curriedArgs[curriedArgsIndex]
@@ -53,7 +53,7 @@ const _curryArity = (arity, func, context, args) => function curried(...curriedA
53
53
  }
54
54
  }
55
55
 
56
- while (++curriedArgsIndex < curriedArgsLength) {
56
+ while ((curriedArgsIndex += 1) < curriedArgsLength) {
57
57
  const curriedArg = curriedArgs[curriedArgsIndex]
58
58
  if (curriedArg == __) {
59
59
  numCurriedPlaceholders += 1
@@ -103,7 +103,7 @@ const curryArity = function (arity, func, context, args) {
103
103
  return _curryArity(arity, func, context, args)
104
104
  }
105
105
  let argsIndex = -1
106
- while (++argsIndex < argsLength) {
106
+ while ((argsIndex += 1) < argsLength) {
107
107
  const arg = args[argsIndex]
108
108
  if (arg == __) {
109
109
  return _curryArity(arity, func, context, args)
@@ -28,7 +28,6 @@ const iteratorFindAsync = async function (iterator, predicate) {
28
28
  }
29
29
  iteration = iterator.next()
30
30
  }
31
- return undefined
32
31
  }
33
32
 
34
33
  /**
@@ -57,7 +56,6 @@ const iteratorFind = function (iterator, predicate) {
57
56
  }
58
57
  iteration = iterator.next()
59
58
  }
60
- return undefined
61
59
  }
62
60
 
63
61
  module.exports = iteratorFind
@@ -32,7 +32,7 @@ const _iteratorForEachSeriesAsync = async function (iterator, callback) {
32
32
  */
33
33
  const iteratorForEachSeries = function (iterator, callback) {
34
34
  let iteration = iterator.next()
35
- while (!iterator.done) {
35
+ while (!iteration.done) {
36
36
  const operation = callback(iteration.value)
37
37
  if (isPromise(operation)) {
38
38
  return operation
@@ -38,9 +38,12 @@ const objectFlatten = function (object) {
38
38
 
39
39
  for (const key in object) {
40
40
  const element = object[key]
41
+
41
42
  if (element == null) {
42
43
  continue
43
- } else if (typeof element[symbolIterator] == 'function') {
44
+ }
45
+
46
+ if (typeof element[symbolIterator] == 'function') {
44
47
  for (const monadElement of element) {
45
48
  objectAssign(result, monadElement)
46
49
  }
package/all.js CHANGED
@@ -36,42 +36,34 @@ const _allValues = function (values) {
36
36
  *
37
37
  * @synopsis
38
38
  * ```coffeescript [specscript]
39
- * args Array<any>
40
- * argsOrPromises Array<Promise|any>
39
+ * type SyncOrAsyncResolver = (...arguments)=>Promise|any
40
+ * type ResolverOrValue = SyncOrAsyncResolver|Promise|any
41
41
  *
42
- * type SyncOrAsyncResolver = (...args)=>Promise|any
42
+ * all(Promise|Array<Promise|any>) -> Promise|Array
43
+ * all(...arguments, Array<ResolverOrValue>) -> Promise|Array
44
+ * all(Array<ResolverOrValue>)(...arguments) -> Promise|Array
43
45
  *
44
- * arrayResolversOrPromisesOrValues Array<SyncOrAsyncResolver|Promise|any>
45
- * objectResolversOrPromisesOrValues Object<SyncOrAsyncResolver|Promise|any>
46
- *
47
- * all(arrayValues Promise|Array<Promise|any>) -> arrayResult Promise|Array
48
- * all(...argsOrPromises, arrayResolversOrPromisesOrValues) -> arrayResult Promise|Array
49
- * all(arrayResolversOrPromisesOrValues)(...args) -> arrayResult Promise|Array
50
- *
51
- * all(objectValues Promise|Object<Promise|any>) -> objectResult Promise|Object
52
- * all(...argsOrPromises, objectResolversOrPromisesOrValues) -> objectResult Promise|Object
53
- * all(objectResolversOrPromisesOrValues)(...args) -> objectResult Promise|Object
46
+ * all(Promise|Object<Promise|any>) -> Promise|Object
47
+ * all(...arguments, Object<ResolverOrValue>) -> Promise|Object
48
+ * all(Object<ResolverOrValue>)(...arguments) -> Promise|Object
54
49
  * ```
55
50
  *
56
51
  * @description
57
- * Constructs an array if provided an array of resolvers, promises, values, or a mix thereof. Constructs an object if provided an object of resolvers, promises, values, or a mix thereof. If provided any resolvers, `all` returns a function that constructs the array or object. Otherwise, if none of the provided values in the array or object are functions, `all` returns the constructed array or object directly.
58
- *
59
- * `all` constructs an array from resolvers.
52
+ * Function composer and data constructor. Constructs an array if provided an array of resolvers, promises, or values. Constructs an object if provided an object of resolvers, promises, or values. `all` returns a constructor function if provided resolvers. Otherwise, `all` returns the constructed array or object directly.
60
53
  *
61
54
  * ```javascript [playground]
62
- * const createArrayOfGreetingsFor = all([
55
+ * const createArrayOfGreetings = all([
63
56
  * name => `Hi ${name}`,
64
- * name => `Hey ${name}`,
65
57
  * name => `Hello ${name}`,
58
+ * name => `Greetings ${name}`,
66
59
  * ])
67
60
  *
68
- * const arrayOfGreetingsFor1 = createArrayOfGreetingsFor('1')
61
+ * const arrayOfGreetings = createArrayOfGreetings('example')
69
62
  *
70
- * console.log(arrayOfGreetingsFor1)
71
- * // ['Hi 1', 'Hey 1', 'Hello 1']
63
+ * console.log(arrayOfGreetings)
72
64
  * ```
73
65
  *
74
- * If any provided values are promises, `all` returns a promise.
66
+ * If provided promises, `all` resolves those promises and returns a promise of the resolved values.
75
67
  *
76
68
  * ```javascript [playground]
77
69
  * const promise1 = all([
@@ -79,23 +71,25 @@ const _allValues = function (values) {
79
71
  * Promise.resolve(2),
80
72
  * 3,
81
73
  * ])
82
- * promise1.then(console.log) // [1, 2, 3]
74
+ *
75
+ * promise1.then(console.log)
83
76
  *
84
77
  * const promise2 = all({
85
78
  * a: 1,
86
79
  * b: Promise.resolve(2),
87
80
  * c: Promise.resolve(3),
88
81
  * })
89
- * promise2.then(console.log) // { a: 1, b: 2, c: 3 }
82
+ *
83
+ * promise2.then(console.log)
90
84
  * ```
91
85
  *
92
- * If any provided resolvers are asynchronous, `all` returns a promise. `all` can be used in a pipeline to compose and manpulate data.
86
+ * If any resolvers provided to `all` are asynchronous, `all` returns a promise.
93
87
  *
94
88
  * ```javascript [playground]
95
89
  * const identity = value => value
96
90
  *
97
91
  * const userbase = new Map()
98
- * userbase.set('1', { _id: 1, name: 'John' })
92
+ * userbase.set('1', { id: 1, name: 'John' })
99
93
  *
100
94
  * const getUserByID = async id => userbase.get(id)
101
95
  *
@@ -109,35 +103,17 @@ const _allValues = function (values) {
109
103
  * }),
110
104
  * ])
111
105
  *
112
- * getAndLogUserById('1') // Got user {"_id":1,"name":"John"} by id 1
106
+ * getAndLogUserById('1')
113
107
  * ```
114
108
  *
115
- * Provided no resolvers, `all` returns the constructed array or object.
109
+ * Any promises in `arguments` are resolved for their values before further execution for the eager interface only.
116
110
  *
117
111
  * ```javascript [playground]
118
- * all({}, {
119
- * a: Promise.resolve(1),
120
- * b: 2,
121
- * c: () => 3,
122
- * d: async () => 4,
123
- * }).then(console.log) // { a: 1, b: 2, c: 3, d: 4 }
124
- *
125
- * all([], [
126
- * Promise.resolve(1),
127
- * 2,
128
- * () => 3,
129
- * async () => 4,
130
- * ]).then(console.log) // [1, 2, 3, 4]
131
- * ```
132
- *
133
- * Any promises passed in argument position are resolved for their values before further execution. This only applies to the eager version of the API.
134
- *
135
- * ```javascript [playground]
136
- * all(Promise.resolve({ a: 1 }), [
137
- * obj => obj.a + 1,
138
- * obj => obj.a + 2,
139
- * obj => obj.a + 3,
140
- * ]).then(console.log) // [2, 3, 4]
112
+ * all(Promise.resolve({ a: 1 }), Promise.resolve(2), [
113
+ * (obj, n) => obj.a + n + 1,
114
+ * (obj, n) => obj.a + n + 2,
115
+ * (obj, n) => obj.a + n + 3,
116
+ * ]).then(console.log)
141
117
  * ```
142
118
  *
143
119
  * See also:
@@ -186,26 +162,24 @@ const all = function (...args) {
186
162
  *
187
163
  * @synopsis
188
164
  * ```coffeescript [specscript]
189
- * all.series(...args, funcsArray Array<function>) -> result Promise|Array
165
+ * all.series(...arguments, Array<function>) -> Promise|Array
190
166
  *
191
- * all.series(funcsArray Array<function>)(...args) -> result Promise|Array
167
+ * all.series(Array<function>)(...arguments) -> Promise|Array
192
168
  * ```
193
169
  *
194
170
  * @description
195
- * `all` with serial execution.
171
+ * [all](/docs/all) with serial execution.
196
172
  *
197
173
  * ```javascript [playground]
198
174
  * const sleep = ms => () => new Promise(resolve => setTimeout(resolve, ms))
199
175
  *
200
- * all.series([
176
+ * all.series('hello', [
201
177
  * greeting => console.log(greeting + ' world'),
202
178
  * sleep(1000),
203
- * greeting => console.log(greeting + ' mom'),
179
+ * greeting => console.log(greeting + ' all'),
204
180
  * sleep(1000),
205
181
  * greeting => console.log(greeting + ' goodbye'),
206
- * ])('hello') // hello world
207
- * // hello mom
208
- * // hello goodbye
182
+ * ])
209
183
  * ```
210
184
  *
211
185
  * @execution series
package/and.js CHANGED
@@ -145,7 +145,7 @@ const areAllPredicatesTruthy = function (args, predicates) {
145
145
  * console.log(condition) // true
146
146
  * ```
147
147
  *
148
- * Any promises passed in argument position are resolved for their values before further execution. This only applies to the eager version of the API.
148
+ * Any promises passed in data argument position are resolved for their values before further execution.
149
149
  *
150
150
  * ```javascript [playground]
151
151
  * and(Promise.resolve(5), [
package/assign.js CHANGED
@@ -18,36 +18,33 @@ const _assign = function (object, funcs) {
18
18
  *
19
19
  * @synopsis
20
20
  * ```coffeescript [specscript]
21
- * args Array<any>
22
- *
23
21
  * type UnarySyncOrAsyncResolver = any=>Promise|any
24
22
  *
25
- * objectResolversOrPromisesOrValues Object<UnarySyncOrAsyncResolver|Promise|any>
26
- *
27
- * assign(argumentObject Promise|Object, objectResolversOrPromisesOrValues) -> resultObject
28
- * assign(objectResolversOrPromisesOrValues)(argumentObject Object) -> resultObject
23
+ * assign(Promise|Object, Object<UnarySyncOrAsyncResolver|Promise|any>) -> Promise|Object
24
+ * assign(Object<UnarySyncOrAsyncResolver|Promise|any>)(Object) -> Promise|Object
29
25
  * ```
30
26
  *
31
27
  * @description
32
- * Function equivalent to [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign). Constructs an object `result` from an object `objectResolversOrPromisesOrValues` of resolvers, promises, values, or a mix thereof and an argument object `argumentObject`.
28
+ * Function composer and data constructor. Constructs a new object from an argument object and an object of resolvers, promises, or values.
33
29
  *
34
- * If any values of `objectResolversOrPromisesOrValues` are resolvers, `assign` provides the `argumentObject` to those resolvers to resolve the values for assignment in `resultObject`.
30
+ * If provided resolver functions, `assign` resolves the values to be assigned at the keys of the resolver functions in the new object by calling those resolvers with the argument object.
35
31
  *
36
32
  * ```javascript [playground]
37
33
  * const assignSquaredAndCubed = assign({
38
34
  * squared: ({ number }) => number ** 2,
39
35
  * cubed: ({ number }) => number ** 3,
40
- * n: 1,
41
36
  * })
42
37
  *
43
38
  * console.log(assignSquaredAndCubed({ number: 2 }))
44
- * // { number: 2, squared: 4, cubed: 8, n: 1 }
45
- *
46
39
  * console.log(assignSquaredAndCubed({ number: 3 }))
47
- * // { number: 3, squared: 9, cubed: 27, n: 1 }
40
+ *
41
+ * const n = 1
42
+ * const assignN = assign({ n })
43
+ *
44
+ * console.log(assignN({}))
48
45
  * ```
49
46
  *
50
- * If any of the resolvers in `objectResolversOrPromisesOrValues` are asynchronous, `assign` returns a promise of `resultObject`.
47
+ * If any of the resolvers provided to `assign` are asynchronous, the execution of `assign` with the argument object returns a promise.
51
48
  *
52
49
  * ```javascript [playground]
53
50
  * const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
@@ -59,11 +56,12 @@ const _assign = function (object, funcs) {
59
56
  * },
60
57
  * })
61
58
  *
62
- * asyncAssignTotal({ numbers: [1, 2, 3, 4, 5] }).then(console.log)
63
- * // { numbers: [1, 2, 3, 4, 5], total: 15 }
59
+ * const promise = asyncAssignTotal({ numbers: [1, 2, 3, 4, 5] })
60
+ *
61
+ * promise.then(console.log)
64
62
  * ```
65
63
  *
66
- * Any promises passed in argument position are resolved for their values before further execution. This only applies to the eager version of the API.
64
+ * If the argument object is a promise, it is resolved for its value before further execution for the eager interface only.
67
65
  *
68
66
  * ```javascript [playground]
69
67
  * assign(Promise.resolve({}), {