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 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(function*(handler=undefined){
528
- if(handler){
529
- var i = 0
530
- for(var e of this){
531
- var res = handler.call(this, e, i++)
532
- // treat non-iterables as single elements...
533
- if(typeof(res) == 'object'
534
- && Symbol.iterator in res){
535
- yield* res
536
- } else {
537
- yield res } }
538
- } else {
539
- yield* this }}),
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
- return list.map(function(elem){
265
- //*/
266
- return elem instanceof Array ?
247
+ elem = elem instanceof Array
248
+ || elem instanceof Promise ?
267
249
  that.__pack(elem, handler, onerror)
268
- : elem instanceof Promise ?
269
- that.__pack(elem, handler, onerror)
270
- //.then(function(elem){
271
- .then(function([elem]){
272
- return elem })
273
- : [handler(elem)] })
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
- // XXX EXPEREMENTAL...
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... (???)