rubico 2.10.0 → 2.11.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.
@@ -1,38 +1,89 @@
1
+ const promiseRace = require('./promiseRace')
2
+ const __ = require('./placeholder')
3
+ const curry2 = require('./curry2')
1
4
  const isPromise = require('./isPromise')
5
+ const LinkedList = require('./LinkedList')
2
6
  const symbolAsyncIterator = require('./symbolAsyncIterator')
7
+ const arrayPush = require('./arrayPush')
8
+ const sleep = require('./sleep')
3
9
 
4
10
  /**
5
11
  * @name FilteringAsyncIterator
6
12
  *
7
13
  * @synopsis
8
14
  * ```coffeescript [specscript]
9
- * const filteringAsyncIterator = new FilteringAsyncIterator(
10
- * asyncIterator AsyncIterator<T>,
11
- * predicate T=>boolean,
12
- * ) -> FilteringAsyncIterator<T>
15
+ * filteringAsyncIterator = new FilteringAsyncIterator(
16
+ * asyncIter AsyncIterator<T>,
17
+ * predicate T=>Promise|boolean,
18
+ * ) -> filteringAsyncIterator AsyncIterator
13
19
  *
14
- * filteringAsyncIterator.next() -> { value: Promise, done: boolean }
20
+ * filteringAsyncIterator.next() -> Promise<{ value: any, done: boolean }>
15
21
  * ```
16
22
  */
17
- const FilteringAsyncIterator = (asyncIterator, predicate) => ({
18
- isAsyncIteratorDone: false,
19
- [symbolAsyncIterator]() {
20
- return this
21
- },
22
- async next() {
23
- while (!this.isAsyncIteratorDone) {
24
- const { value, done } = await asyncIterator.next()
25
- if (done) {
26
- this.isAsyncIteratorDone = true
27
- } else {
28
- const predication = predicate(value)
29
- if (isPromise(predication) ? await predication : predication) {
30
- return { value, done: false }
23
+ const FilteringAsyncIterator = (asyncIterator, predicate) => {
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 booleanResult = predicate(item)
40
+ buffer.append([booleanResult, item])
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 [booleanResult, item] = buffer.popFirst()
62
+ if (isPromise(booleanResult)) {
63
+ booleanResult = await booleanResult
64
+ }
65
+ if (booleanResult) {
66
+ return { value: item, done: false }
67
+ }
68
+ continue
31
69
  }
70
+ await sleep(10)
32
71
  }
33
- }
34
- return { value: undefined, done: true }
35
- },
36
- })
72
+
73
+ while (buffer.length > 0) {
74
+ let [booleanResult, item] = buffer.popFirst()
75
+ if (isPromise(booleanResult)) {
76
+ booleanResult = await booleanResult
77
+ }
78
+ if (booleanResult) {
79
+ return { value: item, done: false }
80
+ }
81
+ }
82
+
83
+ return { value: undefined, done: true }
84
+ },
85
+
86
+ }
87
+ }
37
88
 
38
89
  module.exports = FilteringAsyncIterator
package/filter.js CHANGED
@@ -96,14 +96,14 @@ const _filter = function (value, predicate) {
96
96
  * value any,
97
97
  * indexOrKey number|string|any,
98
98
  * filterable Filterable,
99
- * )=>(condition Promise|boolean)
99
+ * )=>(booleanResult Promise|boolean)
100
100
  *
101
- * filter(filterable Promise|Filterable, predicate SyncOrAsyncPredicate) -> result Promise|Filterable
102
- * filter(predicate SyncOrAsyncPredicate)(filterable Filterable) -> result Promise|Filterable
101
+ * filter(filterable Promise|Filterable, predicate SyncOrAsyncPredicate) -> filteredFilterable Promise|Filterable
102
+ * filter(predicate SyncOrAsyncPredicate)(filterable Filterable) -> filteredFilterable Promise|Filterable
103
103
  * ```
104
104
  *
105
105
  * @description
106
- * Filters out elements from a filterable. Returns a filterable of the same type. The order of the elements in the filterable is preserved.
106
+ * Filters out items from a filterable, returning a filterable of the same type. The order of the items of the filterable is preserved.
107
107
  *
108
108
  * The following data types are considered to be filterables:
109
109
  * * `array`
@@ -114,12 +114,12 @@ const _filter = function (value, predicate) {
114
114
  * * `object with .filter method`
115
115
  * * `object`
116
116
  *
117
- * The filtering operation is defined by a given predicate function. The predicate function dictates whether a given element from the filterable should be included in the returned filterable.
117
+ * The filtering operation is defined by a given predicate function. The predicate function dictates whether a given item from the filterable should be included in the returned filterable.
118
118
  *
119
119
  * ```javascript
120
- * const predicate = function (element) {
121
- * // condition is the boolean result of the predicate test on element
122
- * return condition
120
+ * const predicate = function (item) {
121
+ * // booleanResult is the boolean result of the predicate test on item
122
+ * return booleanResult
123
123
  * }
124
124
  * ```
125
125
  *
@@ -127,48 +127,47 @@ const _filter = function (value, predicate) {
127
127
  *
128
128
  * If the filterable is an array:
129
129
  * ```coffeescript [specscript]
130
- * predicate(element any, index number, filt Array) -> condition Promise|boolean|any
130
+ * predicate(item any, index number, filterable Array) -> booleanResult Promise|boolean|any
131
131
  * ```
132
132
  *
133
133
  * If the filterable is a set:
134
134
  * ```coffeescript [specscript]
135
- * predicate(element any, element any, filt Set) -> condition Promise|boolean|any
135
+ * predicate(item any, item any, filterable Set) -> booleanResult Promise|boolean|any
136
136
  * ```
137
137
  *
138
138
  * If the filterable is a map:
139
139
  * ```coffeescript [specscript]
140
- * predicate(element any, key any, filt Map) -> condition Promise|boolean|any
140
+ * predicate(item any, key any, filterable Map) -> booleanResult Promise|boolean|any
141
141
  * ```
142
142
  *
143
143
  * If the filterable is a generator:
144
144
  * ```coffeescript [specscript]
145
- * predicate(element any) -> condition Promise|boolean|any
145
+ * predicate(item any) -> booleanResult Promise|boolean|any
146
146
  * ```
147
147
  *
148
148
  * If the filterable is an async generator:
149
149
  * ```coffeescript [specscript]
150
- * predicate(element any) -> condition Promise|boolean|any
150
+ * predicate(item any) -> booleanResult Promise|boolean|any
151
151
  * ```
152
152
  *
153
153
  * If the filterable is an object with a `.filter` method, the predicate function signature is defined externally.
154
154
  *
155
155
  * If the filterable is a plain object:
156
156
  * ```coffeescript [specscript]
157
- * predicate(element any, key string, filt Object) -> condition Promise|boolean|any
157
+ * predicate(item any, key string, filterable Object) -> booleanResult Promise|boolean|any
158
158
  * ```
159
159
  *
160
- * `filter` works for arrays.
161
- *
162
160
  * ```javascript [playground]
163
161
  * const isOdd = number => number % 2 == 1
164
162
  *
165
163
  * const array = [1, 2, 3, 4, 5]
166
164
  *
167
- * const result = filter(array, isOdd)
168
- * console.log(result) // [1, 3, 5]
165
+ * const filteredArray = filter(array, isOdd)
166
+ *
167
+ * console.log(filteredArray)
169
168
  * ```
170
169
  *
171
- * If the predicate is asynchronous, the returned promise is concurrently resolved for its boolean condition before continuing with the filtering operation.
170
+ * If the predicate is asynchronous, it is executed concurrently.
172
171
  *
173
172
  * ```javascript [playground]
174
173
  * const asyncIsOdd = async number => number % 2 == 1
package/map.js CHANGED
@@ -107,7 +107,7 @@ const _map = function (value, f) {
107
107
  * ```
108
108
  *
109
109
  * @description
110
- * Applies a mapper function to each item of a functor, returning a mapped functor of the same type with the mapped items. The order of the elements is maintained.
110
+ * Applies a mapper function to each item of a functor, returning a mapped functor of the same type with the mapped items. The order of the items of the functor is preserved.
111
111
  *
112
112
  * The following data types are considered to be functors:
113
113
  * * `array`
@@ -204,7 +204,7 @@ const _map = function (value, f) {
204
204
  * console.log(mappedMap)
205
205
  * ```
206
206
  *
207
- * `map` maps each value of a generator, creating a new generator with mapped elements.
207
+ * `map` maps each value of a generator, creating a new generator with mapped items.
208
208
  *
209
209
  * ```javascript [playground]
210
210
  * const capitalize = string => string.toUpperCase()
@@ -373,7 +373,7 @@ map.entries = function mapEntries(arg0, arg1) {
373
373
  * value any,
374
374
  * indexOrKey number|string|any,
375
375
  * f Functor
376
- * )=>(mappedElement Promise|any)
376
+ * )=>(mappedItem Promise|any)
377
377
  *
378
378
  * _mapSeries(f Functor, f SyncOrAsyncMapper) -> result Promise|Functor
379
379
  * ```
@@ -421,7 +421,7 @@ const _mapSeries = function (functor, f) {
421
421
  * value any,
422
422
  * indexOrKey number|string|any,
423
423
  * functor Functor,
424
- * )=>(mappedElement Promise|any)
424
+ * )=>(mappedItem Promise|any)
425
425
  *
426
426
  * map.series(
427
427
  * functor Promise|Functor,
@@ -558,13 +558,12 @@ const _mapPool = function (f, concurrency, mapper) {
558
558
  * ]))(ids)
559
559
  * ```
560
560
  *
561
- * Any promises passed in data argument position are resolved for their values before further execution.
561
+ * If the functor is a promise, it is resolved for its value before further execution for the eager interface only.
562
562
  *
563
563
  * ```javascript [playground]
564
564
  * const asyncSquare = async n => n ** 2
565
565
  *
566
566
  * map.pool(Promise.resolve([1, 2, 3, 4, 5]), 5, asyncSquare).then(console.log)
567
- * // [1, 4, 9, 16, 25]
568
567
  * ```
569
568
  *
570
569
  * See also:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rubico",
3
- "version": "2.10.0",
3
+ "version": "2.11.0",
4
4
  "description": "[a]synchronous functional programming",
5
5
  "author": "Richard Tong",
6
6
  "license": "CFOSS",