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 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
- iter: function*(){
492
- yield* this },
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
- This is here mainly for compatibility with [`<array>`'s `.iter()`](#arrayiter--arrayiter).
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>.promise()`
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>.promise()
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
- #### `<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)`
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(<reject>)
2199
+ <generator>.then(<resolve>)
2177
2200
  -> <promise>
2178
2201
 
2179
2202
  <generator>.finally(<handler>)
2180
2203
  -> <promise>
2181
2204
  ```
2182
- Shorthands to `<generator>.promise().then(..)` / `<generator>.promise().catch(..)` / `<generator>.promise().finally(..)`
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*(lst=[]){
94
- for(var e of lst){
95
- yield e } }
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>, <handler>)
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
- function*(){
147
- var a = pre ?
148
- pre.call(this, args, ...arguments)
149
- : args
150
- yield* that(...arguments)[name](...a) },
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
- // NOTE: this is here for compatibility with Array.iter(..)
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
- // NOTE: this is here for compatibility with [..].iter()
282
- iter: function*(){
283
- yield* this },
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
- // XXX how do we handle reject(..) / .catch(..)???
394
- promise: function(){
466
+ then: function(onresolve, onreject){
395
467
  var that = this
396
- return new Promise(function(resolve){
397
- resolve([...that]) }) },
398
- then: function(func){
399
- return this.promise().then(func) },
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.promise().catch(func) },
476
+ return this.then().catch(func) },
402
477
  finally: function(func){
403
- return this.promise().finally(func) },
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
- map: makeAsyncGenerator('map'),
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
- //AsyncGeneratorMixin(AsyncGeneratorPrototype)
471
- //AsyncGeneratorProtoMixin(AsyncGeneratorPrototype.prototype)
616
+ AsyncGeneratorMixin(AsyncGeneratorPrototype)
617
+ AsyncGeneratorProtoMixin(AsyncGeneratorPrototype.prototype)
472
618
 
473
619
 
474
620
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ig-types",
3
- "version": "6.15.1",
3
+ "version": "6.15.6",
4
4
  "description": "Generic JavaScript types and type extensions...",
5
5
  "main": "main.js",
6
6
  "scripts": {