ig-types 6.24.10 → 6.24.12

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/README.md CHANGED
@@ -758,8 +758,26 @@ Resulting array length is strictly equal to the longest input array length.
758
758
 
759
759
  Return an iterator/generator from the current array.
760
760
 
761
+ ```bnf
762
+ <array>.iter()
763
+ <array>.iter(<func>)
764
+ <array>.iter(<func>, <onstop>)
765
+ -> <generator>
766
+
767
+ <func>(<elem>, <index>)
768
+ -> <value>
769
+
770
+ <onstop>(STOP, ...<args>)
771
+ <onstop>(<value>, ...<args>)
772
+ ```
773
+
761
774
  This is mostly useful in combination with the [Generator extensions and utilities](#generator-extensions-and-utilities)
762
775
 
776
+ Note that all stoppable functions/iterators support `<onstop>` callback as
777
+ the last argument.
778
+
779
+ <!-- XXX document <onstop> in all applicable functions -->
780
+
763
781
 
764
782
  ### `<array>.between(..)`
765
783
 
@@ -820,6 +838,9 @@ a supporting iterator method will abort further execution and correctly exit.
820
838
  Like `Array`'s `.map(..)`, `.filter(..)`, `.reduce(..)` and `.forEach(..)` but
821
839
  with added support for aborting iteration by throwing `STOP` or `STOP(<value>)`.
822
840
 
841
+ These can be passed a `<onstop>` callback as an additional last argument
842
+ that will be called if `STOP`/`STOP(<value>)` is returned or thrown.
843
+
823
844
 
824
845
  ### Large `Array` iteration (chunked)
825
846
 
@@ -2117,6 +2138,9 @@ Note that if the last `<value>` is a function and no `<onerror>` function
2117
2138
  is given then `.awaitOrRun(..)` will confuse the `<value>` for `<func>`,
2118
2139
  to avoid this one needs to explicitly pass `null`/`undefined` as `<onerror>`.
2119
2140
 
2141
+ _Special-case: this will expand async generators if they define `.then(..)`,
2142
+ this may change in the future._
2143
+
2120
2144
 
2121
2145
  ## Generator extensions and utilities
2122
2146
 
@@ -2301,6 +2325,10 @@ var L = [1,2,3,4,5]
2301
2325
  .toArray()
2302
2326
  ```
2303
2327
 
2328
+ These also support passing the `<onstop>` callback as additional last
2329
+ argument. It will be called when `STOP`/`STOP(<value>)` is thrown or
2330
+ returned.
2331
+
2304
2332
 
2305
2333
  #### `<generator>.reduce(..)` / `<generator>.greduce(..)`
2306
2334
 
package/generator.js CHANGED
@@ -91,23 +91,36 @@ function*(lst=[]){
91
91
  } else {
92
92
  yield lst } }
93
93
 
94
+ // handle stops is onstop(..) is defined...
95
+ var __onstop =
96
+ function(res, _, ...args){
97
+ var onstop = args.at(-1)
98
+ typeof(onstop) == 'function'
99
+ && onstop.call(this,
100
+ ...(res === STOP ?
101
+ []
102
+ : [res])) }
103
+
104
+
94
105
  // XXX updatae Array.js' version for compatibility...
95
106
  // XXX DOCS!!!
96
107
  var iter =
97
108
  module.iter =
98
109
  Generator.iter =
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) })
110
+ stoppable(
111
+ function(lst=[]){
112
+ // handler -> generator-constructor...
113
+ if(typeof(lst) == 'function'){
114
+ // we need to be callable...
115
+ var that = this instanceof Function ?
116
+ this
117
+ // generic root generator...
118
+ : module.__iter
119
+ return function*(){
120
+ yield* that(...arguments).iter(lst) } }
121
+ // no handler -> generator instance...
122
+ return module.__iter(lst) },
123
+ __onstop)
111
124
 
112
125
  // NOTE: we need .iter(..) to both return generators if passed an iterable
113
126
  // and genereator constructos if passed a function...
@@ -308,31 +321,33 @@ var GeneratorProtoMixin =
308
321
  module.GeneratorProtoMixin =
309
322
  object.Mixin('GeneratorProtoMixin', 'soft', {
310
323
  // XXX use module.iter(..) ???
311
- iter: stoppable(function*(handler, onerror){
312
- try{
313
- if(handler){
314
- var i = 0
315
- for(var elem of this){
316
- var res = handler.call(this, elem, i)
317
- // expand iterables...
318
- if(typeof(res) == 'object'
319
- && Symbol.iterator in res){
320
- yield* res
321
- // as-is...
322
- } else {
323
- yield res }}
324
- // no handler...
325
- } else {
326
- yield* this }
327
- }catch(err){
328
- if(onerror){
329
- if(!(err === STOP
330
- || err instanceof STOP)){
331
- var res = onerror(err)
332
- if(res){
333
- yield res
334
- return } } }
335
- throw err }}),
324
+ iter: stoppable(
325
+ function*(handler, onerror){
326
+ try{
327
+ if(handler){
328
+ var i = 0
329
+ for(var elem of this){
330
+ var res = handler.call(this, elem, i)
331
+ // expand iterables...
332
+ if(typeof(res) == 'object'
333
+ && Symbol.iterator in res){
334
+ yield* res
335
+ // as-is...
336
+ } else {
337
+ yield res }}
338
+ // no handler...
339
+ } else {
340
+ yield* this }
341
+ }catch(err){
342
+ if(onerror){
343
+ if(!(err === STOP
344
+ || err instanceof STOP)){
345
+ var res = onerror(err)
346
+ if(res){
347
+ yield res
348
+ return } } }
349
+ throw err }},
350
+ __onstop),
336
351
  //*/
337
352
 
338
353
  at: function(i){
@@ -396,8 +411,10 @@ object.Mixin('GeneratorProtoMixin', 'soft', {
396
411
  yield* func(e, i++, this) }
397
412
  } else {
398
413
  for(var e of this){
399
- yield func(e, i++, this) } } }),
400
- filter: stoppable(function*(func){
414
+ yield func(e, i++, this) } } },
415
+ __onstop),
416
+ filter: stoppable(
417
+ function*(func){
401
418
  var i = 0
402
419
  try{
403
420
  for(var e of this){
@@ -409,28 +426,36 @@ object.Mixin('GeneratorProtoMixin', 'soft', {
409
426
  if(!err.value){
410
427
  throw STOP }
411
428
  err.value = e }
412
- throw err } }),
429
+ throw err } },
430
+ __onstop),
413
431
 
414
- reduce: stoppable(function(func, res){
415
- var i = 0
416
- for(var e of this){
417
- res = func(res, e, i++, this) }
418
- return res }),
432
+ reduce: stoppable(
433
+ function(func, res){
434
+ var i = 0
435
+ for(var e of this){
436
+ res = func(res, e, i++, this) }
437
+ return res },
438
+ // NOTE: we need to wrap __onstop(..) here to prevent res if it
439
+ // was passed a function from ever being treated as onstop(..)...
440
+ function(res, f, _, onstop){
441
+ return __onstop.call(this, res, onstop) }),
419
442
  greduce: function*(func, res){
420
443
  yield this.reduce(...arguments) },
421
444
 
422
- between: stoppable(function*(func){
423
- var i = 0
424
- var j = 0
425
- var prev
426
- for(var e of this){
427
- if(i > 0){
428
- yield typeof(func) == 'function' ?
429
- func.call(this, [prev, e], i-1, i + j++, this)
430
- : func }
431
- prev = e
432
- yield e
433
- i++ } }),
445
+ between: stoppable(
446
+ function*(func){
447
+ var i = 0
448
+ var j = 0
449
+ var prev
450
+ for(var e of this){
451
+ if(i > 0){
452
+ yield typeof(func) == 'function' ?
453
+ func.call(this, [prev, e], i-1, i + j++, this)
454
+ : func }
455
+ prev = e
456
+ yield e
457
+ i++ } },
458
+ __onstop),
434
459
 
435
460
  // NOTE: this is a special case in that it will unwind the generator...
436
461
  // NOTE: this is different from <array>.forEach(..) in that this will
@@ -566,29 +591,31 @@ object.Mixin('AsyncGeneratorProtoMixin', 'soft', {
566
591
  return this.unwind.finally(...arguments) },
567
592
 
568
593
  // XXX might be a good idea to use this approach above...
569
- iter: stoppable(async function*(handler=undefined, onerror=undefined){
570
- try{
571
- var i = 0
572
- if(handler){
573
- for await(var e of this){
574
- var res = handler.call(this, e, i++)
575
- if(typeof(res) == 'object'
576
- && Symbol.iterator in res){
577
- yield* res
578
- } else {
579
- yield res } }
580
- } else {
581
- yield* this }
582
- }catch(err){
583
- if(onerror){
584
- if(!(err === STOP || err instanceof STOP)){
585
- var res = onerror(err)
586
- if(res !== undefined){
587
- yield handler ?
588
- handler(res)
589
- : res }
590
- return } }
591
- throw err } }),
594
+ iter: stoppable(
595
+ async function*(handler=undefined, onerror=undefined){
596
+ try{
597
+ var i = 0
598
+ if(handler){
599
+ for await(var e of this){
600
+ var res = handler.call(this, e, i++)
601
+ if(typeof(res) == 'object'
602
+ && Symbol.iterator in res){
603
+ yield* res
604
+ } else {
605
+ yield res } }
606
+ } else {
607
+ yield* this }
608
+ }catch(err){
609
+ if(onerror){
610
+ if(!(err === STOP || err instanceof STOP)){
611
+ var res = onerror(err)
612
+ if(res !== undefined){
613
+ yield handler ?
614
+ handler(res)
615
+ : res }
616
+ return } }
617
+ throw err } },
618
+ __onstop),
592
619
 
593
620
  map: async function*(func){
594
621
  yield* this.iter(function(elem, i){
@@ -686,9 +713,11 @@ function*(value=true, stop){
686
713
 
687
714
  var produce =
688
715
  module.produce =
689
- stoppable(function*(func){
690
- while(true){
691
- yield func() } })
716
+ stoppable(
717
+ function*(func){
718
+ while(true){
719
+ yield func() } },
720
+ __onstop)
692
721
 
693
722
 
694
723
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ig-types",
3
- "version": "6.24.10",
3
+ "version": "6.24.12",
4
4
  "description": "Generic JavaScript types and type extensions...",
5
5
  "main": "main.js",
6
6
  "scripts": {