ig-types 6.24.10 → 6.24.13
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/Array.js +21 -13
- package/Promise.js +201 -47
- package/Promise.js.new +1127 -0
- package/README.md +28 -0
- package/generator.js +112 -83
- package/package.json +1 -1
- package/test.js +26 -0
package/Array.js
CHANGED
|
@@ -524,19 +524,27 @@ object.Mixin('ArrayProtoMixin', 'soft', {
|
|
|
524
524
|
// XXX this should handle throwing STOP!!!
|
|
525
525
|
// ...might also ne a good idea to isolate the STOP mechanics
|
|
526
526
|
// into a spearate module/package...
|
|
527
|
-
iter: stoppable(
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
var
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
527
|
+
iter: stoppable(
|
|
528
|
+
function*(handler=undefined, onstop){
|
|
529
|
+
if(handler){
|
|
530
|
+
var i = 0
|
|
531
|
+
for(var e of this){
|
|
532
|
+
var res = handler.call(this, e, i++)
|
|
533
|
+
// treat non-iterables as single elements...
|
|
534
|
+
if(typeof(res) == 'object'
|
|
535
|
+
&& Symbol.iterator in res){
|
|
536
|
+
yield* res
|
|
537
|
+
} else {
|
|
538
|
+
yield res } }
|
|
539
|
+
} else {
|
|
540
|
+
yield* this }},
|
|
541
|
+
// handle stops is onstop(..) is defined...
|
|
542
|
+
function(res, _, onstop){
|
|
543
|
+
typeof(onstop) == 'function'
|
|
544
|
+
&& onstop.call(this,
|
|
545
|
+
...(res === STOP ?
|
|
546
|
+
[]
|
|
547
|
+
: [res])) }),
|
|
540
548
|
|
|
541
549
|
|
|
542
550
|
// Stoppable iteration...
|
package/Promise.js
CHANGED
|
@@ -124,6 +124,7 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
124
124
|
// handlers in sequence.
|
|
125
125
|
// XXX EXPEREMENTAL: STOP...
|
|
126
126
|
// XXX ITER can we unwind (sync/async) generators one by one???
|
|
127
|
+
/* XXX this repeats part of the functionality of .__handle(..)
|
|
127
128
|
__pack: function(list, handler=undefined, onerror=undefined){
|
|
128
129
|
var that = this
|
|
129
130
|
// handle iterator...
|
|
@@ -167,8 +168,7 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
167
168
|
handler = handler
|
|
168
169
|
?? function(elem){
|
|
169
170
|
return [elem] }
|
|
170
|
-
|
|
171
|
-
//* XXX EXPEREMENTAL: STOP...
|
|
171
|
+
// XXX this repeats .__handle(..), need to unify...
|
|
172
172
|
var stop = false
|
|
173
173
|
var map = 'map'
|
|
174
174
|
var pack = function(){
|
|
@@ -205,7 +205,6 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
205
205
|
: !handle ?
|
|
206
206
|
elem
|
|
207
207
|
: handler(elem) }) }
|
|
208
|
-
|
|
209
208
|
// pack (stoppable)...
|
|
210
209
|
if(!!this.constructor.STOP){
|
|
211
210
|
map = 'smap'
|
|
@@ -225,21 +224,7 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
225
224
|
|
|
226
225
|
// pack (non-stoppable)...
|
|
227
226
|
return pack() },
|
|
228
|
-
|
|
229
|
-
return [list].flat()
|
|
230
|
-
.map(function(elem){
|
|
231
|
-
return elem && elem.then ?
|
|
232
|
-
//that.__pack(elem, handler)
|
|
233
|
-
elem.then(handler)
|
|
234
|
-
: elem instanceof Array ?
|
|
235
|
-
handler(elem)
|
|
236
|
-
// NOTE: we keep things that do not need protecting
|
|
237
|
-
// from .flat() as-is...
|
|
238
|
-
: !handle ?
|
|
239
|
-
elem
|
|
240
|
-
: handler(elem) }) },
|
|
241
|
-
//*/
|
|
242
|
-
// transform/handle packed array (sync)...
|
|
227
|
+
// transform/handle packed array (sync, but can return promises in the list)...
|
|
243
228
|
__handle: function(list, handler=undefined, onerror=undefined){
|
|
244
229
|
var that = this
|
|
245
230
|
if(typeof(list) == 'function'){
|
|
@@ -255,24 +240,142 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
255
240
|
// NOTE: since each section of the packed .__array is the same
|
|
256
241
|
// structure as the input we'll use .__pack(..) to handle
|
|
257
242
|
// them, this also keeps all the handling code in one place.
|
|
258
|
-
//* XXX EXPEREMENTAL: STOP...
|
|
259
243
|
var map = !!this.constructor.STOP ?
|
|
260
244
|
'smap'
|
|
261
245
|
: 'map'
|
|
262
246
|
return list[map](function(elem){
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
//*/
|
|
266
|
-
return elem instanceof Array ?
|
|
247
|
+
elem = elem instanceof Array
|
|
248
|
+
|| elem instanceof Promise ?
|
|
267
249
|
that.__pack(elem, handler, onerror)
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
250
|
+
: [handler(elem)]
|
|
251
|
+
elem = elem instanceof Promise ?
|
|
252
|
+
elem.then(function([e]){
|
|
253
|
+
return e })
|
|
254
|
+
: elem
|
|
255
|
+
return elem })
|
|
274
256
|
.flat() },
|
|
275
|
-
|
|
257
|
+
/*/
|
|
258
|
+
__pack: function(list, handler=undefined, onerror=undefined){
|
|
259
|
+
var that = this
|
|
260
|
+
// handle iterator...
|
|
261
|
+
// XXX ITER do we unwind the iterator here or wait to unwind later???
|
|
262
|
+
if(typeof(list) == 'object'
|
|
263
|
+
&& Symbol.iterator in list){
|
|
264
|
+
if(!onerror){
|
|
265
|
+
list = [...list]
|
|
266
|
+
// handle errors in input generator...
|
|
267
|
+
// NOTE: this does not offer the most control because semantically
|
|
268
|
+
// we bust behave in the same manner as <generator>.iter(..)
|
|
269
|
+
} else {
|
|
270
|
+
var res = []
|
|
271
|
+
try{
|
|
272
|
+
for(var e of list){
|
|
273
|
+
res.push(e) }
|
|
274
|
+
}catch(err){
|
|
275
|
+
var r = onerror(err)
|
|
276
|
+
r !== undefined
|
|
277
|
+
&& res.push(r) }
|
|
278
|
+
list = res } }
|
|
279
|
+
// handle iterable promise...
|
|
280
|
+
if(list instanceof IterablePromise){
|
|
281
|
+
return this.__handle(list.__packed, handler, onerror) }
|
|
282
|
+
// handle promise / async-iterator...
|
|
283
|
+
// XXX ITER do we unwind the iterator here or wait to unwind later???
|
|
284
|
+
if(typeof(list) == 'object'
|
|
285
|
+
&& Symbol.asyncIterator in list){
|
|
286
|
+
return list
|
|
287
|
+
.iter(handler, onerror)
|
|
288
|
+
.then(function(list){
|
|
289
|
+
return that.__pack(list) }) }
|
|
290
|
+
if(list instanceof Promise){
|
|
291
|
+
return list
|
|
292
|
+
.then(function(list){
|
|
293
|
+
return that.__pack(list, handler, onerror) }) }
|
|
294
|
+
// pack...
|
|
295
|
+
list = [list].flat()
|
|
296
|
+
.map(function(elem){
|
|
297
|
+
return elem instanceof Array ?
|
|
298
|
+
[elem]
|
|
299
|
+
: elem instanceof Promise ?
|
|
300
|
+
elem.then(function(e){
|
|
301
|
+
return [e] })
|
|
302
|
+
: elem })
|
|
303
|
+
// handle if needed...
|
|
304
|
+
return handler ?
|
|
305
|
+
this.__handle(list, handler, onerror)
|
|
306
|
+
: list },
|
|
307
|
+
// transform/handle packed array (sync, but can return promises in the list)...
|
|
308
|
+
// XXX need a strict spec...
|
|
309
|
+
// XXX BUG???
|
|
310
|
+
// await Promise.iter([
|
|
311
|
+
// Promise.sync.resolve([1,1,1]),
|
|
312
|
+
// [2,2,2],
|
|
313
|
+
// Promise.resolve([3,3,3]),
|
|
314
|
+
// Promise.iter([4,4,4]),
|
|
315
|
+
// Promise.all([5,5,5]),
|
|
316
|
+
// ],
|
|
317
|
+
// e => e instanceof Array ? [[1,2,3]] : e)
|
|
318
|
+
// -> [ 1, 2, 3, [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ] ]
|
|
319
|
+
// ...the fist result seems odd...
|
|
320
|
+
// XXX FIXED but need to add a test for IterablePromise branch below...
|
|
321
|
+
__handle: function(list, handler=undefined, onerror=undefined){
|
|
322
|
+
var that = this
|
|
323
|
+
if(typeof(list) == 'function'){
|
|
324
|
+
handler = list
|
|
325
|
+
list = this.__packed }
|
|
326
|
+
if(!handler){
|
|
327
|
+
return list }
|
|
328
|
+
// handle promise list...
|
|
329
|
+
if(list instanceof Promise){
|
|
330
|
+
return list.then(function(list){
|
|
331
|
+
return that.__handle(list, handler, onerror) }) }
|
|
332
|
+
// do the work...
|
|
333
|
+
list = list instanceof Array ?
|
|
334
|
+
list
|
|
335
|
+
: [list]
|
|
336
|
+
var map = !!this.constructor.STOP ?
|
|
337
|
+
'smap'
|
|
338
|
+
: 'map'
|
|
339
|
+
var stop = false
|
|
340
|
+
var unwrap = function(elem){
|
|
341
|
+
return elem.length == 1 ?
|
|
342
|
+
elem[0]
|
|
343
|
+
: elem }
|
|
344
|
+
return list
|
|
345
|
+
[map](
|
|
346
|
+
function(elem){
|
|
347
|
+
return elem instanceof IterablePromise ?
|
|
348
|
+
// XXX should elem be expanded??? (like Array below)
|
|
349
|
+
(elem.isSync() ?
|
|
350
|
+
handler(elem.sync())
|
|
351
|
+
// XXX need to handle this but keep it IterablePromise...
|
|
352
|
+
: elem.iterthen(handler))
|
|
353
|
+
// sync sync promise...
|
|
354
|
+
: (elem instanceof SyncPromise
|
|
355
|
+
&& !(elem.sync() instanceof Promise)) ?
|
|
356
|
+
[handler(unwrap(elem.sync()))]
|
|
357
|
+
// promise / promise-like...
|
|
358
|
+
: elem && elem.then ?
|
|
359
|
+
// NOTE: when this is explicitly stopped we
|
|
360
|
+
// do not call any more handlers after
|
|
361
|
+
// STOP is thrown/returned...
|
|
362
|
+
// XXX TEST!!!
|
|
363
|
+
elem.then(function(elem){
|
|
364
|
+
return !stop ?
|
|
365
|
+
handler(unwrap(elem))
|
|
366
|
+
: [] })
|
|
367
|
+
: elem instanceof Array ?
|
|
368
|
+
// NOTE: we are calling .flat() on the result
|
|
369
|
+
// so we need to keep a handled array as
|
|
370
|
+
// a single element by wrapping the return
|
|
371
|
+
// of handled(..)...
|
|
372
|
+
[handler(unwrap(elem))]
|
|
373
|
+
: handler(elem) },
|
|
374
|
+
// handle STOP...
|
|
375
|
+
function(){
|
|
376
|
+
stop = true })
|
|
377
|
+
.flat() },
|
|
378
|
+
//*/
|
|
276
379
|
// XXX this should return IterablePromise if .__packed is partially sync (???)
|
|
277
380
|
// unpack array (sync/async)...
|
|
278
381
|
__unpack: function(list){
|
|
@@ -293,30 +396,13 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
293
396
|
// give up on a sync solution...
|
|
294
397
|
if(e instanceof Promise){
|
|
295
398
|
// XXX can we return an IterablePromise???
|
|
296
|
-
// XXX this will cause infinite recursion....
|
|
297
|
-
//return Promise.iter(list).flat() }
|
|
298
399
|
// XXX is there a more elegant way to do this???
|
|
299
400
|
return Promise.all(list)
|
|
300
401
|
.then(function(list){
|
|
301
402
|
return list.flat() })
|
|
302
403
|
.iter() }
|
|
303
|
-
//return Promise.all(list)
|
|
304
|
-
// .then(function(list){
|
|
305
|
-
// return list.flat() }) }
|
|
306
404
|
res.push(e) }
|
|
307
405
|
return res.flat() },
|
|
308
|
-
/*/
|
|
309
|
-
// unpack array (async)...
|
|
310
|
-
__unpack: async function(list){
|
|
311
|
-
list = list
|
|
312
|
-
?? this.__packed
|
|
313
|
-
// handle promise list...
|
|
314
|
-
return list instanceof Promise ?
|
|
315
|
-
this.__unpack(await list)
|
|
316
|
-
// do the work...
|
|
317
|
-
: (await Promise.all(list))
|
|
318
|
-
.flat() },
|
|
319
|
-
//*/
|
|
320
406
|
|
|
321
407
|
[Symbol.asyncIterator]: async function*(){
|
|
322
408
|
var list = this.__packed
|
|
@@ -738,6 +824,60 @@ object.Constructor('IterablePromise', Promise, {
|
|
|
738
824
|
|
|
739
825
|
|
|
740
826
|
|
|
827
|
+
//---------------------------------------------------------------------
|
|
828
|
+
// XXX EXPEREMENTAL/HACK...
|
|
829
|
+
|
|
830
|
+
// XXX we are getting a list with promises triggered outside, we can't
|
|
831
|
+
// control order of execution of this but we can control in what
|
|
832
|
+
// order the handler is called...
|
|
833
|
+
// XXX this potentially shows a bug with IterablePromise:
|
|
834
|
+
// Promise.seqiter(
|
|
835
|
+
// [1, Promise.resolve(2), 3, Promise.resolve(4)],
|
|
836
|
+
// e => (console.log('---', e), e))
|
|
837
|
+
// ...this will not resolve/replace the 4's promise...
|
|
838
|
+
// for context:
|
|
839
|
+
// await Promise.resolve(Promise.resolve(Promise.resolve(123)))
|
|
840
|
+
// -> 123
|
|
841
|
+
// ...is this just a nesting issue here???
|
|
842
|
+
// Q: what IterablePromise does/should do if a promise resolves to
|
|
843
|
+
// a promise multiple times...
|
|
844
|
+
// XXX not sure if this is a viable strategy....
|
|
845
|
+
var IterableSequentialPromise =
|
|
846
|
+
module.IterableSequentialPromise =
|
|
847
|
+
object.Constructor('IterableSequentialPromise', IterablePromise, {
|
|
848
|
+
__new__: function(_, list, handler=undefined, onerror=undefined){
|
|
849
|
+
var [_, list, ...rest] = arguments
|
|
850
|
+
var res = list
|
|
851
|
+
// format the list...
|
|
852
|
+
if(list instanceof Array
|
|
853
|
+
|| list instanceof Promise){
|
|
854
|
+
|
|
855
|
+
var pre_process = function(list, start=0){
|
|
856
|
+
if(list instanceof Promise){
|
|
857
|
+
return list.then(pre_process) }
|
|
858
|
+
res = []
|
|
859
|
+
for(let [i, e] of list.entries().slice(start)){
|
|
860
|
+
if(e instanceof Promise){
|
|
861
|
+
res.push(e.then(function(e){
|
|
862
|
+
return [e,
|
|
863
|
+
// XXX need to flatten this...
|
|
864
|
+
...pre_process(list, i+1)] }))
|
|
865
|
+
break }
|
|
866
|
+
res.push(e) }
|
|
867
|
+
return res }
|
|
868
|
+
|
|
869
|
+
res = pre_process(list)
|
|
870
|
+
|
|
871
|
+
var obj = IterablePromise.prototype.__new__.call(this, _, res, 'raw')
|
|
872
|
+
|
|
873
|
+
return obj
|
|
874
|
+
}
|
|
875
|
+
// XXX use .parentCall(..)...
|
|
876
|
+
return IterablePromise.prototype.__new__.call(this, _, res, ...rest) },
|
|
877
|
+
})
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
|
|
741
881
|
//---------------------------------------------------------------------
|
|
742
882
|
// Interactive promise...
|
|
743
883
|
//
|
|
@@ -1044,11 +1184,17 @@ var PromiseMixin =
|
|
|
1044
1184
|
module.PromiseMixin =
|
|
1045
1185
|
object.Mixin('PromiseMixin', 'soft', {
|
|
1046
1186
|
iter: IterablePromise,
|
|
1187
|
+
// XXX
|
|
1188
|
+
seqiter: IterableSequentialPromise,
|
|
1189
|
+
|
|
1047
1190
|
interactive: InteractivePromise,
|
|
1048
1191
|
cooperative: CooperativePromise,
|
|
1192
|
+
|
|
1049
1193
|
sync: SyncPromise,
|
|
1194
|
+
|
|
1050
1195
|
// XXX should this be implemented via SyncPromise???
|
|
1051
1196
|
// XXX not sure if we need to expand async generators...
|
|
1197
|
+
// (update README if this changes)
|
|
1052
1198
|
awaitOrRun: function(data, func, error){
|
|
1053
1199
|
data = [...arguments]
|
|
1054
1200
|
func = data.pop()
|
|
@@ -1071,6 +1217,9 @@ object.Mixin('PromiseMixin', 'soft', {
|
|
|
1071
1217
|
...error)
|
|
1072
1218
|
: data[0].then(func, ...error))
|
|
1073
1219
|
// XXX not sure if we need to expand async generators...
|
|
1220
|
+
// ...since it has .then(..) it can be treated as a promise...
|
|
1221
|
+
// XXX should we just check for .then(..) ???
|
|
1222
|
+
// XXX update README if this changes...
|
|
1074
1223
|
: (data.length == 1
|
|
1075
1224
|
&& Symbol.asyncIterator in data[0]
|
|
1076
1225
|
&& 'then' in data[0]) ?
|
|
@@ -1091,8 +1240,13 @@ var PromiseProtoMixin =
|
|
|
1091
1240
|
module.PromiseProtoMixin =
|
|
1092
1241
|
object.Mixin('PromiseProtoMixin', 'soft', {
|
|
1093
1242
|
as: ProxyPromise,
|
|
1243
|
+
|
|
1094
1244
|
iter: function(handler=undefined, onerror=undefined){
|
|
1095
1245
|
return IterablePromise(this, handler, onerror) },
|
|
1246
|
+
// XXX
|
|
1247
|
+
seqiter: function(handler=undefined, onerror=undefined){
|
|
1248
|
+
return IterableSequentialPromise(this, handler, onerror) },
|
|
1249
|
+
|
|
1096
1250
|
// unify the general promise API with other promise types...
|
|
1097
1251
|
// XXX should this be here???
|
|
1098
1252
|
// XXX error if given must return the result... (???)
|