ig-types 6.24.3 → 6.24.5

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.
Files changed (3) hide show
  1. package/Promise.js +136 -17
  2. package/README.md +27 -8
  3. package/package.json +1 -1
package/Promise.js CHANGED
@@ -70,12 +70,15 @@ function(name){
70
70
  return this.constructor(
71
71
  this.then(function(lst){
72
72
  return lst[name](...args) })) } }
73
+
74
+ // XXX ASYNC should this be async or simply return a SyncPromise/Promise???
73
75
  var promiseProxy =
74
76
  module.promiseProxy =
75
77
  function(name){
76
78
  return async function(...args){
77
79
  return (await this)[name](...args) } }
78
80
 
81
+
79
82
  var IterablePromise =
80
83
  module.IterablePromise =
81
84
  object.Constructor('IterablePromise', Promise, {
@@ -149,7 +152,19 @@ object.Constructor('IterablePromise', Promise, {
149
152
  var pack = function(){
150
153
  return [list].flat()
151
154
  [map](function(elem){
155
+ // XXX EXPEREMENTAL...
156
+ return elem instanceof IterablePromise ?
157
+ (elem.isSync() ?
158
+ handler(elem.sync())
159
+ // XXX need to handle this but keep it IterablePromise...
160
+ : elem.iterthen(handler))
161
+ : (elem instanceof SyncPromise
162
+ && !(elem.sync() instanceof Promise)) ?
163
+ handler(elem.sync())
164
+ : elem && elem.then ?
165
+ /*/
152
166
  return elem && elem.then ?
167
+ //*/
153
168
  (stoppable ?
154
169
  // stoppable -- need to handle stop async...
155
170
  elem
@@ -238,6 +253,35 @@ object.Constructor('IterablePromise', Promise, {
238
253
  return elem })
239
254
  : [handler(elem)] })
240
255
  .flat() },
256
+ // XXX EXPEREMENTAL...
257
+ // XXX this should return IterablePromise if .__packed is partially sync (???)
258
+ // unpack array (sync/async)...
259
+ __unpack: function(list){
260
+ list = list
261
+ ?? this.__packed
262
+ // handle promise list...
263
+ if(list instanceof IterablePromise){
264
+ return list.__unpack() }
265
+ if(list instanceof Promise){
266
+ return list
267
+ .then(this.__unpack.bind(this)) }
268
+ var res = []
269
+ for(var e of list){
270
+ if(e instanceof IterablePromise){
271
+ e = e.__unpack() }
272
+ if(e instanceof SyncPromise){
273
+ e = e.sync() }
274
+ // give up on a sync solution...
275
+ if(e instanceof Promise){
276
+ // XXX can we return an IterablePromise???
277
+ // XXX these will cause infinite recursion....
278
+ //return Promise.iter(list).flat() }
279
+ return Promise.all(list)
280
+ .then(function(list){
281
+ return list.flat() }) }
282
+ res.push(e) }
283
+ return res.flat() },
284
+ /*/
241
285
  // unpack array (async)...
242
286
  __unpack: async function(list){
243
287
  list = list
@@ -248,11 +292,12 @@ object.Constructor('IterablePromise', Promise, {
248
292
  // do the work...
249
293
  : (await Promise.all(list))
250
294
  .flat() },
251
-
295
+ //*/
296
+
252
297
  [Symbol.asyncIterator]: async function*(){
253
298
  var list = this.__packed
254
299
  if(list instanceof Promise){
255
- yield this.__unpack(await list)
300
+ yield* await this.__unpack(list)
256
301
  return }
257
302
  for await(var elem of list){
258
303
  yield* elem instanceof Array ?
@@ -387,6 +432,7 @@ object.Constructor('IterablePromise', Promise, {
387
432
  // NOTE: methods that are guaranteed to return an array will return
388
433
  // an iterable promise (created with iterPromiseProxy(..))...
389
434
  //
435
+ // XXX ASYNC should this be async or simply return a SyncPromise/Promise???
390
436
  at: async function(i){
391
437
  var list = this.__packed
392
438
  return ((i != 0 && i != -1)
@@ -453,6 +499,8 @@ object.Constructor('IterablePromise', Promise, {
453
499
  // to resolve...
454
500
  // - if no clients are available this can lead to wasted
455
501
  // CPU time...
502
+ //
503
+ // XXX ASYNC should this be async or simply return a SyncPromise/Promise???
456
504
  find: async function(func, result='value'){
457
505
  var that = this
458
506
  // NOTE: not using pure await here as this is simpler to actually
@@ -484,11 +532,13 @@ object.Constructor('IterablePromise', Promise, {
484
532
  findIndex: promiseProxy('findIndex'),
485
533
 
486
534
  // NOTE: this is just a special-case of .find(..)
535
+ // XXX ASYNC should this be async or simply return a SyncPromise/Promise???
487
536
  some: async function(func){
488
537
  return this.find(func, 'bool') },
489
538
  every: promiseProxy('every'),
490
539
 
491
540
 
541
+ // XXX ASYNC should this be async or simply return a SyncPromise/Promise???
492
542
  join: async function(){
493
543
  return [...(await this)]
494
544
  .join(...arguments) },
@@ -510,7 +560,10 @@ object.Constructor('IterablePromise', Promise, {
510
560
  // NOTE: this is slightly different from .then(..) in that it can be
511
561
  // called without arguments and return a promise wrapper. This can
512
562
  // be useful to hide special promise functionality...
513
- then: function (onfulfilled, onrejected){
563
+ //
564
+ // NOTE: this is internally linked to the actual (via: ..then.call(this, ..))
565
+ // state and will be resolved in .__new__(..) below.
566
+ then: function(onfulfilled, onrejected){
514
567
  var p = new Promise(
515
568
  function(resolve, reject){
516
569
  Promise.prototype.then.call(this,
@@ -525,6 +578,47 @@ object.Constructor('IterablePromise', Promise, {
525
578
  return arguments.length > 0 ?
526
579
  p.then(...arguments)
527
580
  : p },
581
+ // XXX EXPEREMENTAL revise...
582
+ // Like .then(..) but returns an IterablePromise instance...
583
+ iterthen: function(onfulfilled, onrejected){
584
+ if(this.isSync()){
585
+ var res = onfulfilled ?
586
+ this.constructor(onfulfilled(this.__unpack()))
587
+ : this.constructor(this.__unpack())
588
+ onrejected
589
+ && res.catch(onrejected)
590
+ return res }
591
+ // XXX we need to feed the output of onfulfilled to the value of
592
+ // res, but to this without wrapping the whole thing in a
593
+ // promise (possible???)...
594
+ return arguments.length > 0 ?
595
+ this.constructor(this.then(...arguments))
596
+ : this.constructor(this.__packed, 'raw') },
597
+
598
+ // XXX EXPEREMENTAL
599
+ isSync: function(){
600
+ return !(this.__packed instanceof Promise
601
+ || this.__packed
602
+ .filter(function(e){
603
+ return e instanceof IterablePromise ?
604
+ !e.isSync()
605
+ : e instanceof Promise
606
+ && !(e instanceof SyncPromise) })
607
+ .length > 0) },
608
+ sync: function(error=false){
609
+ try{
610
+ var res = this.__unpack()
611
+ }catch(err){
612
+ if(error == false){
613
+ return }
614
+ if(typeof(error) == 'function'){
615
+ return error(err) }
616
+ throw err }
617
+ return error !== false
618
+ && res instanceof Promise ?
619
+ // XXX should this be an IterablePromise???
620
+ res.catch(error)
621
+ : res },
528
622
 
529
623
 
530
624
  // constructor...
@@ -584,18 +678,37 @@ object.Constructor('IterablePromise', Promise, {
584
678
  // handle/pack input data...
585
679
  if(handler != 'raw'){
586
680
  list = list instanceof IterablePromise ?
587
- this.__handle(list.__packed, handler)
588
- : this.__pack(list, handler) }
681
+ obj.__handle(list.__packed, handler)
682
+ : obj.__pack(list, handler) }
589
683
  Object.defineProperty(obj, '__packed', {
590
684
  value: list,
591
685
  enumerable: false,
686
+ // NOTE: this is needed for self-resolve...
687
+ writable: true,
592
688
  })
593
689
  // handle promise state...
594
- this.__unpack(list)
595
- .then(function(list){
596
- promise.resolve(list) })
597
- .catch(promise.reject) }
598
-
690
+ try{
691
+ var res = obj.__unpack(list)
692
+ }catch(err){
693
+ promise.reject(err) }
694
+ res instanceof Promise ?
695
+ res
696
+ .then(function(list){
697
+ promise.resolve(list) })
698
+ .catch(promise.reject)
699
+ : promise.resolve(res)
700
+ // XXX EXPEREMENTAL
701
+ // XXX do we handle errors here???
702
+ // self-resolve state...
703
+ list instanceof Promise ?
704
+ list.then(function(list){
705
+ obj.__packed = list })
706
+ : list.forEach(function(elem, i){
707
+ elem instanceof Promise
708
+ && elem.then(function(elem){
709
+ lst = obj.__packed.slice()
710
+ lst[i] = elem
711
+ obj.__packed = lst }) }) }
599
712
  return obj },
600
713
  })
601
714
 
@@ -795,6 +908,7 @@ object.Constructor('ProxyPromise', Promise, {
795
908
 
796
909
  //---------------------------------------------------------------------
797
910
 
911
+ // XXX should this support async generators???
798
912
  var syncAllProxy =
799
913
  function(name){
800
914
  return function(lst){
@@ -809,6 +923,7 @@ function(name){
809
923
  : Promise[name](lst) } }
810
924
 
811
925
  // XXX REVISE/TEST...
926
+ // XXX should this support async generators???
812
927
  var syncAnyProxy =
813
928
  function(name){
814
929
  return function(lst){
@@ -837,6 +952,8 @@ object.Constructor('SyncPromise', Promise, {
837
952
  return new this(function(resolve){ resolve(value) }) },
838
953
  reject: function(error){
839
954
  return new this(function(_, reject){ reject(error) }) },
955
+ // NOTE: these essentially add a special case where the inputs are
956
+ // either not promises or SyncPromise instances...
840
957
  all: syncAllProxy('all'),
841
958
  allSettled: syncAllProxy('allSettled'),
842
959
  any: syncAnyProxy('any'),
@@ -859,6 +976,13 @@ object.Constructor('SyncPromise', Promise, {
859
976
  resolve(this.value))
860
977
  // XXX should we return a copy???
861
978
  : this },
979
+ sync: function(error='throw'){
980
+ if(error !== false
981
+ && 'error' in this){
982
+ if(typeof(error) != 'function'){
983
+ throw this.error }
984
+ return error(this.error) }
985
+ return this.value },
862
986
 
863
987
  // NOTE: if func calls resolve(..) with a promise then this will return
864
988
  // that promise...
@@ -890,6 +1014,7 @@ object.Constructor('SyncPromise', Promise, {
890
1014
  })
891
1015
 
892
1016
 
1017
+
893
1018
  //---------------------------------------------------------------------
894
1019
 
895
1020
  var PromiseMixin =
@@ -944,13 +1069,7 @@ object.Mixin('PromiseProtoMixin', 'soft', {
944
1069
  as: ProxyPromise,
945
1070
  iter: function(handler=undefined){
946
1071
  return IterablePromise(this, handler) },
947
- sync: function(error='throw'){
948
- if(this instanceof SyncPromise){
949
- if('error' in this){
950
- if(typeof(error) != 'function'){
951
- throw this.error }
952
- return error(this.error) }
953
- return this.value }
1072
+ sync: function(){
954
1073
  return this },
955
1074
  })
956
1075
 
package/README.md CHANGED
@@ -77,7 +77,7 @@ Library of JavaScript type extensions, types and utilities.
77
77
  - [`<promise>.iter()`](#promiseiter)
78
78
  - [`<promise-iter>.iter()`](#promise-iteriter)
79
79
  - [`<promise-iter>.map(..)` / `<promise-iter>.filter(..)` / `<promise-iter>.reduce(..)`](#promise-itermap--promise-iterfilter--promise-iterreduce)
80
- - [`<promise-iter>.between(..)`](#promise-iterbetween)
80
+ - [`<promise-iter>.between(..)`](#promise-iterbetween)
81
81
  - [`<promise-iter>.flat(..)`](#promise-iterflat)
82
82
  - [`<promise-iter>.reverse()`](#promise-iterreverse)
83
83
  - [`<promise-iter>.concat(..)`](#promise-iterconcat)
@@ -95,7 +95,7 @@ Library of JavaScript type extensions, types and utilities.
95
95
  - [`<promise>.as(..)`](#promiseas)
96
96
  - [`<promise-proxy>.<method>(..)`](#promise-proxymethod)
97
97
  - [Sync/async promise](#syncasync-promise)
98
- - [`Promise.sync(..)` / `promise.SyncPromice(..)`](#promisesync--promisesyncpromice)
98
+ - [`Promise.sync(..)` / `promise.SyncPromise(..)`](#promisesync--promisesyncpromise)
99
99
  - [`<promise>.sync(..)`](#promisesync)
100
100
  - [`<sync-promise>.value` / `<sync-promise>.error`](#sync-promisevalue--sync-promiseerror)
101
101
  - [`Promise.sync.all(..)` / `Promise.sync.allSettled(..)` / `Promise.sync.any(..)` / `Promise.sync.race(..)`](promisesyncall--promisesyncallsettled--promisesyncany--promisesyncrace`)
@@ -1706,7 +1706,7 @@ Note that since `.reduce(..)` handler's execution order can not be known,
1706
1706
  there is no point in implementing `.reduceRigth(..)`.
1707
1707
 
1708
1708
 
1709
- ### `<promise-iter>.between(..)`
1709
+ #### `<promise-iter>.between(..)`
1710
1710
 
1711
1711
  ```bnf
1712
1712
  <promise-iter>.between(<value>)
@@ -2009,7 +2009,7 @@ the main `<promise>` is resolved.
2009
2009
  ### Sync/async promise
2010
2010
 
2011
2011
 
2012
- #### `Promise.sync(..)` / `promise.SyncPromice(..)`
2012
+ #### `Promise.sync(..)` / `promise.SyncPromise(..)`
2013
2013
 
2014
2014
  ```dnf
2015
2015
  Promise.sync(<func>)
@@ -2034,10 +2034,29 @@ Example:
2034
2034
  -->
2035
2035
 
2036
2036
 
2037
- #### `<promise>.sync()`
2037
+ #### `<promise>.sync(..)`
2038
2038
 
2039
2039
  Synchronously return the resolved value if `<sync-promise>` resolved, and
2040
- if it _rejected_ then re-throw the `<error>`.
2040
+ if it _rejected_ then re-throw the `<error>`. Normal promises will return self.
2041
+
2042
+ ```bnf
2043
+ <promise>.sync()
2044
+ -> <value>
2045
+ -> <promise>
2046
+ ```
2047
+
2048
+ To suppress errors pass `false` to `.sync(..)` and to handle them differently
2049
+ pass an error handler function.
2050
+ ```bnf
2051
+ <promise>.sync(false)
2052
+ -> <value>
2053
+
2054
+ <promise>.sync(<onerror>)
2055
+ -> <value>
2056
+
2057
+ <onerror>(<error>)
2058
+ -> <value>
2059
+ ```
2041
2060
 
2042
2061
 
2043
2062
  #### `<sync-promise>.value` / `<sync-promise>.error`
@@ -2048,8 +2067,8 @@ rejection `.error`.
2048
2067
 
2049
2068
  #### `Promise.sync.all(..)` / `Promise.sync.allSettled(..)` / `Promise.sync.any(..)` / `Promise.sync.race(..)`
2050
2069
 
2051
- Equivalents to `Promise`'s version but will run sync if the relevant
2052
- items in the input are either non-promises or `<sync-promise>`s.
2070
+ Equivalents to `Promise`'s respective versions but will run sync if the
2071
+ relevant items in the input are either non-promises or `<sync-promise>`s.
2053
2072
 
2054
2073
 
2055
2074
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ig-types",
3
- "version": "6.24.3",
3
+ "version": "6.24.5",
4
4
  "description": "Generic JavaScript types and type extensions...",
5
5
  "main": "main.js",
6
6
  "scripts": {