ig-types 6.13.7 → 6.14.0
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 +92 -36
- package/README.md +11 -0
- package/package.json +1 -1
package/Promise.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
/**********************************************************************
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
2
|
*
|
|
6
3
|
* This defines the following extensions to Promise:
|
|
7
4
|
*
|
|
8
5
|
* Promise.iter(seq)
|
|
6
|
+
* <promise>.iter()
|
|
9
7
|
* Iterable promise object.
|
|
10
8
|
* Similar to Promise.all(..) but adds basic iterator/generator
|
|
11
9
|
* API and will resolve the items as they are ready (resolved).
|
|
@@ -19,6 +17,11 @@
|
|
|
19
17
|
* Exposes the API to resolve/reject the promise object
|
|
20
18
|
* externally.
|
|
21
19
|
*
|
|
20
|
+
* <promise>.as(obj)
|
|
21
|
+
* Promise proxy.
|
|
22
|
+
* Proxies the methods available from obj to promise value.
|
|
23
|
+
*
|
|
24
|
+
*
|
|
22
25
|
*
|
|
23
26
|
*
|
|
24
27
|
**********************************************/ /* c8 ignore next 2 */
|
|
@@ -28,18 +31,6 @@
|
|
|
28
31
|
|
|
29
32
|
var object = require('ig-object')
|
|
30
33
|
|
|
31
|
-
// XXX required for STOP...
|
|
32
|
-
//var generator = require('./generator')
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
/*********************************************************************/
|
|
36
|
-
|
|
37
|
-
/* XXX not used yet...
|
|
38
|
-
// NOTE: this is used in a similar fashion to Python's StopIteration...
|
|
39
|
-
var STOP =
|
|
40
|
-
module.STOP =
|
|
41
|
-
object.STOP
|
|
42
|
-
//*/
|
|
43
34
|
|
|
44
35
|
|
|
45
36
|
//---------------------------------------------------------------------
|
|
@@ -48,13 +39,38 @@ module.STOP =
|
|
|
48
39
|
// Like Promise.all(..) but adds ability to iterate through results
|
|
49
40
|
// via generators .map(..)/.reduce(..) and friends...
|
|
50
41
|
//
|
|
42
|
+
// NOTE: it would be nice to support throwing STOP from the iterable
|
|
43
|
+
// promise but...
|
|
44
|
+
// - this is more complicated than simply using .smap(..) instead
|
|
45
|
+
// of .map(..) because the list can contain async promises...
|
|
46
|
+
// ...would need to wrap each .then(..) call in try-catch and
|
|
47
|
+
// manually handle the stop...
|
|
48
|
+
// ...then there's a question of derivative iterators etc.
|
|
49
|
+
// - another issue here is that the stop would happen in order of
|
|
50
|
+
// execution and not order of elements...
|
|
51
|
+
// XXX though stopping within a single level might be useful...
|
|
52
|
+
//
|
|
53
|
+
|
|
54
|
+
// NOTE: we are not using async/await here as we need to control the
|
|
55
|
+
// type of promise returned in cases where we know we are returning
|
|
56
|
+
// an array...
|
|
57
|
+
// XXX should these be exported???
|
|
58
|
+
var iterPromiseProxy =
|
|
59
|
+
//module.iterPromiseProxy =
|
|
60
|
+
function(name){
|
|
61
|
+
return function(...args){
|
|
62
|
+
return this.constructor(
|
|
63
|
+
this.then(function(lst){
|
|
64
|
+
return lst[name](...args) })) } }
|
|
65
|
+
var promiseProxy =
|
|
66
|
+
//module.promiseProxy =
|
|
67
|
+
function(name){
|
|
68
|
+
return async function(...args){
|
|
69
|
+
return (await this)[name](...args) } }
|
|
51
70
|
|
|
52
71
|
var IterablePromise =
|
|
53
72
|
module.IterablePromise =
|
|
54
73
|
object.Constructor('IterablePromise', Promise, {
|
|
55
|
-
// XXX
|
|
56
|
-
//STOP: object.STOP,
|
|
57
|
-
|
|
58
74
|
//
|
|
59
75
|
// Format:
|
|
60
76
|
// [
|
|
@@ -64,6 +80,13 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
64
80
|
// ...
|
|
65
81
|
// ]
|
|
66
82
|
//
|
|
83
|
+
// This format has several useful features:
|
|
84
|
+
// - concatenating packed list results in a packed list
|
|
85
|
+
// - adding an iterable promise (as-is) into a packed list results
|
|
86
|
+
// in a packed list
|
|
87
|
+
//
|
|
88
|
+
// NOTE: in general iterable promises are implicitly immutable, so
|
|
89
|
+
// it is not recomended to ever edit this inplace...
|
|
67
90
|
__list: null,
|
|
68
91
|
|
|
69
92
|
// low-level .__list handlers/helpers...
|
|
@@ -163,6 +186,7 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
163
186
|
// .includes(..)
|
|
164
187
|
// .some(..) / .every(..)
|
|
165
188
|
// .sort(..)
|
|
189
|
+
// XXX update this note...
|
|
166
190
|
map: function(func){
|
|
167
191
|
return this.constructor(this,
|
|
168
192
|
function(e){
|
|
@@ -196,6 +220,7 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
196
220
|
return [] })
|
|
197
221
|
.then(function(){
|
|
198
222
|
return res }) },
|
|
223
|
+
|
|
199
224
|
flat: function(depth=1){
|
|
200
225
|
return this.constructor(this,
|
|
201
226
|
function(e){
|
|
@@ -252,14 +277,54 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
252
277
|
return this.constructor([elem])
|
|
253
278
|
.concat(this) },
|
|
254
279
|
|
|
255
|
-
// XXX
|
|
280
|
+
// XXX can we do these?
|
|
256
281
|
// .pop()
|
|
257
282
|
// .shift()
|
|
258
|
-
// .
|
|
259
|
-
// .at(..)
|
|
283
|
+
// .splice(..)
|
|
260
284
|
// ...would be nice if these could stop everything that's not
|
|
261
|
-
// needed to execute
|
|
285
|
+
// needed to execute -- likely not possible (XXX)
|
|
286
|
+
// ...these need to somehow both return an element and affect
|
|
287
|
+
// the iterator (or return a new one) -- we can trivially do either
|
|
288
|
+
// one action within the spec but not both...
|
|
289
|
+
|
|
290
|
+
// NOTE: this can avoid waiting for the whole promise to resolve only
|
|
291
|
+
// for indexes 0 and -1, everything else is non-deterministic and
|
|
292
|
+
// we'll have to wait for the whole thing to resolve.
|
|
293
|
+
at: async function(i){
|
|
294
|
+
var list = this.__list
|
|
295
|
+
return ((i != 0 && i != -1)
|
|
296
|
+
|| list instanceof Promise
|
|
297
|
+
|| list.at(i) instanceof Promise) ?
|
|
298
|
+
(await this).at(i)
|
|
299
|
+
// NOTE: we can only reason about first/last explicit elements,
|
|
300
|
+
// anything else is non-deterministic...
|
|
301
|
+
: list.at(i) instanceof Promise ?
|
|
302
|
+
[await list.at(i)].flat().at(i)
|
|
303
|
+
: list.at(i) instanceof Array ?
|
|
304
|
+
list.at(i).at(i)
|
|
305
|
+
: list.at(i) },
|
|
306
|
+
first: function(){
|
|
307
|
+
return this.at(0) },
|
|
308
|
+
last: function(){
|
|
309
|
+
return this.at(-1) },
|
|
262
310
|
|
|
311
|
+
// NOTE: there is no way we can do a sync generator returning
|
|
312
|
+
// promises for values because any promise in .__list makes the
|
|
313
|
+
// value count/index non-deterministic...
|
|
314
|
+
sort: iterPromiseProxy('sort'),
|
|
315
|
+
slice: iterPromiseProxy('slice'),
|
|
316
|
+
entries: iterPromiseProxy('entries'),
|
|
317
|
+
keys: iterPromiseProxy('keys'),
|
|
318
|
+
// XXX we could possibly make this better via .map(..)
|
|
319
|
+
values: iterPromiseProxy('values'),
|
|
320
|
+
|
|
321
|
+
indexOf: promiseProxy('indexOf'),
|
|
322
|
+
includes: promiseProxy('includes'),
|
|
323
|
+
|
|
324
|
+
every: promiseProxy('every'),
|
|
325
|
+
// XXX this can be lazy...
|
|
326
|
+
some: promiseProxy('some'),
|
|
327
|
+
|
|
263
328
|
|
|
264
329
|
// Overload .then(..), .catch(..) and .finally(..) to return a plain
|
|
265
330
|
// Promise instnace...
|
|
@@ -295,8 +360,9 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
295
360
|
//
|
|
296
361
|
//
|
|
297
362
|
// handler(e)
|
|
298
|
-
// -> [value]
|
|
363
|
+
// -> [value, ..]
|
|
299
364
|
// -> []
|
|
365
|
+
// -> <promise>
|
|
300
366
|
//
|
|
301
367
|
//
|
|
302
368
|
// NOTE: element index is unknowable until the full list is expanded
|
|
@@ -321,14 +387,7 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
321
387
|
// - do we unwind here or externally?
|
|
322
388
|
// ...feels like with the generator external unwinding is
|
|
323
389
|
// needed...
|
|
324
|
-
// XXX
|
|
325
|
-
// - this is more complicated than simply suing .smap(..) instead
|
|
326
|
-
// of .map(..) because the list can contain async promises...
|
|
327
|
-
// ...would need to wrap each .then(..) call in try-catch and
|
|
328
|
-
// manually handle the stop...
|
|
329
|
-
// - another issue here is that the stop would happen in order of
|
|
330
|
-
// execution and not order of elements...
|
|
331
|
-
// XXX how do we handle errors???
|
|
390
|
+
// XXX how do we handle errors/rejections???
|
|
332
391
|
__new__: function(_, list, handler){
|
|
333
392
|
// instance...
|
|
334
393
|
var promise
|
|
@@ -344,7 +403,7 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
344
403
|
promise = {resolve, reject} }],
|
|
345
404
|
IterablePromise)
|
|
346
405
|
|
|
347
|
-
// new instance...
|
|
406
|
+
// populate new instance...
|
|
348
407
|
if(promise){
|
|
349
408
|
// handle/pack input data...
|
|
350
409
|
if(handler != 'raw'){
|
|
@@ -536,10 +595,7 @@ object.Constructor('ProxyPromise', Promise, {
|
|
|
536
595
|
&& !value.enumerable){
|
|
537
596
|
return }
|
|
538
597
|
// proxy...
|
|
539
|
-
obj[key] =
|
|
540
|
-
// XXX should we also .catch(..) here???
|
|
541
|
-
return context.then(function(res){
|
|
542
|
-
return res[key](...args) }) } })
|
|
598
|
+
obj[key] = promiseProxy(key) })
|
|
543
599
|
proto = proto.__proto__ }
|
|
544
600
|
return obj },
|
|
545
601
|
})
|
package/README.md
CHANGED
|
@@ -1508,6 +1508,17 @@ promise, even if the original is resolved.
|
|
|
1508
1508
|
If all values are resolved the `<promise-iter>` will resolve on the next
|
|
1509
1509
|
execution frame.
|
|
1510
1510
|
|
|
1511
|
+
There are two types of iterator methods here, both are transparent but different
|
|
1512
|
+
in how they process values:
|
|
1513
|
+
- *Parallel methods*
|
|
1514
|
+
These handle elements as soon as they are available even if the parent promise
|
|
1515
|
+
is not yet resolved.
|
|
1516
|
+
<!-- XXX list -->
|
|
1517
|
+
- *Proxies*
|
|
1518
|
+
These methods simply wait for the main promise to resolve and then call the
|
|
1519
|
+
appropriate method on the result.
|
|
1520
|
+
<!-- XXX list + mark definitions as "(proxy)" -->
|
|
1521
|
+
|
|
1511
1522
|
<!--
|
|
1512
1523
|
XXX should we support generators as input?
|
|
1513
1524
|
...not sure about the control flow direction here, on one hand the generator
|