ig-types 6.24.9 → 6.24.12

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,126 @@ 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
+ __handle: function(list, handler=undefined, onerror=undefined){
310
+ var that = this
311
+ if(typeof(list) == 'function'){
312
+ handler = list
313
+ list = this.__packed }
314
+ if(!handler){
315
+ return list }
316
+ // handle promise list...
317
+ if(list instanceof Promise){
318
+ return list.then(function(list){
319
+ return that.__handle(list, handler, onerror) }) }
320
+ // do the work...
321
+ list = list instanceof Array ?
322
+ list
323
+ : [list]
324
+ var map = !!this.constructor.STOP ?
325
+ 'smap'
326
+ : 'map'
327
+ var stop = false
328
+ return list
329
+ [map](
330
+ function(elem){
331
+ return elem instanceof IterablePromise ?
332
+ // XXX should this be expanded??? (like Array below)
333
+ (elem.isSync() ?
334
+ handler(elem.sync())
335
+ // XXX need to handle this but keep it IterablePromise...
336
+ : elem.iterthen(handler))
337
+ : (elem instanceof SyncPromise
338
+ && !(elem.sync() instanceof Promise)) ?
339
+ // XXX should this be expanded??? (like Array below)
340
+ handler(elem.sync())
341
+ // promise / promise-like...
342
+ : elem && elem.then ?
343
+ // NOTE: when this is explicitly stopped we
344
+ // do not call any more handlers...
345
+ // XXX TEST!!!
346
+ elem.then(function(elem){
347
+ return !stop ?
348
+ handler(
349
+ elem.length == 1 ?
350
+ elem[0]
351
+ :elem)
352
+ : [] })
353
+ : elem instanceof Array ?
354
+ [handler(
355
+ elem.length == 1 ?
356
+ elem[0]
357
+ : elem)]
358
+ : handler(elem) },
359
+ function(res){
360
+ stop = true })
361
+ .flat() },
362
+ //*/
276
363
  // XXX this should return IterablePromise if .__packed is partially sync (???)
277
364
  // unpack array (sync/async)...
278
365
  __unpack: function(list){
@@ -293,30 +380,13 @@ object.Constructor('IterablePromise', Promise, {
293
380
  // give up on a sync solution...
294
381
  if(e instanceof Promise){
295
382
  // XXX can we return an IterablePromise???
296
- // XXX this will cause infinite recursion....
297
- //return Promise.iter(list).flat() }
298
383
  // XXX is there a more elegant way to do this???
299
384
  return Promise.all(list)
300
385
  .then(function(list){
301
386
  return list.flat() })
302
387
  .iter() }
303
- //return Promise.all(list)
304
- // .then(function(list){
305
- // return list.flat() }) }
306
388
  res.push(e) }
307
389
  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
390
 
321
391
  [Symbol.asyncIterator]: async function*(){
322
392
  var list = this.__packed
@@ -738,6 +808,60 @@ object.Constructor('IterablePromise', Promise, {
738
808
 
739
809
 
740
810
 
811
+ //---------------------------------------------------------------------
812
+ // XXX EXPEREMENTAL/HACK...
813
+
814
+ // XXX we are getting a list with promises triggered outside, we can't
815
+ // control order of execution of this but we can control in what
816
+ // order the handler is called...
817
+ // XXX this potentially shows a bug with IterablePromise:
818
+ // Promise.seqiter(
819
+ // [1, Promise.resolve(2), 3, Promise.resolve(4)],
820
+ // e => (console.log('---', e), e))
821
+ // ...this will not resolve/replace the 4's promise...
822
+ // for context:
823
+ // await Promise.resolve(Promise.resolve(Promise.resolve(123)))
824
+ // -> 123
825
+ // ...is this just a nesting issue here???
826
+ // Q: what IterablePromise does/should do if a promise resolves to
827
+ // a promise multiple times...
828
+ // XXX not sure if this is a viable strategy....
829
+ var IterableSequentialPromise =
830
+ module.IterableSequentialPromise =
831
+ object.Constructor('IterableSequentialPromise', IterablePromise, {
832
+ __new__: function(_, list, handler=undefined, onerror=undefined){
833
+ var [_, list, ...rest] = arguments
834
+ var res = list
835
+ // format the list...
836
+ if(list instanceof Array
837
+ || list instanceof Promise){
838
+
839
+ var pre_process = function(list, start=0){
840
+ if(list instanceof Promise){
841
+ return list.then(pre_process) }
842
+ res = []
843
+ for(let [i, e] of list.entries().slice(start)){
844
+ if(e instanceof Promise){
845
+ res.push(e.then(function(e){
846
+ return [e,
847
+ // XXX need to flatten this...
848
+ ...pre_process(list, i+1)] }))
849
+ break }
850
+ res.push(e) }
851
+ return res }
852
+
853
+ res = pre_process(list)
854
+
855
+ var obj = IterablePromise.prototype.__new__.call(this, _, res, 'raw')
856
+
857
+ return obj
858
+ }
859
+ // XXX use .parentCall(..)...
860
+ return IterablePromise.prototype.__new__.call(this, _, res, ...rest) },
861
+ })
862
+
863
+
864
+
741
865
  //---------------------------------------------------------------------
742
866
  // Interactive promise...
743
867
  //
@@ -1044,41 +1168,52 @@ var PromiseMixin =
1044
1168
  module.PromiseMixin =
1045
1169
  object.Mixin('PromiseMixin', 'soft', {
1046
1170
  iter: IterablePromise,
1171
+ // XXX
1172
+ seqiter: IterableSequentialPromise,
1173
+
1047
1174
  interactive: InteractivePromise,
1048
1175
  cooperative: CooperativePromise,
1176
+
1049
1177
  sync: SyncPromise,
1178
+
1050
1179
  // XXX should this be implemented via SyncPromise???
1180
+ // XXX not sure if we need to expand async generators...
1181
+ // (update README if this changes)
1051
1182
  awaitOrRun: function(data, func, error){
1052
1183
  data = [...arguments]
1053
1184
  func = data.pop()
1054
1185
  if(typeof(data.at(-1)) == 'function'){
1055
1186
  error = func
1056
1187
  func = data.pop() }
1057
- // ceck if we need to await...
1058
- return data
1059
- .reduce(function(res, e){
1188
+ error = error ?
1189
+ [error]
1190
+ : []
1191
+ // check if we need to await...
1192
+ return data.reduce(function(res, e){
1060
1193
  return res
1061
1194
  || e instanceof Promise }, false) ?
1062
- // NOTE: we will not reach this on empty data...
1063
- (data.length > 1 ?
1064
- Promise.all(data)
1065
- .then(
1066
- function(res){
1067
- return func(...res) },
1068
- ...(error ?
1069
- [error]
1070
- : []))
1071
- : data[0].then(
1072
- func,
1073
- ...(error ?
1074
- [error]
1075
- : [])))
1076
- : error ?
1195
+ // NOTE: we will not reach this on empty data...
1196
+ (data.length > 1 ?
1197
+ Promise.all(data)
1198
+ .then(
1199
+ function(res){
1200
+ return func(...res) },
1201
+ ...error)
1202
+ : data[0].then(func, ...error))
1203
+ // XXX not sure if we need to expand async generators...
1204
+ // ...since it has .then(..) it can be treated as a promise...
1205
+ // XXX should we just check for .then(..) ???
1206
+ // XXX update README if this changes...
1207
+ : (data.length == 1
1208
+ && Symbol.asyncIterator in data[0]
1209
+ && 'then' in data[0]) ?
1210
+ data[0].then(func, ...error)
1211
+ : error.length > 0 ?
1077
1212
  function(){
1078
1213
  try{
1079
1214
  return func(...data)
1080
1215
  }catch(err){
1081
- return error(err) } }()
1216
+ return error[0](err) } }()
1082
1217
  : func(...data) },
1083
1218
  })
1084
1219
 
@@ -1089,8 +1224,13 @@ var PromiseProtoMixin =
1089
1224
  module.PromiseProtoMixin =
1090
1225
  object.Mixin('PromiseProtoMixin', 'soft', {
1091
1226
  as: ProxyPromise,
1227
+
1092
1228
  iter: function(handler=undefined, onerror=undefined){
1093
1229
  return IterablePromise(this, handler, onerror) },
1230
+ // XXX
1231
+ seqiter: function(handler=undefined, onerror=undefined){
1232
+ return IterableSequentialPromise(this, handler, onerror) },
1233
+
1094
1234
  // unify the general promise API with other promise types...
1095
1235
  // XXX should this be here???
1096
1236
  // XXX error if given must return the result... (???)