ig-types 6.15.1 → 6.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Array.js +24 -6
- package/Function.js +18 -0
- package/Promise.js +15 -14
- package/README.md +101 -13
- package/event.js +6 -2
- package/generator.js +200 -88
- package/main.js +3 -0
- package/package.json +3 -2
package/Array.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
/*********************************************************************/
|
|
13
13
|
|
|
14
14
|
var object = require('ig-object')
|
|
15
|
+
var stoppable = require('ig-stoppable')
|
|
15
16
|
|
|
16
17
|
var generator = require('./generator')
|
|
17
18
|
|
|
@@ -22,8 +23,7 @@ var generator = require('./generator')
|
|
|
22
23
|
// NOTE: this is used in a similar fashion to Python's StopIteration...
|
|
23
24
|
var STOP =
|
|
24
25
|
module.STOP =
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
stoppable.STOP
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
//---------------------------------------------------------------------
|
|
@@ -212,8 +212,12 @@ object.Mixin('ArrayMixin', 'soft', {
|
|
|
212
212
|
// done...
|
|
213
213
|
: [] },
|
|
214
214
|
|
|
215
|
-
|
|
216
|
-
|
|
215
|
+
// XXX not sure about the handler API here yet...
|
|
216
|
+
iter: function*(lst=[], handler=undefined){
|
|
217
|
+
yield* lst.iter(
|
|
218
|
+
...(handler ?
|
|
219
|
+
[handler]
|
|
220
|
+
: [])) },
|
|
217
221
|
})
|
|
218
222
|
|
|
219
223
|
|
|
@@ -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/Function.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**********************************************************************
|
|
2
|
+
*
|
|
3
|
+
*
|
|
4
|
+
*
|
|
5
|
+
**********************************************/ /* c8 ignore next 2 */
|
|
6
|
+
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
|
|
7
|
+
(function(require){ var module={} // make module AMD/node compatible...
|
|
8
|
+
/*********************************************************************/
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
var AsyncFunction =
|
|
12
|
+
module.AsyncFunction =
|
|
13
|
+
(async function(){}).constructor
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**********************************************************************
|
|
18
|
+
* vim:set ts=4 sw=4 : */ return module })
|
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){
|
|
@@ -468,6 +464,11 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
468
464
|
every: promiseProxy('every'),
|
|
469
465
|
|
|
470
466
|
|
|
467
|
+
join: async function(){
|
|
468
|
+
return [...(await this)]
|
|
469
|
+
.join(...arguments) },
|
|
470
|
+
|
|
471
|
+
|
|
471
472
|
// this is defined globally as Promise.prototype.iter(..)
|
|
472
473
|
//
|
|
473
474
|
// for details see: PromiseMixin(..) below...
|
package/README.md
CHANGED
|
@@ -13,6 +13,8 @@ Library of JavaScript type extensions, types and utilities.
|
|
|
13
13
|
- [`Object.matchPartial(..)`](#objectmatchpartial)
|
|
14
14
|
- [`<object>.run(..)`](#objectrun)
|
|
15
15
|
- [`Object.sort(..)`](#objectsort)
|
|
16
|
+
- [`Function`](#function)
|
|
17
|
+
- [`func.AsyncFunction`](#funcasyncfunction)
|
|
16
18
|
- [`Array`](#array)
|
|
17
19
|
- [`<array>.first(..)` / `<array>.last(..)`](#arrayfirst--arraylast)
|
|
18
20
|
- [`<array>.rol(..)`](#arrayrol)
|
|
@@ -78,6 +80,7 @@ Library of JavaScript type extensions, types and utilities.
|
|
|
78
80
|
- [`<promise-iter>.concat(..)`](#promise-iterconcat)
|
|
79
81
|
- [`<promise-iter>.push(..)` / `<promise-iter>.unshift(..)`](#promise-iterpush--promise-iterunshift)
|
|
80
82
|
- [`<promise-iter>.at(..)` / `<promise-iter>.first()` / `<promise-iter>.last()`](#promise-iterat--promise-iterfirst--promise-iterlast)
|
|
83
|
+
- [`<promise-iter>.join(..)`](#promise-iterjoin)
|
|
81
84
|
- [`<promise-iter>.some(..)` / `<promise-iter>.find(..)`](#promise-itersome--promise-iterfind)
|
|
82
85
|
- [Array proxy methods returning `<promise-iter>`](#array-proxy-methods-returning-promise-iter)
|
|
83
86
|
- [Array proxy methods returning a `<promise>`](#array-proxy-methods-returning-a-promise)
|
|
@@ -94,7 +97,7 @@ Library of JavaScript type extensions, types and utilities.
|
|
|
94
97
|
- [`generator.iter(..)`](#generatoriter)
|
|
95
98
|
- [`generator.STOP`](#generatorstop)
|
|
96
99
|
- [Generator instance iteration](#generator-instance-iteration)
|
|
97
|
-
- [`<generator>.iter()`](#generatoriter-1)
|
|
100
|
+
- [`<generator>.iter(..)`](#generatoriter-1)
|
|
98
101
|
- [`<generator>.map(..)` / `<generator>.filter(..)`](#generatormap--generatorfilter)
|
|
99
102
|
- [`<generator>.reduce(..)` / `<generator>.greduce(..)`](#generatorreduce--generatorgreduce)
|
|
100
103
|
- [`<generator>.slice(..)`](#generatorslice)
|
|
@@ -102,7 +105,7 @@ Library of JavaScript type extensions, types and utilities.
|
|
|
102
105
|
- [`<generator>.flat(..)`](#generatorflat)
|
|
103
106
|
- [`<generator>.shift()` / `<generator>.pop()` / `<generator>.gshift()` / `<generator>.gpop()`](#generatorshift--generatorpop--generatorgshift--generatorgpop)
|
|
104
107
|
- [`<generator>.unshift(..)` / `<generator>.push(..)`](#generatorunshift--generatorpush)
|
|
105
|
-
- [`<generator>.
|
|
108
|
+
- [`<generator>.join(..)`](#generatorjoin)
|
|
106
109
|
- [`<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)`](#generatorthen--generatorcatch--generatorfinally)
|
|
107
110
|
- [`<generator>.toArray()`](#generatortoarray)
|
|
108
111
|
- [Treating iterators the same as generators](#treating-iterators-the-same-as-generators)
|
|
@@ -114,6 +117,7 @@ Library of JavaScript type extensions, types and utilities.
|
|
|
114
117
|
- [`<Generator>.slice(..)`](#generatorslice-1)
|
|
115
118
|
- [`<Generator>.map(..)` / `<Generator>.filter(..)` / `<Generator>.reduce(..)` / `<Generator>.flat()`](#generatormap--generatorfilter--generatorreduce--generatorflat)
|
|
116
119
|
- [`<Generator>.toArray()`](#generatortoarray-1)
|
|
120
|
+
- [`<Generator>.join(..)`](#generatorjoin-1)
|
|
117
121
|
- [`<Generator>.then(..)` / `<Generator>.catch(..)` / `<Generator>.finally(..)`](#generatorthen--generatorcatch--generatorfinally-1)
|
|
118
122
|
- [Generator combinators](#generator-combinators)
|
|
119
123
|
- [`<Generator>.chain(..)` / `<generator>.chain(..)`](#generatorchain--generatorchain)
|
|
@@ -124,6 +128,15 @@ Library of JavaScript type extensions, types and utilities.
|
|
|
124
128
|
- [`generator.produce(..)`](#generatorproduce)
|
|
125
129
|
- [Generator helpers](#generator-helpers)
|
|
126
130
|
- [`generator.stoppable(..)`](#generatorstoppable)
|
|
131
|
+
- [Async generator extensions](#async-generator-extensions)
|
|
132
|
+
- [`generator.AsyncGenerator`](#generatorasyncgenerator)
|
|
133
|
+
- [`<async-generator>.then(..)` / `<async-generator>.catch(..)` / `<async-generator>.finally(..)`](#async-generatorthen--async-generatorcatch--async-generatorfinally)
|
|
134
|
+
- [`<async-generator>.iter(..)`](#async-generatoriter)
|
|
135
|
+
- [`<async-generator>.map(..)` / `<async-generator>.filter(..)` / `<async-generator>.reduce(..)`](#async-generatormap--async-generatorfilter--async-generatorreduce)
|
|
136
|
+
- [`<async-generator>.chain(..)`](#async-generatorchain)
|
|
137
|
+
- [`<async-generator>.flat(..)`](#async-generatorflat)
|
|
138
|
+
- [`<async-generator>.concat(..)`](#async-generatorconcat)
|
|
139
|
+
- [`<async-generator>.push(..)` / `<async-generator>.unshift(..)`](#async-generatorpush--async-generatorunshift)
|
|
127
140
|
- [Containers](#containers)
|
|
128
141
|
- [`containers.UniqueKeyMap()` (`Map`)](#containersuniquekeymap-map)
|
|
129
142
|
- [`<unique-key-map>.set(..)`](#unique-key-mapset)
|
|
@@ -446,6 +459,30 @@ Object.keys(Object.sort(o, ['x', 'a', '100']))
|
|
|
446
459
|
This is similar to [`<map>.sort(..)`](#mapsort) and [`<ser>.sort(..)`](#setsort).
|
|
447
460
|
|
|
448
461
|
|
|
462
|
+
## `Function`
|
|
463
|
+
|
|
464
|
+
```javascript
|
|
465
|
+
var func = require('ig-types/Function')
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### `func.AsyncFunction`
|
|
469
|
+
|
|
470
|
+
The async function constructor.
|
|
471
|
+
|
|
472
|
+
This enables us to test if an object is an instance of an async function.
|
|
473
|
+
|
|
474
|
+
```javascript
|
|
475
|
+
var a = async function(){
|
|
476
|
+
// ...
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
a instanceof func.AsyncFunction // -> true
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
This is hidden by JavaScript by default.
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
|
|
449
486
|
## `Array`
|
|
450
487
|
|
|
451
488
|
```javascript
|
|
@@ -1677,6 +1714,12 @@ parent `<promise-iter>`.
|
|
|
1677
1714
|
|
|
1678
1715
|
XXX
|
|
1679
1716
|
|
|
1717
|
+
|
|
1718
|
+
#### `<promise-iter>.join(..)`
|
|
1719
|
+
|
|
1720
|
+
XXX
|
|
1721
|
+
|
|
1722
|
+
|
|
1680
1723
|
#### `<promise-iter>.some(..)` / `<promise-iter>.find(..)`
|
|
1681
1724
|
|
|
1682
1725
|
```bnf
|
|
@@ -2023,7 +2066,7 @@ Chained generators handle items depth-first, i.e. the items are passed as they
|
|
|
2023
2066
|
are yielded down the generator chain.
|
|
2024
2067
|
|
|
2025
2068
|
|
|
2026
|
-
#### `<generator>.iter()`
|
|
2069
|
+
#### `<generator>.iter(..)`
|
|
2027
2070
|
|
|
2028
2071
|
Iterate over the generator.
|
|
2029
2072
|
```bnf
|
|
@@ -2031,7 +2074,24 @@ Iterate over the generator.
|
|
|
2031
2074
|
-> <generator>
|
|
2032
2075
|
```
|
|
2033
2076
|
|
|
2034
|
-
|
|
2077
|
+
XXX move this to `generator.iter(..)`
|
|
2078
|
+
|
|
2079
|
+
Compatible with [`<array>`'s `.iter()`](#arrayiter--arrayiter).
|
|
2080
|
+
|
|
2081
|
+
`.iter(..)` also supports a handler function
|
|
2082
|
+
```bnf
|
|
2083
|
+
<generator>.iter(<handler>)
|
|
2084
|
+
-> <generator>
|
|
2085
|
+
|
|
2086
|
+
|
|
2087
|
+
<handler>(<elem>, <index>)
|
|
2088
|
+
-> <elem>
|
|
2089
|
+
-> [<elem>, ..]
|
|
2090
|
+
-> []
|
|
2091
|
+
```
|
|
2092
|
+
|
|
2093
|
+
Note that the iterables returned by `<handler>(..)` will be expanded, to prevent
|
|
2094
|
+
this wrap them in an array.
|
|
2035
2095
|
|
|
2036
2096
|
|
|
2037
2097
|
#### `<generator>.map(..)` / `<generator>.filter(..)`
|
|
@@ -2156,30 +2216,34 @@ Value added by `.unshift(..)` will be yielded by `<generator>` "first", i.e. on
|
|
|
2156
2216
|
_next_ call to `.next()`, regardless of the current generator state.
|
|
2157
2217
|
|
|
2158
2218
|
|
|
2159
|
-
#### `<generator>.
|
|
2219
|
+
#### `<generator>.join(..)`
|
|
2220
|
+
|
|
2221
|
+
XXX
|
|
2222
|
+
|
|
2223
|
+
|
|
2224
|
+
#### `<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)`
|
|
2225
|
+
|
|
2226
|
+
Return a promise and resolve it with the generator value.
|
|
2160
2227
|
|
|
2161
2228
|
```bnf
|
|
2162
|
-
<generator>.
|
|
2229
|
+
<generator>.then()
|
|
2163
2230
|
-> <promise>
|
|
2164
2231
|
```
|
|
2165
|
-
Return a promise and resolve it with the generator value.
|
|
2166
|
-
|
|
2167
|
-
Note that this will deplete the generator.
|
|
2168
2232
|
|
|
2169
|
-
|
|
2170
|
-
#### `<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)`
|
|
2233
|
+
Adding handlers to the promise
|
|
2171
2234
|
|
|
2172
2235
|
```bnf
|
|
2173
2236
|
<generator>.then(<resolve>, <reject>)
|
|
2174
2237
|
-> <promise>
|
|
2175
2238
|
|
|
2176
|
-
<generator>.then(<
|
|
2239
|
+
<generator>.then(<resolve>)
|
|
2177
2240
|
-> <promise>
|
|
2178
2241
|
|
|
2179
2242
|
<generator>.finally(<handler>)
|
|
2180
2243
|
-> <promise>
|
|
2181
2244
|
```
|
|
2182
|
-
|
|
2245
|
+
|
|
2246
|
+
Note that this will deplete the generator.
|
|
2183
2247
|
|
|
2184
2248
|
These are the same as equivalent `Promise` methods, for more info see:
|
|
2185
2249
|
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
|
|
@@ -2360,6 +2424,10 @@ Return a function that will return a `<generator>` output as an `Array`.
|
|
|
2360
2424
|
-> <function>
|
|
2361
2425
|
```
|
|
2362
2426
|
|
|
2427
|
+
#### `<Generator>.join(..)`
|
|
2428
|
+
|
|
2429
|
+
XXX
|
|
2430
|
+
|
|
2363
2431
|
|
|
2364
2432
|
#### `<Generator>.then(..)` / `<Generator>.catch(..)` / `<Generator>.finally(..)`
|
|
2365
2433
|
|
|
@@ -2483,6 +2551,26 @@ stoppable(<generator>)
|
|
|
2483
2551
|
|
|
2484
2552
|
<!-- XXX example? -->
|
|
2485
2553
|
|
|
2554
|
+
## Async generator extensions
|
|
2555
|
+
|
|
2556
|
+
XXX EXPERIMENTAL
|
|
2557
|
+
|
|
2558
|
+
#### `generator.AsyncGenerator`
|
|
2559
|
+
|
|
2560
|
+
#### `<async-generator>.then(..)` / `<async-generator>.catch(..)` / `<async-generator>.finally(..)`
|
|
2561
|
+
|
|
2562
|
+
#### `<async-generator>.iter(..)`
|
|
2563
|
+
|
|
2564
|
+
#### `<async-generator>.map(..)` / `<async-generator>.filter(..)` / `<async-generator>.reduce(..)`
|
|
2565
|
+
|
|
2566
|
+
#### `<async-generator>.chain(..)`
|
|
2567
|
+
|
|
2568
|
+
#### `<async-generator>.flat(..)`
|
|
2569
|
+
|
|
2570
|
+
#### `<async-generator>.concat(..)`
|
|
2571
|
+
|
|
2572
|
+
#### `<async-generator>.push(..)` / `<async-generator>.unshift(..)`
|
|
2573
|
+
|
|
2486
2574
|
|
|
2487
2575
|
|
|
2488
2576
|
## Containers
|
package/event.js
CHANGED
|
@@ -120,6 +120,8 @@ object.Constructor('Eventful', {
|
|
|
120
120
|
Object.defineProperty(context, '__event_handlers__', {
|
|
121
121
|
value: {[this.name]: (handlers = [])},
|
|
122
122
|
enumerable: false,
|
|
123
|
+
configurable: true,
|
|
124
|
+
writable: true,
|
|
123
125
|
})
|
|
124
126
|
&& handlers
|
|
125
127
|
: (context.__event_handlers__[this.name] =
|
|
@@ -293,6 +295,8 @@ module.EventHandlerMixin = object.Mixin('EventHandlerMixin', {
|
|
|
293
295
|
&& Object.defineProperty(this, '__event_handlers__', {
|
|
294
296
|
value: {},
|
|
295
297
|
enumerable: false,
|
|
298
|
+
configurable: true,
|
|
299
|
+
writable: true,
|
|
296
300
|
})
|
|
297
301
|
;(this.__event_handlers__[evt] =
|
|
298
302
|
this.__event_handlers__[evt] || [])
|
|
@@ -343,14 +347,14 @@ module.EventDocMixin = object.Mixin('EventDocMixin', {
|
|
|
343
347
|
return object.deepKeys(this)
|
|
344
348
|
.filter(function(n){
|
|
345
349
|
// avoid triggering props...
|
|
346
|
-
return !object.values(this, n,
|
|
350
|
+
return !object.values(this, n, true).next().value.get
|
|
347
351
|
// XXX this is too strict...
|
|
348
352
|
&& (this[n] || {}).constructor === Eventful}.bind(this)) },
|
|
349
353
|
get events(){
|
|
350
354
|
return object.deepKeys(this)
|
|
351
355
|
.filter(function(n){
|
|
352
356
|
// avoid triggering props...
|
|
353
|
-
return !object.values(this, n,
|
|
357
|
+
return !object.values(this, n, true).next().value.get
|
|
354
358
|
// XXX this is too strict...
|
|
355
359
|
&& (this[n] || {}).constructor === Event }.bind(this)) },
|
|
356
360
|
})
|
package/generator.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
/*********************************************************************/
|
|
9
9
|
|
|
10
10
|
var object = require('ig-object')
|
|
11
|
+
var stoppable = require('ig-stoppable')
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
|
|
@@ -16,7 +17,7 @@ var object = require('ig-object')
|
|
|
16
17
|
// NOTE: this is used in a similar fashion to Python's StopIteration...
|
|
17
18
|
var STOP =
|
|
18
19
|
module.STOP =
|
|
19
|
-
|
|
20
|
+
stoppable.STOP
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
//---------------------------------------------------------------------
|
|
@@ -38,11 +39,11 @@ module.STOP =
|
|
|
38
39
|
// of each of them.
|
|
39
40
|
// So, below we will define:
|
|
40
41
|
//
|
|
41
|
-
//
|
|
42
|
+
// Generator.prototype
|
|
42
43
|
// prototype of the generator constructors (i.e. Iter(..) from the
|
|
43
44
|
// above example)
|
|
44
45
|
//
|
|
45
|
-
//
|
|
46
|
+
// Generator.prototype.prototype
|
|
46
47
|
// generator instance prototype (i.e. iter for the above code)
|
|
47
48
|
//
|
|
48
49
|
//
|
|
@@ -58,17 +59,10 @@ module.STOP =
|
|
|
58
59
|
//
|
|
59
60
|
//---------------------------------------------------------------------
|
|
60
61
|
|
|
61
|
-
var GeneratorPrototype =
|
|
62
|
-
(function*(){}).constructor.prototype
|
|
63
|
-
|
|
64
62
|
var Generator =
|
|
65
63
|
module.Generator =
|
|
66
64
|
(function*(){}).constructor
|
|
67
65
|
|
|
68
|
-
|
|
69
|
-
var AsyncGeneratorPrototype =
|
|
70
|
-
(async function*(){}).constructor.prototype
|
|
71
|
-
|
|
72
66
|
var AsyncGenerator =
|
|
73
67
|
module.AsyncGenerator =
|
|
74
68
|
(async function*(){}).constructor
|
|
@@ -85,19 +79,44 @@ var ITERATOR_PROTOTYPES = [
|
|
|
85
79
|
|
|
86
80
|
|
|
87
81
|
//---------------------------------------------------------------------
|
|
88
|
-
|
|
89
82
|
// generic generator wrapper...
|
|
83
|
+
|
|
84
|
+
// helper...
|
|
85
|
+
var __iter =
|
|
86
|
+
module.__iter =
|
|
87
|
+
function*(lst=[]){
|
|
88
|
+
if(typeof(lst) == 'object'
|
|
89
|
+
&& Symbol.iterator in lst){
|
|
90
|
+
yield* lst
|
|
91
|
+
} else {
|
|
92
|
+
yield lst } }
|
|
93
|
+
|
|
94
|
+
// XXX updatae Array.js' version for compatibility...
|
|
95
|
+
// XXX DOCS!!!
|
|
90
96
|
var iter =
|
|
91
97
|
module.iter =
|
|
92
98
|
Generator.iter =
|
|
93
|
-
function
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
stoppable(function(lst=[]){
|
|
100
|
+
// handler -> generator-constructor...
|
|
101
|
+
if(typeof(lst) == 'function'){
|
|
102
|
+
// we need to be callable...
|
|
103
|
+
var that = this instanceof Function ?
|
|
104
|
+
this
|
|
105
|
+
// generic root generator...
|
|
106
|
+
: module.__iter
|
|
107
|
+
return function*(){
|
|
108
|
+
yield* that(...arguments).iter(lst) } }
|
|
109
|
+
// no handler -> generator instance...
|
|
110
|
+
return module.__iter(lst) })
|
|
111
|
+
|
|
112
|
+
// NOTE: we need .iter(..) to both return generators if passed an iterable
|
|
113
|
+
// and genereator constructos if passed a function...
|
|
114
|
+
iter.__proto__ = Generator.prototype
|
|
96
115
|
|
|
97
116
|
|
|
98
117
|
|
|
99
118
|
//---------------------------------------------------------------------
|
|
100
|
-
//
|
|
119
|
+
// Generator.prototype "class" methods...
|
|
101
120
|
//
|
|
102
121
|
// the following are effectively the same:
|
|
103
122
|
// 1) Wrapper
|
|
@@ -121,9 +140,11 @@ Generator.iter =
|
|
|
121
140
|
|
|
122
141
|
//
|
|
123
142
|
// makeGenerator(<name>)
|
|
143
|
+
// makeGenerator(<name>, <handler>)
|
|
124
144
|
// -> <func>
|
|
125
145
|
//
|
|
126
|
-
// makeGenerator(<name
|
|
146
|
+
// makeGenerator('async', <name>)
|
|
147
|
+
// makeGenerator('async', <name>, <handler>)
|
|
127
148
|
// -> <func>
|
|
128
149
|
//
|
|
129
150
|
//
|
|
@@ -140,14 +161,26 @@ Generator.iter =
|
|
|
140
161
|
// XXX this needs to be of the correct type... (???)
|
|
141
162
|
// XXX need to accept generators as handlers...
|
|
142
163
|
var makeGenerator = function(name, pre){
|
|
164
|
+
var sync = true
|
|
165
|
+
if(name == 'async'){
|
|
166
|
+
sync = false
|
|
167
|
+
var [name, pre] = [...arguments].slice(1) }
|
|
143
168
|
return function(...args){
|
|
144
169
|
var that = this
|
|
145
170
|
return Object.assign(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
171
|
+
// NOTE: the two branches here are identical, the only
|
|
172
|
+
// difference is the async keyword...
|
|
173
|
+
sync ?
|
|
174
|
+
function*(){
|
|
175
|
+
var a = pre ?
|
|
176
|
+
pre.call(this, args, ...arguments)
|
|
177
|
+
: args
|
|
178
|
+
yield* that(...arguments)[name](...a) }
|
|
179
|
+
: async function*(){
|
|
180
|
+
var a = pre ?
|
|
181
|
+
pre.call(this, args, ...arguments)
|
|
182
|
+
: args
|
|
183
|
+
yield* that(...arguments)[name](...a) },
|
|
151
184
|
{ toString: function(){
|
|
152
185
|
return [
|
|
153
186
|
that.toString(),
|
|
@@ -163,34 +196,6 @@ var makePromise = function(name){
|
|
|
163
196
|
return that(...arguments)[name](func) } } }
|
|
164
197
|
|
|
165
198
|
|
|
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
199
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
195
200
|
|
|
196
201
|
var GeneratorMixin =
|
|
@@ -198,9 +203,7 @@ module.GeneratorMixin =
|
|
|
198
203
|
object.Mixin('GeneratorMixin', 'soft', {
|
|
199
204
|
STOP: object.STOP,
|
|
200
205
|
|
|
201
|
-
|
|
202
|
-
iter: function*(lst=[]){
|
|
203
|
-
yield* module.iter(lst) },
|
|
206
|
+
iter: module.iter,
|
|
204
207
|
|
|
205
208
|
gat: makeGenerator('gat'),
|
|
206
209
|
at: function(i){
|
|
@@ -229,7 +232,7 @@ object.Mixin('GeneratorMixin', 'soft', {
|
|
|
229
232
|
return that(...arguments).toArray() },
|
|
230
233
|
{ toString: function(){
|
|
231
234
|
return that.toString()
|
|
232
|
-
+ '\n .
|
|
235
|
+
+ '\n .toArray()'}, }) },
|
|
233
236
|
gpop: makeGenerator('gpop'),
|
|
234
237
|
pop: function(){
|
|
235
238
|
var that = this
|
|
@@ -239,7 +242,7 @@ object.Mixin('GeneratorMixin', 'soft', {
|
|
|
239
242
|
return that(...arguments).pop() },
|
|
240
243
|
{ toString: function(){
|
|
241
244
|
return that.toString()
|
|
242
|
-
+ '\n .
|
|
245
|
+
+ '\n .pop()'}, }) },
|
|
243
246
|
push: makeGenerator('push'),
|
|
244
247
|
gshift: makeGenerator('gshift'),
|
|
245
248
|
shift: function(){
|
|
@@ -250,7 +253,7 @@ object.Mixin('GeneratorMixin', 'soft', {
|
|
|
250
253
|
return that(...arguments).shift() },
|
|
251
254
|
{ toString: function(){
|
|
252
255
|
return that.toString()
|
|
253
|
-
+ '\n .
|
|
256
|
+
+ '\n .shift()'}, }) },
|
|
254
257
|
unshift: makeGenerator('unshift'),
|
|
255
258
|
|
|
256
259
|
// promises...
|
|
@@ -272,15 +275,43 @@ object.Mixin('GeneratorMixin', 'soft', {
|
|
|
272
275
|
e(...args)
|
|
273
276
|
: e }) }),
|
|
274
277
|
//zip: makeGenerator('zip'),
|
|
278
|
+
|
|
279
|
+
enumerate: makeGenerator('enumerate'),
|
|
280
|
+
|
|
281
|
+
// XXX should this have a .gjoin(..) companion...
|
|
282
|
+
join: function(){
|
|
283
|
+
var args = [...arguments]
|
|
284
|
+
var that = this
|
|
285
|
+
return Object.assign(
|
|
286
|
+
function(){
|
|
287
|
+
//return that(...arguments).toArray().shift() },
|
|
288
|
+
return that(...arguments).join(...args) },
|
|
289
|
+
{ toString: function(){
|
|
290
|
+
return that.toString()
|
|
291
|
+
+ '\n .join()'}, }) },
|
|
275
292
|
})
|
|
276
293
|
|
|
277
294
|
|
|
278
295
|
var GeneratorProtoMixin =
|
|
279
296
|
module.GeneratorProtoMixin =
|
|
280
297
|
object.Mixin('GeneratorProtoMixin', 'soft', {
|
|
281
|
-
//
|
|
282
|
-
iter: function*(){
|
|
283
|
-
|
|
298
|
+
// XXX use module.iter(..) ???
|
|
299
|
+
iter: stoppable(function*(handler){
|
|
300
|
+
if(handler){
|
|
301
|
+
var i = 0
|
|
302
|
+
for(var elem of this){
|
|
303
|
+
var res = handler.call(this, elem, i)
|
|
304
|
+
// expand iterables...
|
|
305
|
+
if(typeof(res) == 'object'
|
|
306
|
+
&& Symbol.iterator in res){
|
|
307
|
+
yield* res
|
|
308
|
+
// as-is...
|
|
309
|
+
} else {
|
|
310
|
+
yield res }}
|
|
311
|
+
// no handler...
|
|
312
|
+
} else {
|
|
313
|
+
yield* this } }),
|
|
314
|
+
//*/
|
|
284
315
|
|
|
285
316
|
at: function(i){
|
|
286
317
|
return this.gat(i).next().value },
|
|
@@ -390,17 +421,19 @@ object.Mixin('GeneratorProtoMixin', 'soft', {
|
|
|
390
421
|
|
|
391
422
|
// promises...
|
|
392
423
|
//
|
|
393
|
-
|
|
394
|
-
promise: function(){
|
|
424
|
+
then: function(onresolve, onreject){
|
|
395
425
|
var that = this
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
426
|
+
var p = new Promise(
|
|
427
|
+
function(resolve){
|
|
428
|
+
resolve([...that]) })
|
|
429
|
+
p = (onresolve || onreject) ?
|
|
430
|
+
p.then(...arguments)
|
|
431
|
+
: p
|
|
432
|
+
return p },
|
|
400
433
|
catch: function(func){
|
|
401
|
-
return this.
|
|
434
|
+
return this.then().catch(func) },
|
|
402
435
|
finally: function(func){
|
|
403
|
-
return this.
|
|
436
|
+
return this.then().finally(func) },
|
|
404
437
|
|
|
405
438
|
// combinators...
|
|
406
439
|
//
|
|
@@ -423,11 +456,20 @@ object.Mixin('GeneratorProtoMixin', 'soft', {
|
|
|
423
456
|
// XXX
|
|
424
457
|
},
|
|
425
458
|
//*/
|
|
459
|
+
|
|
460
|
+
enumerate: function*(){
|
|
461
|
+
var i = 0
|
|
462
|
+
for(var e of this){
|
|
463
|
+
yield [i++, e] } },
|
|
464
|
+
|
|
465
|
+
join: function(){
|
|
466
|
+
return [...this]
|
|
467
|
+
.join(...arguments) },
|
|
426
468
|
})
|
|
427
469
|
|
|
428
470
|
|
|
429
|
-
GeneratorMixin(
|
|
430
|
-
GeneratorProtoMixin(
|
|
471
|
+
GeneratorMixin(Generator.prototype)
|
|
472
|
+
GeneratorProtoMixin(Generator.prototype.prototype)
|
|
431
473
|
|
|
432
474
|
|
|
433
475
|
// Extend base iterators...
|
|
@@ -439,36 +481,106 @@ ITERATOR_PROTOTYPES
|
|
|
439
481
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
440
482
|
// XXX EXPERIMENTAL...
|
|
441
483
|
|
|
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
484
|
var AsyncGeneratorMixin =
|
|
460
485
|
module.AsyncGeneratorMixin =
|
|
461
486
|
object.Mixin('AsyncGeneratorMixin', 'soft', {
|
|
462
|
-
|
|
487
|
+
// XXX TEST...
|
|
488
|
+
iter: makeGenerator('async', 'iter'),
|
|
489
|
+
|
|
490
|
+
map: makeGenerator('async', 'map'),
|
|
491
|
+
filter: makeGenerator('async', 'filter'),
|
|
492
|
+
reduce: makeGenerator('async', 'reduce'),
|
|
463
493
|
})
|
|
464
494
|
|
|
465
495
|
var AsyncGeneratorProtoMixin =
|
|
466
496
|
module.AsyncGeneratorProtoMixin =
|
|
467
497
|
object.Mixin('AsyncGeneratorProtoMixin', 'soft', {
|
|
498
|
+
// promise...
|
|
499
|
+
//
|
|
500
|
+
// NOTE: this will unwind the generator...
|
|
501
|
+
// XXX create an iterator promise???
|
|
502
|
+
// XXX should we unwind???
|
|
503
|
+
then: function(resolve, reject){
|
|
504
|
+
var that = this
|
|
505
|
+
var p = new Promise(async function(_resolve, _reject){
|
|
506
|
+
var res = []
|
|
507
|
+
for await(var elem of that){
|
|
508
|
+
res.push(elem) }
|
|
509
|
+
_resolve(res) })
|
|
510
|
+
p = (resolve || reject) ?
|
|
511
|
+
p.then(...arguments)
|
|
512
|
+
: p
|
|
513
|
+
return p },
|
|
514
|
+
catch: function(func){
|
|
515
|
+
return this.then().catch(func) },
|
|
516
|
+
finally: function(){
|
|
517
|
+
return this.then().finally(func) },
|
|
518
|
+
|
|
519
|
+
// XXX might be a good idea to use this approach above...
|
|
520
|
+
iter: stoppable(async function*(handler=undefined){
|
|
521
|
+
var i = 0
|
|
522
|
+
if(handler){
|
|
523
|
+
for await(var e of this){
|
|
524
|
+
var res = handler.call(this, e, i++)
|
|
525
|
+
if(typeof(res) == 'object'
|
|
526
|
+
&& Symbol.iterator in res){
|
|
527
|
+
yield* res
|
|
528
|
+
} else {
|
|
529
|
+
yield res } }
|
|
530
|
+
} else {
|
|
531
|
+
yield* this } }),
|
|
532
|
+
|
|
533
|
+
map: async function*(func){
|
|
534
|
+
yield* this.iter(function(elem, i){
|
|
535
|
+
return [func.call(this, elem, i)] }) },
|
|
536
|
+
filter: async function*(func){
|
|
537
|
+
yield* this.iter(function(elem, i){
|
|
538
|
+
return func.call(this, elem, i) ?
|
|
539
|
+
[elem]
|
|
540
|
+
: [] }) },
|
|
541
|
+
// NOTE: there is not much point in .reduceRight(..) in an async
|
|
542
|
+
// generator as we'll need to fully unwind it then go from the
|
|
543
|
+
// end...
|
|
544
|
+
reduce: async function(func, state){
|
|
545
|
+
this.iter(function(elem, i){
|
|
546
|
+
state = func.call(this, state, elem, i)
|
|
547
|
+
return [] })
|
|
548
|
+
return state },
|
|
549
|
+
|
|
550
|
+
// XXX TEST...
|
|
551
|
+
chain: async function*(...next){
|
|
552
|
+
yield* next
|
|
553
|
+
.reduce(function(cur, next){
|
|
554
|
+
return next(cur) }, this) },
|
|
555
|
+
|
|
556
|
+
flat: async function*(){
|
|
557
|
+
for await(var e of this){
|
|
558
|
+
if(e instanceof Array){
|
|
559
|
+
yield* e
|
|
560
|
+
} else {
|
|
561
|
+
yield e }}},
|
|
562
|
+
|
|
563
|
+
concat: async function*(other){
|
|
564
|
+
yield* this
|
|
565
|
+
yield* other },
|
|
566
|
+
push: async function*(elem){
|
|
567
|
+
yield* this
|
|
568
|
+
yield elem },
|
|
569
|
+
unsift: async function*(elem){
|
|
570
|
+
yield elem
|
|
571
|
+
yield* this },
|
|
572
|
+
|
|
573
|
+
join: async function(){
|
|
574
|
+
return [...(await this)]
|
|
575
|
+
.join(...arguments) },
|
|
576
|
+
|
|
577
|
+
// XXX
|
|
578
|
+
// slice -- not sure if we need this...
|
|
579
|
+
// ...
|
|
468
580
|
})
|
|
469
581
|
|
|
470
|
-
|
|
471
|
-
|
|
582
|
+
AsyncGeneratorMixin(AsyncGenerator.prototype)
|
|
583
|
+
AsyncGeneratorProtoMixin(AsyncGenerator.prototype.prototype)
|
|
472
584
|
|
|
473
585
|
|
|
474
586
|
|
package/main.js
CHANGED
|
@@ -22,6 +22,7 @@ module.patchDate = require('./Date').patchDate
|
|
|
22
22
|
|
|
23
23
|
// Additional types...
|
|
24
24
|
module.containers = require('./containers')
|
|
25
|
+
module.func = require('./Function')
|
|
25
26
|
module.generator = require('./generator')
|
|
26
27
|
module.event = require('./event')
|
|
27
28
|
module.runner = require('./runner')
|
|
@@ -31,7 +32,9 @@ module.runner = require('./runner')
|
|
|
31
32
|
module.STOP = object.STOP
|
|
32
33
|
|
|
33
34
|
// frequently used stuff...
|
|
35
|
+
module.AsyncFunction = module.func.AsyncFunction
|
|
34
36
|
module.Generator = module.generator.Generator
|
|
37
|
+
module.AsyncGenerator = module.generator.AsyncGenerator
|
|
35
38
|
// XXX doc...
|
|
36
39
|
module.iter = module.generator.iter
|
|
37
40
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ig-types",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.16.1",
|
|
4
4
|
"description": "Generic JavaScript types and type extensions...",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"scripts": {
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
},
|
|
24
24
|
"homepage": "https://github.com/flynx/types.js#readme",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"ig-object": "^
|
|
26
|
+
"ig-object": "^6.0.0",
|
|
27
|
+
"ig-stoppable": "^2.0.0",
|
|
27
28
|
"object-run": "^1.0.1"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|