ig-types 6.24.4 → 6.24.7

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 +160 -31
  2. package/README.md +31 -4
  3. package/package.json +1 -1
package/Promise.js CHANGED
@@ -30,7 +30,7 @@
30
30
 
31
31
  var object = require('ig-object')
32
32
 
33
- //var generator = require('./generator')
33
+ var generator = require('./generator')
34
34
 
35
35
 
36
36
 
@@ -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, {
@@ -120,18 +123,22 @@ object.Constructor('IterablePromise', Promise, {
120
123
  // stop will stop the handlers not yet run and not the next
121
124
  // handlers in sequence.
122
125
  // 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???
126
+ // XXX ITER can we unwind (sync/async) generators one by one???
128
127
  __pack: function(list, handler=undefined){
129
128
  var that = this
130
- // handle iterable promise list...
129
+ // handle iterator...
130
+ // XXX ITER do we unwind the iterator here or wait to unwind later???
131
+ if(typeof(list) == 'object'
132
+ && Symbol.iterator in list){
133
+ list = [...list] }
134
+ // handle iterable promise...
131
135
  if(list instanceof IterablePromise){
132
136
  return this.__handle(list.__packed, handler) }
133
- // handle promise list...
134
- if(list instanceof Promise){
137
+ // handle promise / async-iterator...
138
+ // XXX ITER do we unwind the iterator here or wait to unwind later???
139
+ if(list instanceof Promise
140
+ || (typeof(list) == 'object'
141
+ && Symbol.asyncIterator in list)){
135
142
  return list.then(function(list){
136
143
  return that.__pack(list, handler) }) }
137
144
  // do the work...
@@ -149,7 +156,23 @@ object.Constructor('IterablePromise', Promise, {
149
156
  var pack = function(){
150
157
  return [list].flat()
151
158
  [map](function(elem){
159
+ // XXX EXPEREMENTAL -- not sure about this yet...
160
+ //elem = Symbol.iterator in elem ?
161
+ // [...elem]
162
+ // : elem
163
+ // XXX EXPEREMENTAL...
164
+ return elem instanceof IterablePromise ?
165
+ (elem.isSync() ?
166
+ handler(elem.sync())
167
+ // XXX need to handle this but keep it IterablePromise...
168
+ : elem.iterthen(handler))
169
+ : (elem instanceof SyncPromise
170
+ && !(elem.sync() instanceof Promise)) ?
171
+ handler(elem.sync())
172
+ : elem && elem.then ?
173
+ /*/
152
174
  return elem && elem.then ?
175
+ //*/
153
176
  (stoppable ?
154
177
  // stoppable -- need to handle stop async...
155
178
  elem
@@ -238,6 +261,40 @@ object.Constructor('IterablePromise', Promise, {
238
261
  return elem })
239
262
  : [handler(elem)] })
240
263
  .flat() },
264
+ // XXX EXPEREMENTAL...
265
+ // XXX this should return IterablePromise if .__packed is partially sync (???)
266
+ // unpack array (sync/async)...
267
+ __unpack: function(list){
268
+ list = list
269
+ ?? this.__packed
270
+ // handle promise list...
271
+ if(list instanceof IterablePromise){
272
+ return list.__unpack() }
273
+ if(list instanceof Promise){
274
+ return list
275
+ .then(this.__unpack.bind(this)) }
276
+ var res = []
277
+ for(var e of list){
278
+ if(e instanceof IterablePromise){
279
+ e = e.__unpack() }
280
+ if(e instanceof SyncPromise){
281
+ e = e.sync() }
282
+ // give up on a sync solution...
283
+ if(e instanceof Promise){
284
+ // XXX can we return an IterablePromise???
285
+ // XXX this will cause infinite recursion....
286
+ //return Promise.iter(list).flat() }
287
+ // XXX is there a more elegant way to do this???
288
+ return Promise.all(list)
289
+ .then(function(list){
290
+ return list.flat() })
291
+ .iter() }
292
+ //return Promise.all(list)
293
+ // .then(function(list){
294
+ // return list.flat() }) }
295
+ res.push(e) }
296
+ return res.flat() },
297
+ /*/
241
298
  // unpack array (async)...
242
299
  __unpack: async function(list){
243
300
  list = list
@@ -248,11 +305,12 @@ object.Constructor('IterablePromise', Promise, {
248
305
  // do the work...
249
306
  : (await Promise.all(list))
250
307
  .flat() },
251
-
308
+ //*/
309
+
252
310
  [Symbol.asyncIterator]: async function*(){
253
311
  var list = this.__packed
254
312
  if(list instanceof Promise){
255
- yield this.__unpack(await list)
313
+ yield* await this.__unpack(list)
256
314
  return }
257
315
  for await(var elem of list){
258
316
  yield* elem instanceof Array ?
@@ -387,6 +445,7 @@ object.Constructor('IterablePromise', Promise, {
387
445
  // NOTE: methods that are guaranteed to return an array will return
388
446
  // an iterable promise (created with iterPromiseProxy(..))...
389
447
  //
448
+ // XXX ASYNC should this be async or simply return a SyncPromise/Promise???
390
449
  at: async function(i){
391
450
  var list = this.__packed
392
451
  return ((i != 0 && i != -1)
@@ -453,6 +512,8 @@ object.Constructor('IterablePromise', Promise, {
453
512
  // to resolve...
454
513
  // - if no clients are available this can lead to wasted
455
514
  // CPU time...
515
+ //
516
+ // XXX ASYNC should this be async or simply return a SyncPromise/Promise???
456
517
  find: async function(func, result='value'){
457
518
  var that = this
458
519
  // NOTE: not using pure await here as this is simpler to actually
@@ -484,11 +545,13 @@ object.Constructor('IterablePromise', Promise, {
484
545
  findIndex: promiseProxy('findIndex'),
485
546
 
486
547
  // NOTE: this is just a special-case of .find(..)
548
+ // XXX ASYNC should this be async or simply return a SyncPromise/Promise???
487
549
  some: async function(func){
488
550
  return this.find(func, 'bool') },
489
551
  every: promiseProxy('every'),
490
552
 
491
553
 
554
+ // XXX ASYNC should this be async or simply return a SyncPromise/Promise???
492
555
  join: async function(){
493
556
  return [...(await this)]
494
557
  .join(...arguments) },
@@ -510,7 +573,10 @@ object.Constructor('IterablePromise', Promise, {
510
573
  // NOTE: this is slightly different from .then(..) in that it can be
511
574
  // called without arguments and return a promise wrapper. This can
512
575
  // be useful to hide special promise functionality...
513
- then: function (onfulfilled, onrejected){
576
+ //
577
+ // NOTE: this is internally linked to the actual (via: ..then.call(this, ..))
578
+ // state and will be resolved in .__new__(..) below.
579
+ then: function(onfulfilled, onrejected){
514
580
  var p = new Promise(
515
581
  function(resolve, reject){
516
582
  Promise.prototype.then.call(this,
@@ -525,6 +591,47 @@ object.Constructor('IterablePromise', Promise, {
525
591
  return arguments.length > 0 ?
526
592
  p.then(...arguments)
527
593
  : p },
594
+ // XXX EXPEREMENTAL revise...
595
+ // Like .then(..) but returns an IterablePromise instance...
596
+ iterthen: function(onfulfilled, onrejected){
597
+ if(this.isSync()){
598
+ var res = onfulfilled ?
599
+ this.constructor(onfulfilled(this.__unpack()))
600
+ : this.constructor(this.__unpack())
601
+ onrejected
602
+ && res.catch(onrejected)
603
+ return res }
604
+ // XXX we need to feed the output of onfulfilled to the value of
605
+ // res, but to this without wrapping the whole thing in a
606
+ // promise (possible???)...
607
+ return arguments.length > 0 ?
608
+ this.constructor(this.then(...arguments))
609
+ : this.constructor(this.__packed, 'raw') },
610
+
611
+ // XXX EXPEREMENTAL
612
+ isSync: function(){
613
+ return !(this.__packed instanceof Promise
614
+ || this.__packed
615
+ .filter(function(e){
616
+ return e instanceof IterablePromise ?
617
+ !e.isSync()
618
+ : e instanceof Promise
619
+ && !(e instanceof SyncPromise) })
620
+ .length > 0) },
621
+ sync: function(error=false){
622
+ try{
623
+ var res = this.__unpack()
624
+ }catch(err){
625
+ if(error == false){
626
+ return }
627
+ if(typeof(error) == 'function'){
628
+ return error(err) }
629
+ throw err }
630
+ return error !== false
631
+ && res instanceof Promise ?
632
+ // XXX should this be an IterablePromise???
633
+ res.catch(error)
634
+ : res },
528
635
 
529
636
 
530
637
  // constructor...
@@ -584,18 +691,37 @@ object.Constructor('IterablePromise', Promise, {
584
691
  // handle/pack input data...
585
692
  if(handler != 'raw'){
586
693
  list = list instanceof IterablePromise ?
587
- this.__handle(list.__packed, handler)
588
- : this.__pack(list, handler) }
694
+ obj.__handle(list.__packed, handler)
695
+ : obj.__pack(list, handler) }
589
696
  Object.defineProperty(obj, '__packed', {
590
697
  value: list,
591
698
  enumerable: false,
699
+ // NOTE: this is needed for self-resolve...
700
+ writable: true,
592
701
  })
593
702
  // handle promise state...
594
- this.__unpack(list)
595
- .then(function(list){
596
- promise.resolve(list) })
597
- .catch(promise.reject) }
598
-
703
+ try{
704
+ var res = obj.__unpack(list)
705
+ }catch(err){
706
+ promise.reject(err) }
707
+ res instanceof Promise ?
708
+ res
709
+ .then(function(list){
710
+ promise.resolve(list) })
711
+ .catch(promise.reject)
712
+ : promise.resolve(res)
713
+ // XXX EXPEREMENTAL
714
+ // XXX do we handle errors here???
715
+ // self-resolve state...
716
+ list instanceof Promise ?
717
+ list.then(function(list){
718
+ obj.__packed = list })
719
+ : list.forEach(function(elem, i){
720
+ elem instanceof Promise
721
+ && elem.then(function(elem){
722
+ lst = obj.__packed.slice()
723
+ lst[i] = elem
724
+ obj.__packed = lst }) }) }
599
725
  return obj },
600
726
  })
601
727
 
@@ -863,6 +989,13 @@ object.Constructor('SyncPromise', Promise, {
863
989
  resolve(this.value))
864
990
  // XXX should we return a copy???
865
991
  : this },
992
+ sync: function(error='throw'){
993
+ if(error !== false
994
+ && 'error' in this){
995
+ if(typeof(error) != 'function'){
996
+ throw this.error }
997
+ return error(this.error) }
998
+ return this.value },
866
999
 
867
1000
  // NOTE: if func calls resolve(..) with a promise then this will return
868
1001
  // that promise...
@@ -883,10 +1016,9 @@ object.Constructor('SyncPromise', Promise, {
883
1016
  // async...
884
1017
  if(!error
885
1018
  && value instanceof Promise){
886
- return value }
1019
+ return object.ASIS(value) }
887
1020
  // sync...
888
1021
  var obj = Promise.resolve(value)
889
- obj.__proto__ = this.prototype
890
1022
  obj.value = value
891
1023
  rejected
892
1024
  && (obj.error = error)
@@ -894,6 +1026,7 @@ object.Constructor('SyncPromise', Promise, {
894
1026
  })
895
1027
 
896
1028
 
1029
+
897
1030
  //---------------------------------------------------------------------
898
1031
 
899
1032
  var PromiseMixin =
@@ -948,16 +1081,12 @@ object.Mixin('PromiseProtoMixin', 'soft', {
948
1081
  as: ProxyPromise,
949
1082
  iter: function(handler=undefined){
950
1083
  return IterablePromise(this, handler) },
951
- // XXX should we try and return a sync value if normal promise is resolved???
952
- // ...sould need to hook .then(..) to do this...
953
- sync: function(error='throw'){
954
- if(this instanceof SyncPromise){
955
- if(error !== false
956
- && 'error' in this){
957
- if(typeof(error) != 'function'){
958
- throw this.error }
959
- return error(this.error) }
960
- return this.value }
1084
+ // unify the general promise API with other promise types...
1085
+ // XXX should this be here???
1086
+ // XXX error if given must return the result... (???)
1087
+ sync: function(error){
1088
+ typeof(error) == 'function'
1089
+ && this.catch(error)
961
1090
  return this },
962
1091
  })
963
1092
 
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)
@@ -88,6 +88,9 @@ Library of JavaScript type extensions, types and utilities.
88
88
  - [Array proxy methods returning `<promise-iter>`](#array-proxy-methods-returning-promise-iter)
89
89
  - [Array proxy methods returning a `<promise>`](#array-proxy-methods-returning-a-promise)
90
90
  - [`<promise-iter>.then(..)` / `<promise-iter>.catch(..)` / `<promise-iter>.finally(..)`](#promise-iterthen--promise-itercatch--promise-iterfinally)
91
+ - [`<promise-iter>.iterthen(..)`](#promise-iterthen)
92
+ - [`<promise-iter>.isSync(..)`](#promise-issync)
93
+ - [`<promise-iter>.sync(..)`](#promise-sync)
91
94
  - [`promise.IterablePromise.STOP` / `promise.IterablePromise.STOP(..)`](#promiseiterablepromisestop--promiseiterablepromisestop)
92
95
  - [Advanced handler](#advanced-handler)
93
96
  - [Stopping the iteration](#stopping-the-iteration)
@@ -95,7 +98,7 @@ Library of JavaScript type extensions, types and utilities.
95
98
  - [`<promise>.as(..)`](#promiseas)
96
99
  - [`<promise-proxy>.<method>(..)`](#promise-proxymethod)
97
100
  - [Sync/async promise](#syncasync-promise)
98
- - [`Promise.sync(..)` / `promise.SyncPromice(..)`](#promisesync--promisesyncpromice)
101
+ - [`Promise.sync(..)` / `promise.SyncPromise(..)`](#promisesync--promisesyncpromise)
99
102
  - [`<promise>.sync(..)`](#promisesync)
100
103
  - [`<sync-promise>.value` / `<sync-promise>.error`](#sync-promisevalue--sync-promiseerror)
101
104
  - [`Promise.sync.all(..)` / `Promise.sync.allSettled(..)` / `Promise.sync.any(..)` / `Promise.sync.race(..)`](promisesyncall--promisesyncallsettled--promisesyncany--promisesyncrace`)
@@ -1706,7 +1709,7 @@ Note that since `.reduce(..)` handler's execution order can not be known,
1706
1709
  there is no point in implementing `.reduceRigth(..)`.
1707
1710
 
1708
1711
 
1709
- ### `<promise-iter>.between(..)`
1712
+ #### `<promise-iter>.between(..)`
1710
1713
 
1711
1714
  ```bnf
1712
1715
  <promise-iter>.between(<value>)
@@ -1823,6 +1826,7 @@ These are similar to [`<array>.some(..)`](https://developer.mozilla.org/en-US/do
1823
1826
  and [`<array>.find(..)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
1824
1827
  see them for more info.
1825
1828
 
1829
+
1826
1830
  #### Array proxy methods returning `<promise-iter>`
1827
1831
 
1828
1832
  - `<promise-iter>.sort(..)`
@@ -1887,6 +1891,24 @@ For more info see: [Stopping the iteration](#stopping-the-iteration) below, and
1887
1891
  [the 'Array' STOP section](#arraystop--arraystop)
1888
1892
 
1889
1893
 
1894
+ #### `<promise-iter>.iterthen(..)`
1895
+
1896
+ Like `.then(..)` but will return an `IterablePromise` instance.
1897
+
1898
+
1899
+ #### `<promise-iter>.isSync()`
1900
+
1901
+ Return `true` if all content is resolved, otherwise return `false`.
1902
+
1903
+
1904
+ #### `<promise-iter>.sync(..)`
1905
+
1906
+ If all content is resolved return the promise value, otherwise return a promise.
1907
+
1908
+ For more info see: [`<promise>.sync(..)`](#promisesync)
1909
+
1910
+
1911
+
1890
1912
  #### Advanced handler
1891
1913
 
1892
1914
  ```bnf
@@ -2008,12 +2030,17 @@ the main `<promise>` is resolved.
2008
2030
 
2009
2031
  ### Sync/async promise
2010
2032
 
2033
+ The goal of this is to handle both sync and asynchronous data flows with
2034
+ one promise-like API, if all of the data can be obtained in a sync manner
2035
+ this will be sync otherwise we will revert to a normal promise.
2036
+
2011
2037
 
2012
- #### `Promise.sync(..)` / `promise.SyncPromice(..)`
2038
+ #### `Promise.sync(..)` / `promise.SyncPromise(..)`
2013
2039
 
2014
2040
  ```dnf
2015
2041
  Promise.sync(<func>)
2016
2042
  -> <sync-promise>
2043
+ -> <promise>
2017
2044
 
2018
2045
  <func>(<resolve>, <reject>)
2019
2046
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ig-types",
3
- "version": "6.24.4",
3
+ "version": "6.24.7",
4
4
  "description": "Generic JavaScript types and type extensions...",
5
5
  "main": "main.js",
6
6
  "scripts": {