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.
- package/Promise.js +160 -31
- package/README.md +31 -4
- 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
|
-
|
|
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
|
|
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
|
|
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
|
|
134
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
588
|
-
:
|
|
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
|
-
|
|
595
|
-
.
|
|
596
|
-
|
|
597
|
-
|
|
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
|
-
//
|
|
952
|
-
//
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
|