ig-types 6.13.2 → 6.13.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.
Files changed (3) hide show
  1. package/Promise.js +63 -77
  2. package/package.json +1 -1
  3. package/test.js +17 -0
package/Promise.js CHANGED
@@ -58,6 +58,7 @@ object.Constructor('IterablePromise', Promise, {
58
58
  //
59
59
  // Format:
60
60
  // [
61
+ // <non-array-value>,
61
62
  // [ <value> ],
62
63
  // <promise>,
63
64
  // ...
@@ -66,24 +67,33 @@ object.Constructor('IterablePromise', Promise, {
66
67
  __list: null,
67
68
 
68
69
  // low-level .__list handlers/helpers...
70
+ //
69
71
  // NOTE: these can be useful for debugging and extending...
70
- __normalize: function(list, handler){
72
+ __pack: function(list, handler){
73
+ var that = this
74
+ // handle iterable promise list...
75
+ if(list instanceof IterablePromise){
76
+ return this.__handle(list.__list, handler) }
71
77
  // handle promise list...
72
78
  if(list instanceof Promise){
73
- var that = this
74
79
  return list.then(function(list){
75
- return that.__normalize(list, handler) }) }
76
-
80
+ return that.__pack(list, handler) }) }
81
+ // do the work...
82
+ // NOTE: packing and handling are mixed here because it's faster
83
+ // to do them both on a single list traverse...
77
84
  var handle = !!handler
78
85
  handler = handler
79
86
  ?? function(elem){
80
87
  return [elem] }
81
88
  return [list].flat()
82
89
  .map(function(elem){
83
- return elem instanceof Array ?
84
- handler(elem)
85
- : elem && elem.then ?
90
+ return elem && elem.then ?
91
+ //that.__pack(elem, handler)
86
92
  elem.then(handler)
93
+ : elem instanceof Array ?
94
+ handler(elem)
95
+ // NOTE: we keep things that do not need protecting
96
+ // from .flat() as-is...
87
97
  : !handle ?
88
98
  elem
89
99
  : handler(elem) }) },
@@ -98,25 +108,28 @@ object.Constructor('IterablePromise', Promise, {
98
108
  if(list instanceof Promise){
99
109
  return list.then(function(list){
100
110
  return that.__handle(list, handler) }) }
101
-
111
+ // do the work...
112
+ // NOTE: since each section of the packed .__array is the same
113
+ // structure as the input we'll use .__pack(..) to handle
114
+ // them, this also keeps all the handling code in one place.
102
115
  return list.map(function(elem){
103
116
  return elem instanceof Array ?
104
- that.__normalize(elem, handler)
117
+ that.__pack(elem, handler)
105
118
  : elem instanceof Promise ?
106
- that.__normalize([elem], handler).pop()
119
+ that.__pack(elem, handler)
107
120
  .then(function(elem){
108
121
  return elem.flat() })
109
- : handler(elem) })
122
+ : [handler(elem)] })
110
123
  .flat() },
111
- __denormalize: function(list){
124
+ __unpack: function(list){
112
125
  list = list
113
126
  ?? this.__list
114
127
  // handle promise list...
115
128
  if(list instanceof Promise){
116
129
  var that = this
117
130
  return list.then(function(list){
118
- return that.__denormalize(list) }) }
119
-
131
+ return that.__unpack(list) }) }
132
+ // do the work...
120
133
  return Promise.all(list)
121
134
  .then(function(list){
122
135
  return list.flat() }) },
@@ -150,12 +163,9 @@ object.Constructor('IterablePromise', Promise, {
150
163
  // .includes(..)
151
164
  // .some(..) / .every(..)
152
165
  // .sort(..)
153
- //
154
- // XXX should these support STOP???
155
166
  map: function(func){
156
167
  return this.constructor(this,
157
168
  function(e){
158
- //return [func(e)] }) },
159
169
  var res = func(e)
160
170
  return res instanceof Promise ?
161
171
  res.then(function(e){
@@ -164,27 +174,21 @@ object.Constructor('IterablePromise', Promise, {
164
174
  filter: function(func){
165
175
  return this.constructor(this,
166
176
  function(e){
167
- //return func(e) ?
168
- // [e]
169
- // : [] }) },
170
177
  var res = func(e)
178
+ var _filter = function(elem){
179
+ return res ?
180
+ [elem]
181
+ : [] }
171
182
  return res instanceof Promise ?
172
- res.then(function(res){
173
- return res ?
174
- [e]
175
- : [] })
176
- : res ?
177
- [e]
178
- : [] }) },
183
+ res.then(_filter)
184
+ : _filter(e) }) },
179
185
  // NOTE: this does not return an iterable promise as we can't know
180
186
  // what the user reduces to...
181
187
  // XXX we could look at the initial state though...
182
188
  // NOTE: the items can be handled out of order because the nested
183
- // promises can resolve in any order.
184
- // XXX doc how to go around this...
189
+ // promises can resolve in any order...
185
190
  // NOTE: since order of execution can not be guaranteed there is no
186
191
  // point in implementing .reduceRight(..)
187
- // XXX should func be able to return a promise???
188
192
  reduce: function(func, res){
189
193
  return this.constructor(this,
190
194
  function(e){
@@ -192,14 +196,6 @@ object.Constructor('IterablePromise', Promise, {
192
196
  return [] })
193
197
  .then(function(){
194
198
  return res }) },
195
- /* // XXX since order of execution is not fixed there is no point in
196
- // adding this.
197
- reduceRight: function(func, res){
198
- return this
199
- .reverse()
200
- .reduce(...arguments)
201
- .reverse() },
202
- //*/
203
199
  flat: function(depth=1){
204
200
  return this.constructor(this,
205
201
  function(e){
@@ -231,13 +227,25 @@ object.Constructor('IterablePromise', Promise, {
231
227
  .reverse(),
232
228
  'raw') },
233
229
 
234
- // NOTE: these can create an unresolved promise from a resolved
235
- // promise...
230
+ // NOTE: the following methods can create an unresolved promise from
231
+ // a resolved promise...
236
232
  concat: function(other){
233
+ var that = this
234
+ var cur = this.__pack(this)
235
+ var other = this.__pack(other)
237
236
  return this.constructor(
238
- this.__list
239
- .concat(this.__normalize(other)),
240
- 'raw') },
237
+ // NOTE: we need to keep things as exposed as possible, this
238
+ // is why we're not blanketing all the cases with
239
+ // Promise.all(..)...
240
+ (cur instanceof Promise
241
+ && other instanceof Promise) ?
242
+ [cur, other]
243
+ : cur instanceof Promise ?
244
+ [cur, ...other]
245
+ : other instanceof Promise ?
246
+ [...cur, other]
247
+ : [...cur, ...other],
248
+ 'raw') },
241
249
  push: function(elem){
242
250
  return this.concat([elem]) },
243
251
  unshift: function(elem){
@@ -248,6 +256,7 @@ object.Constructor('IterablePromise', Promise, {
248
256
  // .pop()
249
257
  // .shift()
250
258
  // .first() / .last()
259
+ // .at(..)
251
260
  // ...would be nice if these could stop everything that's not
252
261
  // needed to execute...
253
262
 
@@ -290,14 +299,14 @@ object.Constructor('IterablePromise', Promise, {
290
299
  // -> []
291
300
  //
292
301
  //
293
- // NOTE: element index is unknowable untill the full list is expanded
302
+ // NOTE: element index is unknowable until the full list is expanded
294
303
  // as handler(..)'s return value can expand to any number of
295
304
  // items...
296
305
  // XXX we can make the index a promise, then if the client needs
297
306
  // the value they can wait for it...
298
307
  //
299
308
  //
300
- // Spectial cases usefull for extending this constructor...
309
+ // Special cases useful for extending this constructor...
301
310
  //
302
311
  // Set raw .__list without any pre-processing...
303
312
  // Promise.iter([ .. ], 'raw')
@@ -308,45 +317,25 @@ object.Constructor('IterablePromise', Promise, {
308
317
  // -> iterable-promise
309
318
  //
310
319
  //
311
- // XXX if list is an iterator, can we fill this async???
312
320
  // XXX iterator/generator as input:
313
321
  // - do we unwind here or externally?
314
322
  // ...feels like with the generator external unwinding is
315
323
  // needed...
316
- // XXX would be nice to support trowing STOP...
324
+ // XXX would be nice to support throwing STOP...
317
325
  // - this is more complicated than simply suing .smap(..) instead
318
326
  // of .map(..) because the list can contain async promises...
319
327
  // ...would need to wrap each .then(..) call in try-catch and
320
328
  // manually handle the stop...
321
329
  // - another issue here is that the stop would happen in order of
322
330
  // execution and not order of elements...
323
- // XXX DOC:
324
- // inputs:
325
- // - Chaining -- list instanceof IterablePromise
326
- // After all the promises resolve .flat() should
327
- // turn this into the input list.
328
- // For this to work we'll need to at least wrap all
329
- // arrays and promise results in arrays.
330
- // (currently each value is wrapped)
331
- // -> __list
332
- // - promise (value | array)
333
- // - array of:
334
- // - array
335
- // - value
336
- // - promise (value | array)
337
- // - New
338
- // - promise (value | array)
339
- // - value (non-array)
340
- // - array of:
341
- // - value
342
- // - promise (value)
331
+ // XXX how do we handle errors???
343
332
  __new__: function(_, list, handler){
344
333
  // instance...
345
334
  var promise
346
335
  var obj = Reflect.construct(
347
336
  IterablePromise.__proto__,
348
337
  [function(resolve, reject){
349
- // NOTE: this is here for Promise compatibilty...
338
+ // NOTE: this is here for Promise compatibility...
350
339
  if(typeof(list) == 'function'){
351
340
  return list.call(this, ...arguments) }
352
341
  // initial reject...
@@ -355,19 +344,19 @@ object.Constructor('IterablePromise', Promise, {
355
344
  promise = {resolve, reject} }],
356
345
  IterablePromise)
357
346
 
347
+ // new instance...
358
348
  if(promise){
349
+ // handle/pack input data...
359
350
  if(handler != 'raw'){
360
351
  list = list instanceof IterablePromise ?
361
352
  this.__handle(list.__list, handler)
362
- : this.__normalize(list, handler) }
363
-
353
+ : this.__pack(list, handler) }
364
354
  Object.defineProperty(obj, '__list', {
365
355
  value: list,
366
356
  enumerable: false,
367
357
  })
368
-
369
358
  // handle promise state...
370
- this.__denormalize(list)
359
+ this.__unpack(list)
371
360
  .then(function(list){
372
361
  promise.resolve(list) })
373
362
  .catch(promise.reject) }
@@ -570,15 +559,12 @@ object.Mixin('PromiseMixin', 'soft', {
570
559
  PromiseMixin(Promise)
571
560
 
572
561
 
573
- // XXX EXPEREMENTAL...
574
562
  var PromiseProtoMixin =
575
563
  module.PromiseProtoMixin =
576
564
  object.Mixin('PromiseProtoMixin', 'soft', {
577
565
  as: ProxyPromise,
578
-
579
- // XXX
580
- iter: function(){
581
- return IterablePromise(this) },
566
+ iter: function(handler){
567
+ return IterablePromise(this, handler) },
582
568
  })
583
569
 
584
570
  PromiseProtoMixin(Promise.prototype)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ig-types",
3
- "version": "6.13.2",
3
+ "version": "6.13.7",
4
4
  "description": "Generic JavaScript types and type extensions...",
5
5
  "main": "main.js",
6
6
  "scripts": {
package/test.js CHANGED
@@ -183,6 +183,23 @@ var cases = test.Cases({
183
183
  .filter(function(e){ return false }),
184
184
  } },
185
185
 
186
+ /* XXX need tuning...
187
+ concat_basic: function(assert, {input, output}){
188
+ return {
189
+ input: [input].flat()
190
+ .concat(['a', 'b', 'c']),
191
+ output: output
192
+ .concat(['a', 'b', 'c']),
193
+ } },
194
+ concat_nested_array: function(assert, {input, output}){
195
+ return {
196
+ input: [input].flat()
197
+ .concat(['a', ['b'], 'c']),
198
+ output: output
199
+ .concat(['a', ['b'], 'c']),
200
+ } },
201
+ //*/
202
+
186
203
  })
187
204
  this.Test({
188
205
  value: async function(assert, {input, output}){