ig-types 6.15.1 → 6.15.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Array.js +20 -2
- package/Promise.js +10 -14
- package/README.md +57 -13
- package/generator.js +217 -71
- package/package.json +1 -1
package/Array.js
CHANGED
|
@@ -24,6 +24,9 @@ var STOP =
|
|
|
24
24
|
module.STOP =
|
|
25
25
|
object.STOP
|
|
26
26
|
|
|
27
|
+
var stoppable =
|
|
28
|
+
module.stoppable =
|
|
29
|
+
generator.stoppable
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
//---------------------------------------------------------------------
|
|
@@ -212,6 +215,7 @@ object.Mixin('ArrayMixin', 'soft', {
|
|
|
212
215
|
// done...
|
|
213
216
|
: [] },
|
|
214
217
|
|
|
218
|
+
// XXX add handler function support -- a-la generator.js'
|
|
215
219
|
iter: function*(lst=[]){
|
|
216
220
|
yield* lst.iter() },
|
|
217
221
|
})
|
|
@@ -488,8 +492,22 @@ object.Mixin('ArrayProtoMixin', 'soft', {
|
|
|
488
492
|
// -> iterator
|
|
489
493
|
//
|
|
490
494
|
// XXX should this take an argument and be like map??
|
|
491
|
-
|
|
492
|
-
|
|
495
|
+
// XXX this should handle throwing STOP!!!
|
|
496
|
+
// ...might also ne a good idea to isolate the STOP mechanics
|
|
497
|
+
// into a spearate module/package...
|
|
498
|
+
iter: stoppable(function*(handler=undefined){
|
|
499
|
+
if(handler){
|
|
500
|
+
var i = 0
|
|
501
|
+
for(var e of this){
|
|
502
|
+
var res = handler.call(this, e, i++)
|
|
503
|
+
// treat non-iterables as single elements...
|
|
504
|
+
if(typeof(res) == 'object'
|
|
505
|
+
&& Symbol.iterator in res){
|
|
506
|
+
yield* res
|
|
507
|
+
} else {
|
|
508
|
+
yield res } }
|
|
509
|
+
} else {
|
|
510
|
+
yield* this }}),
|
|
493
511
|
|
|
494
512
|
|
|
495
513
|
// Stoppable iteration...
|
package/Promise.js
CHANGED
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
var object = require('ig-object')
|
|
32
32
|
|
|
33
|
+
//var generator = require('./generator')
|
|
34
|
+
|
|
33
35
|
|
|
34
36
|
|
|
35
37
|
//---------------------------------------------------------------------
|
|
@@ -58,6 +60,7 @@ var object = require('ig-object')
|
|
|
58
60
|
//
|
|
59
61
|
// XXX how do we handle errors/rejections???
|
|
60
62
|
// ...mostly the current state is OK, but need more testing...
|
|
63
|
+
// XXX add support for async generators...
|
|
61
64
|
//
|
|
62
65
|
|
|
63
66
|
var iterPromiseProxy =
|
|
@@ -117,6 +120,11 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
117
120
|
// stop will stop the handlers not yet run and not the next
|
|
118
121
|
// handlers in sequence.
|
|
119
122
|
// XXX EXPEREMENTAL: STOP...
|
|
123
|
+
// XXX add support for async generators...
|
|
124
|
+
// ...an async generator is not "parallel", i.e. intil one
|
|
125
|
+
// returned promise is resolved the generator blocks (will not
|
|
126
|
+
// advance)...
|
|
127
|
+
// ...can we feed out a results one by one???
|
|
120
128
|
__pack: function(list, handler=undefined){
|
|
121
129
|
var that = this
|
|
122
130
|
// handle iterable promise list...
|
|
@@ -198,20 +206,6 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
198
206
|
: handler(elem) }) },
|
|
199
207
|
//*/
|
|
200
208
|
// transform/handle packed array (sync)...
|
|
201
|
-
//
|
|
202
|
-
// XXX BUG:
|
|
203
|
-
// await Promise.iter(['a', Promise.resolve(222), ['c']])
|
|
204
|
-
// .map(async e => e)
|
|
205
|
-
// -> ['a', <promise>, ['c']]
|
|
206
|
-
// is not the same as:
|
|
207
|
-
// await Promise.iter(['a', Promise.resolve(222), ['c']])
|
|
208
|
-
// .map(e => e)
|
|
209
|
-
// -> ['a', 222, ['c']]
|
|
210
|
-
// ...and these works as expected:
|
|
211
|
-
// await Promise.iter(['a', Promise.resolve(222), ['c']], async e => [e])
|
|
212
|
-
// -> ['a', 222, ['c']]
|
|
213
|
-
// await Promise.iter(['a', Promise.resolve(222), ['c']], e => [e])
|
|
214
|
-
// -> ['a', 222, ['c']]
|
|
215
209
|
__handle: function(list, handler=undefined){
|
|
216
210
|
var that = this
|
|
217
211
|
if(typeof(list) == 'function'){
|
|
@@ -300,6 +294,8 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
300
294
|
.then(function(){
|
|
301
295
|
return res }) },
|
|
302
296
|
|
|
297
|
+
// XXX .chain(..) -- see generator.chain(..)
|
|
298
|
+
|
|
303
299
|
flat: function(depth=1){
|
|
304
300
|
return this.constructor(this,
|
|
305
301
|
function(e){
|
package/README.md
CHANGED
|
@@ -94,7 +94,7 @@ Library of JavaScript type extensions, types and utilities.
|
|
|
94
94
|
- [`generator.iter(..)`](#generatoriter)
|
|
95
95
|
- [`generator.STOP`](#generatorstop)
|
|
96
96
|
- [Generator instance iteration](#generator-instance-iteration)
|
|
97
|
-
- [`<generator>.iter()`](#generatoriter-1)
|
|
97
|
+
- [`<generator>.iter(..)`](#generatoriter-1)
|
|
98
98
|
- [`<generator>.map(..)` / `<generator>.filter(..)`](#generatormap--generatorfilter)
|
|
99
99
|
- [`<generator>.reduce(..)` / `<generator>.greduce(..)`](#generatorreduce--generatorgreduce)
|
|
100
100
|
- [`<generator>.slice(..)`](#generatorslice)
|
|
@@ -102,7 +102,6 @@ Library of JavaScript type extensions, types and utilities.
|
|
|
102
102
|
- [`<generator>.flat(..)`](#generatorflat)
|
|
103
103
|
- [`<generator>.shift()` / `<generator>.pop()` / `<generator>.gshift()` / `<generator>.gpop()`](#generatorshift--generatorpop--generatorgshift--generatorgpop)
|
|
104
104
|
- [`<generator>.unshift(..)` / `<generator>.push(..)`](#generatorunshift--generatorpush)
|
|
105
|
-
- [`<generator>.promise()`](#generatorpromise)
|
|
106
105
|
- [`<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)`](#generatorthen--generatorcatch--generatorfinally)
|
|
107
106
|
- [`<generator>.toArray()`](#generatortoarray)
|
|
108
107
|
- [Treating iterators the same as generators](#treating-iterators-the-same-as-generators)
|
|
@@ -124,6 +123,15 @@ Library of JavaScript type extensions, types and utilities.
|
|
|
124
123
|
- [`generator.produce(..)`](#generatorproduce)
|
|
125
124
|
- [Generator helpers](#generator-helpers)
|
|
126
125
|
- [`generator.stoppable(..)`](#generatorstoppable)
|
|
126
|
+
- [Async generator extensions](#async-generator-extensions)
|
|
127
|
+
- [`generator.AsyncGenerator`](#generatorasyncgenerator)
|
|
128
|
+
- [`<async-generator>.then(..)` / `<async-generator>.catch(..)` / `<async-generator>.finally(..)`](#async-generatorthen--async-generatorcatch--async-generatorfinally)
|
|
129
|
+
- [`<async-generator>.iter(..)`](#async-generatoriter)
|
|
130
|
+
- [`<async-generator>.map(..)` / `<async-generator>.filter(..)` / `<async-generator>.reduce(..)`](#async-generatormap--async-generatorfilter--async-generatorreduce)
|
|
131
|
+
- [`<async-generator>.chain(..)`](#async-generatorchain)
|
|
132
|
+
- [`<async-generator>.flat(..)`](#async-generatorflat)
|
|
133
|
+
- [`<async-generator>.concat(..)`](#async-generatorconcat)
|
|
134
|
+
- [`<async-generator>.push(..)` / `<async-generator>.unshift(..)`](#async-generatorpush--async-generatorunshift)
|
|
127
135
|
- [Containers](#containers)
|
|
128
136
|
- [`containers.UniqueKeyMap()` (`Map`)](#containersuniquekeymap-map)
|
|
129
137
|
- [`<unique-key-map>.set(..)`](#unique-key-mapset)
|
|
@@ -2023,7 +2031,7 @@ Chained generators handle items depth-first, i.e. the items are passed as they
|
|
|
2023
2031
|
are yielded down the generator chain.
|
|
2024
2032
|
|
|
2025
2033
|
|
|
2026
|
-
#### `<generator>.iter()`
|
|
2034
|
+
#### `<generator>.iter(..)`
|
|
2027
2035
|
|
|
2028
2036
|
Iterate over the generator.
|
|
2029
2037
|
```bnf
|
|
@@ -2031,7 +2039,24 @@ Iterate over the generator.
|
|
|
2031
2039
|
-> <generator>
|
|
2032
2040
|
```
|
|
2033
2041
|
|
|
2034
|
-
|
|
2042
|
+
XXX move this to `generator.iter(..)`
|
|
2043
|
+
|
|
2044
|
+
Compatible with [`<array>`'s `.iter()`](#arrayiter--arrayiter).
|
|
2045
|
+
|
|
2046
|
+
`.iter(..)` also supports a handler function
|
|
2047
|
+
```bnf
|
|
2048
|
+
<generator>.iter(<handler>)
|
|
2049
|
+
-> <generator>
|
|
2050
|
+
|
|
2051
|
+
|
|
2052
|
+
<handler>(<elem>, <index>)
|
|
2053
|
+
-> <elem>
|
|
2054
|
+
-> [<elem>, ..]
|
|
2055
|
+
-> []
|
|
2056
|
+
```
|
|
2057
|
+
|
|
2058
|
+
Note that the iterables returned by `<handler>(..)` will be expanded, to prevent
|
|
2059
|
+
this wrap them in an array.
|
|
2035
2060
|
|
|
2036
2061
|
|
|
2037
2062
|
#### `<generator>.map(..)` / `<generator>.filter(..)`
|
|
@@ -2156,30 +2181,29 @@ Value added by `.unshift(..)` will be yielded by `<generator>` "first", i.e. on
|
|
|
2156
2181
|
_next_ call to `.next()`, regardless of the current generator state.
|
|
2157
2182
|
|
|
2158
2183
|
|
|
2159
|
-
#### `<generator>.
|
|
2184
|
+
#### `<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)`
|
|
2185
|
+
|
|
2186
|
+
Return a promise and resolve it with the generator value.
|
|
2160
2187
|
|
|
2161
2188
|
```bnf
|
|
2162
|
-
<generator>.
|
|
2189
|
+
<generator>.then()
|
|
2163
2190
|
-> <promise>
|
|
2164
2191
|
```
|
|
2165
|
-
Return a promise and resolve it with the generator value.
|
|
2166
|
-
|
|
2167
|
-
Note that this will deplete the generator.
|
|
2168
|
-
|
|
2169
2192
|
|
|
2170
|
-
|
|
2193
|
+
Adding handlers to the promise
|
|
2171
2194
|
|
|
2172
2195
|
```bnf
|
|
2173
2196
|
<generator>.then(<resolve>, <reject>)
|
|
2174
2197
|
-> <promise>
|
|
2175
2198
|
|
|
2176
|
-
<generator>.then(<
|
|
2199
|
+
<generator>.then(<resolve>)
|
|
2177
2200
|
-> <promise>
|
|
2178
2201
|
|
|
2179
2202
|
<generator>.finally(<handler>)
|
|
2180
2203
|
-> <promise>
|
|
2181
2204
|
```
|
|
2182
|
-
|
|
2205
|
+
|
|
2206
|
+
Note that this will deplete the generator.
|
|
2183
2207
|
|
|
2184
2208
|
These are the same as equivalent `Promise` methods, for more info see:
|
|
2185
2209
|
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
|
|
@@ -2483,6 +2507,26 @@ stoppable(<generator>)
|
|
|
2483
2507
|
|
|
2484
2508
|
<!-- XXX example? -->
|
|
2485
2509
|
|
|
2510
|
+
## Async generator extensions
|
|
2511
|
+
|
|
2512
|
+
XXX EXPERIMENTAL
|
|
2513
|
+
|
|
2514
|
+
#### `generator.AsyncGenerator`
|
|
2515
|
+
|
|
2516
|
+
#### `<async-generator>.then(..)` / `<async-generator>.catch(..)` / `<async-generator>.finally(..)`
|
|
2517
|
+
|
|
2518
|
+
#### `<async-generator>.iter(..)`
|
|
2519
|
+
|
|
2520
|
+
#### `<async-generator>.map(..)` / `<async-generator>.filter(..)` / `<async-generator>.reduce(..)`
|
|
2521
|
+
|
|
2522
|
+
#### `<async-generator>.chain(..)`
|
|
2523
|
+
|
|
2524
|
+
#### `<async-generator>.flat(..)`
|
|
2525
|
+
|
|
2526
|
+
#### `<async-generator>.concat(..)`
|
|
2527
|
+
|
|
2528
|
+
#### `<async-generator>.push(..)` / `<async-generator>.unshift(..)`
|
|
2529
|
+
|
|
2486
2530
|
|
|
2487
2531
|
|
|
2488
2532
|
## Containers
|
package/generator.js
CHANGED
|
@@ -86,13 +86,86 @@ var ITERATOR_PROTOTYPES = [
|
|
|
86
86
|
|
|
87
87
|
//---------------------------------------------------------------------
|
|
88
88
|
|
|
89
|
+
// XXX should this be part of object???
|
|
90
|
+
var stoppable =
|
|
91
|
+
module.stoppable =
|
|
92
|
+
function(func){
|
|
93
|
+
return Object.assign(
|
|
94
|
+
func instanceof Generator ?
|
|
95
|
+
// NOTE: the only difference between Generator/AsyncGenerator
|
|
96
|
+
// versions of this is the async keyword -- keep them
|
|
97
|
+
// in sync...
|
|
98
|
+
function*(){
|
|
99
|
+
try{
|
|
100
|
+
yield* func.call(this, ...arguments)
|
|
101
|
+
} catch(err){
|
|
102
|
+
if(err === STOP){
|
|
103
|
+
return
|
|
104
|
+
} else if(err instanceof STOP){
|
|
105
|
+
yield err.value
|
|
106
|
+
return }
|
|
107
|
+
throw err } }
|
|
108
|
+
: func instanceof AsyncGenerator ?
|
|
109
|
+
// NOTE: the only difference between Generator/AsyncGenerator
|
|
110
|
+
// versions of this is the async keyword -- keep them
|
|
111
|
+
// in sync...
|
|
112
|
+
async function*(){
|
|
113
|
+
try{
|
|
114
|
+
yield* func.call(this, ...arguments)
|
|
115
|
+
} catch(err){
|
|
116
|
+
if(err === STOP){
|
|
117
|
+
return
|
|
118
|
+
} else if(err instanceof STOP){
|
|
119
|
+
yield err.value
|
|
120
|
+
return }
|
|
121
|
+
throw err } }
|
|
122
|
+
: function(){
|
|
123
|
+
try{
|
|
124
|
+
return func.call(this, ...arguments)
|
|
125
|
+
} catch(err){
|
|
126
|
+
if(err === STOP){
|
|
127
|
+
return
|
|
128
|
+
} else if(err instanceof STOP){
|
|
129
|
+
return err.value }
|
|
130
|
+
throw err } },
|
|
131
|
+
{ toString: function(){
|
|
132
|
+
return func.toString() }, }) }
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
//---------------------------------------------------------------------
|
|
89
136
|
// generic generator wrapper...
|
|
137
|
+
|
|
138
|
+
// helper...
|
|
139
|
+
var __iter =
|
|
140
|
+
module.__iter =
|
|
141
|
+
function*(lst=[]){
|
|
142
|
+
if(typeof(lst) == 'object'
|
|
143
|
+
&& Symbol.iterator in lst){
|
|
144
|
+
yield* lst
|
|
145
|
+
} else {
|
|
146
|
+
yield lst } }
|
|
147
|
+
|
|
148
|
+
// XXX updatae Array.js' version for compatibility...
|
|
149
|
+
// XXX DOCS!!!
|
|
90
150
|
var iter =
|
|
91
151
|
module.iter =
|
|
92
152
|
Generator.iter =
|
|
93
|
-
function
|
|
94
|
-
|
|
95
|
-
|
|
153
|
+
stoppable(function(lst=[]){
|
|
154
|
+
// handler -> generator-constructor...
|
|
155
|
+
if(typeof(lst) == 'function'){
|
|
156
|
+
// we need to be callable...
|
|
157
|
+
var that = this instanceof Function ?
|
|
158
|
+
this
|
|
159
|
+
// generic root generator...
|
|
160
|
+
: module.__iter
|
|
161
|
+
return function*(){
|
|
162
|
+
yield* that(...arguments).iter(lst) } }
|
|
163
|
+
// no handler -> generator instance...
|
|
164
|
+
return module.__iter(lst) })
|
|
165
|
+
|
|
166
|
+
// NOTE: we need .iter(..) to both return generators if passed an iterable
|
|
167
|
+
// and genereator constructos if passed a function...
|
|
168
|
+
iter.__proto__ = GeneratorPrototype
|
|
96
169
|
|
|
97
170
|
|
|
98
171
|
|
|
@@ -121,9 +194,11 @@ Generator.iter =
|
|
|
121
194
|
|
|
122
195
|
//
|
|
123
196
|
// makeGenerator(<name>)
|
|
197
|
+
// makeGenerator(<name>, <handler>)
|
|
124
198
|
// -> <func>
|
|
125
199
|
//
|
|
126
|
-
// makeGenerator(<name
|
|
200
|
+
// makeGenerator('async', <name>)
|
|
201
|
+
// makeGenerator('async', <name>, <handler>)
|
|
127
202
|
// -> <func>
|
|
128
203
|
//
|
|
129
204
|
//
|
|
@@ -140,14 +215,26 @@ Generator.iter =
|
|
|
140
215
|
// XXX this needs to be of the correct type... (???)
|
|
141
216
|
// XXX need to accept generators as handlers...
|
|
142
217
|
var makeGenerator = function(name, pre){
|
|
218
|
+
var sync = true
|
|
219
|
+
if(name == 'async'){
|
|
220
|
+
sync = false
|
|
221
|
+
var [name, pre] = [...arguments].slice(1) }
|
|
143
222
|
return function(...args){
|
|
144
223
|
var that = this
|
|
145
224
|
return Object.assign(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
225
|
+
// NOTE: the two branches here are identical, the only
|
|
226
|
+
// difference is the async keyword...
|
|
227
|
+
sync ?
|
|
228
|
+
function*(){
|
|
229
|
+
var a = pre ?
|
|
230
|
+
pre.call(this, args, ...arguments)
|
|
231
|
+
: args
|
|
232
|
+
yield* that(...arguments)[name](...a) }
|
|
233
|
+
: async function*(){
|
|
234
|
+
var a = pre ?
|
|
235
|
+
pre.call(this, args, ...arguments)
|
|
236
|
+
: args
|
|
237
|
+
yield* that(...arguments)[name](...a) },
|
|
151
238
|
{ toString: function(){
|
|
152
239
|
return [
|
|
153
240
|
that.toString(),
|
|
@@ -163,34 +250,6 @@ var makePromise = function(name){
|
|
|
163
250
|
return that(...arguments)[name](func) } } }
|
|
164
251
|
|
|
165
252
|
|
|
166
|
-
var stoppable =
|
|
167
|
-
module.stoppable =
|
|
168
|
-
function(func){
|
|
169
|
-
return Object.assign(
|
|
170
|
-
func instanceof Generator ?
|
|
171
|
-
function*(){
|
|
172
|
-
try{
|
|
173
|
-
yield* func.call(this, ...arguments)
|
|
174
|
-
} catch(err){
|
|
175
|
-
if(err === STOP){
|
|
176
|
-
return
|
|
177
|
-
} else if(err instanceof STOP){
|
|
178
|
-
yield err.value
|
|
179
|
-
return }
|
|
180
|
-
throw err } }
|
|
181
|
-
: function(){
|
|
182
|
-
try{
|
|
183
|
-
return func.call(this, ...arguments)
|
|
184
|
-
} catch(err){
|
|
185
|
-
if(err === STOP){
|
|
186
|
-
return
|
|
187
|
-
} else if(err instanceof STOP){
|
|
188
|
-
return err.value }
|
|
189
|
-
throw err } },
|
|
190
|
-
{ toString: function(){
|
|
191
|
-
return func.toString() }, }) }
|
|
192
|
-
|
|
193
|
-
|
|
194
253
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
195
254
|
|
|
196
255
|
var GeneratorMixin =
|
|
@@ -198,9 +257,7 @@ module.GeneratorMixin =
|
|
|
198
257
|
object.Mixin('GeneratorMixin', 'soft', {
|
|
199
258
|
STOP: object.STOP,
|
|
200
259
|
|
|
201
|
-
|
|
202
|
-
iter: function*(lst=[]){
|
|
203
|
-
yield* module.iter(lst) },
|
|
260
|
+
iter: module.iter,
|
|
204
261
|
|
|
205
262
|
gat: makeGenerator('gat'),
|
|
206
263
|
at: function(i){
|
|
@@ -272,15 +329,31 @@ object.Mixin('GeneratorMixin', 'soft', {
|
|
|
272
329
|
e(...args)
|
|
273
330
|
: e }) }),
|
|
274
331
|
//zip: makeGenerator('zip'),
|
|
332
|
+
|
|
333
|
+
enumerate: makeGenerator('enumerate'),
|
|
275
334
|
})
|
|
276
335
|
|
|
277
336
|
|
|
278
337
|
var GeneratorProtoMixin =
|
|
279
338
|
module.GeneratorProtoMixin =
|
|
280
339
|
object.Mixin('GeneratorProtoMixin', 'soft', {
|
|
281
|
-
//
|
|
282
|
-
iter: function*(){
|
|
283
|
-
|
|
340
|
+
// XXX use module.iter(..) ???
|
|
341
|
+
iter: stoppable(function*(handler){
|
|
342
|
+
if(handler){
|
|
343
|
+
var i = 0
|
|
344
|
+
for(var elem of this){
|
|
345
|
+
var res = handler.call(this, elem, i)
|
|
346
|
+
// expand iterables...
|
|
347
|
+
if(typeof(res) == 'object'
|
|
348
|
+
&& Symbol.iterator in res){
|
|
349
|
+
yield* res
|
|
350
|
+
// as-is...
|
|
351
|
+
} else {
|
|
352
|
+
yield res }}
|
|
353
|
+
// no handler...
|
|
354
|
+
} else {
|
|
355
|
+
yield* this } }),
|
|
356
|
+
//*/
|
|
284
357
|
|
|
285
358
|
at: function(i){
|
|
286
359
|
return this.gat(i).next().value },
|
|
@@ -390,17 +463,19 @@ object.Mixin('GeneratorProtoMixin', 'soft', {
|
|
|
390
463
|
|
|
391
464
|
// promises...
|
|
392
465
|
//
|
|
393
|
-
|
|
394
|
-
promise: function(){
|
|
466
|
+
then: function(onresolve, onreject){
|
|
395
467
|
var that = this
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
468
|
+
var p = new Promise(
|
|
469
|
+
function(resolve){
|
|
470
|
+
resolve([...that]) })
|
|
471
|
+
p = (onresolve || onreject) ?
|
|
472
|
+
p.then(...arguments)
|
|
473
|
+
: p
|
|
474
|
+
return p },
|
|
400
475
|
catch: function(func){
|
|
401
|
-
return this.
|
|
476
|
+
return this.then().catch(func) },
|
|
402
477
|
finally: function(func){
|
|
403
|
-
return this.
|
|
478
|
+
return this.then().finally(func) },
|
|
404
479
|
|
|
405
480
|
// combinators...
|
|
406
481
|
//
|
|
@@ -423,6 +498,11 @@ object.Mixin('GeneratorProtoMixin', 'soft', {
|
|
|
423
498
|
// XXX
|
|
424
499
|
},
|
|
425
500
|
//*/
|
|
501
|
+
|
|
502
|
+
enumerate: function*(){
|
|
503
|
+
var i = 0
|
|
504
|
+
for(var e of this){
|
|
505
|
+
yield [i++, e] } },
|
|
426
506
|
})
|
|
427
507
|
|
|
428
508
|
|
|
@@ -439,36 +519,102 @@ ITERATOR_PROTOTYPES
|
|
|
439
519
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
440
520
|
// XXX EXPERIMENTAL...
|
|
441
521
|
|
|
442
|
-
var makeAsyncGenerator = function(name, pre){
|
|
443
|
-
return function(...args){
|
|
444
|
-
var that = this
|
|
445
|
-
return Object.assign(
|
|
446
|
-
async function*(){
|
|
447
|
-
var a = pre ?
|
|
448
|
-
pre.call(this, args, ...arguments)
|
|
449
|
-
: args
|
|
450
|
-
for await (var e of that(...arguments)[name](...a)){
|
|
451
|
-
yield e } },
|
|
452
|
-
{ toString: function(){
|
|
453
|
-
return [
|
|
454
|
-
that.toString(),
|
|
455
|
-
// XXX need to normalize args better...
|
|
456
|
-
`.${ name }(${ args.join(', ') })`,
|
|
457
|
-
].join('\n ') }, }) } }
|
|
458
|
-
|
|
459
522
|
var AsyncGeneratorMixin =
|
|
460
523
|
module.AsyncGeneratorMixin =
|
|
461
524
|
object.Mixin('AsyncGeneratorMixin', 'soft', {
|
|
462
|
-
|
|
525
|
+
// XXX TEST...
|
|
526
|
+
iter: makeGenerator('async', 'iter'),
|
|
527
|
+
|
|
528
|
+
map: makeGenerator('async', 'map'),
|
|
529
|
+
filter: makeGenerator('async', 'filter'),
|
|
530
|
+
reduce: makeGenerator('async', 'reduce'),
|
|
463
531
|
})
|
|
464
532
|
|
|
465
533
|
var AsyncGeneratorProtoMixin =
|
|
466
534
|
module.AsyncGeneratorProtoMixin =
|
|
467
535
|
object.Mixin('AsyncGeneratorProtoMixin', 'soft', {
|
|
536
|
+
// promise...
|
|
537
|
+
//
|
|
538
|
+
// NOTE: this will unwind the generator...
|
|
539
|
+
// XXX create an iterator promise???
|
|
540
|
+
// XXX should we unwind???
|
|
541
|
+
then: function(resolve, reject){
|
|
542
|
+
var that = this
|
|
543
|
+
var p = new Promise(async function(_resolve, _reject){
|
|
544
|
+
var res = []
|
|
545
|
+
for await(var elem of that){
|
|
546
|
+
res.push(elem) }
|
|
547
|
+
_resolve(res) })
|
|
548
|
+
p = (resolve || reject) ?
|
|
549
|
+
p.then(...arguments)
|
|
550
|
+
: p
|
|
551
|
+
return p },
|
|
552
|
+
catch: function(func){
|
|
553
|
+
return this.then().catch(func) },
|
|
554
|
+
finally: function(){
|
|
555
|
+
return this.then().finally(func) },
|
|
556
|
+
|
|
557
|
+
// XXX might be a good idea to use this approach above...
|
|
558
|
+
iter: stoppable(async function*(handler=undefined){
|
|
559
|
+
var i = 0
|
|
560
|
+
if(handler){
|
|
561
|
+
for await(var e of this){
|
|
562
|
+
var res = handler.call(this, e, i++)
|
|
563
|
+
if(typeof(res) == 'object'
|
|
564
|
+
&& Symbol.iterator in res){
|
|
565
|
+
yield* res
|
|
566
|
+
} else {
|
|
567
|
+
yield res } }
|
|
568
|
+
} else {
|
|
569
|
+
yield* this } }),
|
|
570
|
+
|
|
571
|
+
map: async function*(func){
|
|
572
|
+
yield* this.iter(function(elem, i){
|
|
573
|
+
return [func.call(this, elem, i)] }) },
|
|
574
|
+
filter: async function*(func){
|
|
575
|
+
yield* this.iter(function(elem, i){
|
|
576
|
+
return func.call(this, elem, i) ?
|
|
577
|
+
[elem]
|
|
578
|
+
: [] }) },
|
|
579
|
+
// NOTE: there is not much point in .reduceRight(..) in an async
|
|
580
|
+
// generator as we'll need to fully unwind it then go from the
|
|
581
|
+
// end...
|
|
582
|
+
reduce: async function(func, state){
|
|
583
|
+
this.iter(function(elem, i){
|
|
584
|
+
state = func.call(this, state, elem, i)
|
|
585
|
+
return [] })
|
|
586
|
+
return state },
|
|
587
|
+
|
|
588
|
+
// XXX TEST...
|
|
589
|
+
chain: async function*(...next){
|
|
590
|
+
yield* next
|
|
591
|
+
.reduce(function(cur, next){
|
|
592
|
+
return next(cur) }, this) },
|
|
593
|
+
|
|
594
|
+
flat: async function*(){
|
|
595
|
+
for await(var e of this){
|
|
596
|
+
if(e instanceof Array){
|
|
597
|
+
yield* e
|
|
598
|
+
} else {
|
|
599
|
+
yield e }}},
|
|
600
|
+
|
|
601
|
+
concat: async function*(other){
|
|
602
|
+
yield* this
|
|
603
|
+
yield* other },
|
|
604
|
+
push: async function*(elem){
|
|
605
|
+
yield* this
|
|
606
|
+
yield elem },
|
|
607
|
+
unsift: async function*(elem){
|
|
608
|
+
yield elem
|
|
609
|
+
yield* this },
|
|
610
|
+
|
|
611
|
+
// XXX
|
|
612
|
+
// slice -- not sure if we need this...
|
|
613
|
+
// ...
|
|
468
614
|
})
|
|
469
615
|
|
|
470
|
-
|
|
471
|
-
|
|
616
|
+
AsyncGeneratorMixin(AsyncGeneratorPrototype)
|
|
617
|
+
AsyncGeneratorProtoMixin(AsyncGeneratorPrototype.prototype)
|
|
472
618
|
|
|
473
619
|
|
|
474
620
|
|