ig-types 6.12.1 → 6.13.2

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 +104 -74
  2. package/package.json +1 -1
  3. package/test.js +126 -28
package/Promise.js CHANGED
@@ -65,6 +65,62 @@ object.Constructor('IterablePromise', Promise, {
65
65
  //
66
66
  __list: null,
67
67
 
68
+ // low-level .__list handlers/helpers...
69
+ // NOTE: these can be useful for debugging and extending...
70
+ __normalize: function(list, handler){
71
+ // handle promise list...
72
+ if(list instanceof Promise){
73
+ var that = this
74
+ return list.then(function(list){
75
+ return that.__normalize(list, handler) }) }
76
+
77
+ var handle = !!handler
78
+ handler = handler
79
+ ?? function(elem){
80
+ return [elem] }
81
+ return [list].flat()
82
+ .map(function(elem){
83
+ return elem instanceof Array ?
84
+ handler(elem)
85
+ : elem && elem.then ?
86
+ elem.then(handler)
87
+ : !handle ?
88
+ elem
89
+ : handler(elem) }) },
90
+ __handle: function(list, handler){
91
+ var that = this
92
+ if(typeof(list) == 'function'){
93
+ handler = list
94
+ list = this.__list }
95
+ if(!handler){
96
+ return list }
97
+ // handle promise list...
98
+ if(list instanceof Promise){
99
+ return list.then(function(list){
100
+ return that.__handle(list, handler) }) }
101
+
102
+ return list.map(function(elem){
103
+ return elem instanceof Array ?
104
+ that.__normalize(elem, handler)
105
+ : elem instanceof Promise ?
106
+ that.__normalize([elem], handler).pop()
107
+ .then(function(elem){
108
+ return elem.flat() })
109
+ : handler(elem) })
110
+ .flat() },
111
+ __denormalize: function(list){
112
+ list = list
113
+ ?? this.__list
114
+ // handle promise list...
115
+ if(list instanceof Promise){
116
+ var that = this
117
+ return list.then(function(list){
118
+ return that.__denormalize(list) }) }
119
+
120
+ return Promise.all(list)
121
+ .then(function(list){
122
+ return list.flat() }) },
123
+
68
124
 
69
125
  // iterator methods...
70
126
  //
@@ -99,21 +155,36 @@ object.Constructor('IterablePromise', Promise, {
99
155
  map: function(func){
100
156
  return this.constructor(this,
101
157
  function(e){
102
- return [func(e)] }) },
158
+ //return [func(e)] }) },
159
+ var res = func(e)
160
+ return res instanceof Promise ?
161
+ res.then(function(e){
162
+ return [e] })
163
+ : [res] }) },
103
164
  filter: function(func){
104
165
  return this.constructor(this,
105
166
  function(e){
106
- return func(e) ?
107
- [e]
167
+ //return func(e) ?
168
+ // [e]
169
+ // : [] }) },
170
+ var res = func(e)
171
+ return res instanceof Promise ?
172
+ res.then(function(res){
173
+ return res ?
174
+ [e]
175
+ : [] })
176
+ : res ?
177
+ [e]
108
178
  : [] }) },
109
179
  // NOTE: this does not return an iterable promise as we can't know
110
180
  // what the user reduces to...
111
181
  // XXX we could look at the initial state though...
112
182
  // NOTE: the items can be handled out of order because the nested
113
183
  // promises can resolve in any order.
114
- // XXX write how to go around this...
184
+ // XXX doc how to go around this...
115
185
  // NOTE: since order of execution can not be guaranteed there is no
116
186
  // point in implementing .reduceRight(..)
187
+ // XXX should func be able to return a promise???
117
188
  reduce: function(func, res){
118
189
  return this.constructor(this,
119
190
  function(e){
@@ -162,29 +233,10 @@ object.Constructor('IterablePromise', Promise, {
162
233
 
163
234
  // NOTE: these can create an unresolved promise from a resolved
164
235
  // promise...
165
- // XXX EXPEREMENTAL...
166
- // ....can we remove a level of indirection here???
167
- // would be better to use the raw mode...
168
236
  concat: function(other){
169
- var lst = this.__list
170
- return lst instanceof Promise ?
171
- this.constructor([this, other])
172
- .flat()
173
- : other instanceof IterablePromise ?
174
- this.constructor(
175
- lst.concat(other.__list),
176
- 'raw')
177
- : other instanceof Promise ?
178
- this.constructor(
179
- lst.concat(other
180
- .then(function(res){
181
- return res instanceof Array ?
182
- res
183
- : [res] })),
184
- 'raw')
185
- : this.constructor(
186
- // XXX this is cheating -- need a more direct way to form the array...
187
- lst.concat(this.constructor(other).__list),
237
+ return this.constructor(
238
+ this.__list
239
+ .concat(this.__normalize(other)),
188
240
  'raw') },
189
241
  push: function(elem){
190
242
  return this.concat([elem]) },
@@ -268,6 +320,26 @@ object.Constructor('IterablePromise', Promise, {
268
320
  // manually handle the stop...
269
321
  // - another issue here is that the stop would happen in order of
270
322
  // 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)
271
343
  __new__: function(_, list, handler){
272
344
  // instance...
273
345
  var promise
@@ -284,47 +356,10 @@ object.Constructor('IterablePromise', Promise, {
284
356
  IterablePromise)
285
357
 
286
358
  if(promise){
287
-
288
359
  if(handler != 'raw'){
289
- handler = handler
290
- ?? function(e){
291
- return [e] }
292
-
293
- // NOTE: this is recursive to handle expanding nested promises...
294
- var handle = function(elem){
295
- // call the handler...
296
- return (elem && elem.then) ?
297
- //elem.then(function(elem){
298
- // return handler(elem) })
299
- elem.then(handler)
300
- : handler(elem) }
301
-
302
- // handle the list...
303
- // NOTE: we can't .flat() the results here as we need to
304
- // wait till all the promises resolve...
305
- list =
306
- (list instanceof IterablePromise
307
- && !(list.__list instanceof Promise)) ?
308
- // NOTE: this is essentially the same as below but
309
- // with a normalized list as input...
310
- // XXX can we merge the two???
311
- list.__list
312
- .map(function(elems){
313
- return elems instanceof Promise ?
314
- elems.then(function(elems){
315
- return elems
316
- .map(handle)
317
- .flat() })
318
- : elems
319
- .map(handle)
320
- .flat() })
321
- : list instanceof Promise ?
322
- // special case: promised list...
323
- list.then(function(list){
324
- return [list].flat()
325
- .map(handle) })
326
- : [list].flat()
327
- .map(handle) }
360
+ list = list instanceof IterablePromise ?
361
+ this.__handle(list.__list, handler)
362
+ : this.__normalize(list, handler) }
328
363
 
329
364
  Object.defineProperty(obj, '__list', {
330
365
  value: list,
@@ -332,14 +367,9 @@ object.Constructor('IterablePromise', Promise, {
332
367
  })
333
368
 
334
369
  // handle promise state...
335
- ;(list instanceof Promise ?
336
- // special case: promised list...
337
- list
338
- : Promise.all([list].flat()))
339
- .then(function(res){
340
- promise.resolve(handler ?
341
- res.flat()
342
- : res) })
370
+ this.__denormalize(list)
371
+ .then(function(list){
372
+ promise.resolve(list) })
343
373
  .catch(promise.reject) }
344
374
 
345
375
  return obj },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ig-types",
3
- "version": "6.12.1",
3
+ "version": "6.13.2",
4
4
  "description": "Generic JavaScript types and type extensions...",
5
5
  "main": "main.js",
6
6
  "scripts": {
package/test.js CHANGED
@@ -111,45 +111,143 @@ var cases = test.Cases({
111
111
  RegExp: function(assert){
112
112
  },
113
113
 
114
- Promise: function(assert){
114
+ IterablePromise: test.TestSet(function(){
115
+ var create = function(assert, value){
116
+ return {
117
+ input: value,
118
+ output: assert(Promise.iter(value), 'Promise.iter(', value, ')'),
119
+ } }
120
+
121
+ this.Setup({
122
+ empty: function(assert){
123
+ return create(assert, []) },
124
+ value: function(assert){
125
+ return create(assert, 123) },
126
+ array: function(assert){
127
+ return create(assert, [1, 2, 3]) },
128
+ nested_array: function(assert){
129
+ return create(assert, [1, 2, [3]]) },
130
+ promise_value: function(assert){
131
+ return create(assert, Promise.resolve(123)) },
132
+ promise_array: function(assert){
133
+ return create(assert, Promise.resolve([1, 2, 3])) },
134
+ promise_nested_array: function(assert){
135
+ return create(assert, Promise.resolve([1, 2, [3]])) },
136
+ array_mixed: function(assert){
137
+ return create(assert, [1, Promise.resolve(2), 3]) },
138
+ nested_array_mixed: function(assert){
139
+ return create(assert, [
140
+ 1,
141
+ Promise.resolve(2),
142
+ [3],
143
+ Promise.resolve([4]),
144
+ ]) },
145
+ promise_array_mixed: function(assert){
146
+ return create(assert, Promise.resolve([1, Promise.resolve(2), 3])) },
147
+ promise_nested_array_mixed: function(assert){
148
+ return create(assert, Promise.resolve([
149
+ 1,
150
+ Promise.resolve(2),
151
+ [3],
152
+ Promise.resolve([4]),
153
+ ])) },
154
+ })
155
+ this.Modifier({
156
+ nest: function(assert, setup){
157
+ setup.output = Promise.iter(setup.output)
158
+ return setup },
159
+ iter: function(assert, setup){
160
+ setup.output = setup.output.iter()
161
+ return setup },
162
+
163
+ map_asis: function(assert, setup){
164
+ setup.output = setup.output
165
+ .map(function(e){
166
+ return e })
167
+ return setup },
168
+ map_promise: function(assert, setup){
169
+ setup.output = setup.output
170
+ .map(function(e){
171
+ return Promise.resolve(e) })
172
+ return setup },
173
+
174
+ filter_all: function(assert, setup){
175
+ setup.output = setup.output
176
+ .filter(function(e){ return true })
177
+ return setup },
178
+ // XXX either the test is worng or something is broken...
179
+ filter_none: function(assert, setup){
180
+ return {
181
+ input: [],
182
+ output: setup.output
183
+ .filter(function(e){ return false }),
184
+ } },
185
+
186
+ })
187
+ this.Test({
188
+ value: async function(assert, {input, output}){
189
+
190
+ var res = await output
191
+
192
+ assert(res instanceof Array, 'result is array')
193
+
194
+ input instanceof Array ?
195
+ // XXX this does not catch some errors -- map_promise specifically...
196
+ assert.array(res,
197
+ await Promise.all(input),
198
+ 'array -> array')
199
+ : (input instanceof Promise && await input instanceof Array) ?
200
+ assert.array(res,
201
+ await input,
202
+ 'promise array -> array')
203
+ : input instanceof Promise ?
204
+ assert.array(res,
205
+ [await input],
206
+ 'promise value -> array')
207
+ : assert.array(res,
208
+ [input],
209
+ 'value -> array') },
210
+ })
211
+ }),
212
+ Promise: async function(assert){
115
213
  var p = assert(Promise.cooperative(), '.cooperative()')
116
- //var p = assert(promise._CooperativePromise())
117
214
 
118
- assert(!p.isSet, '.isSet is false')
119
-
215
+ assert(!p.isSet, 'promise unset')
216
+
120
217
  var RESOLVE = 123
218
+ var then = false
219
+ var done = false
121
220
 
122
- var then
123
221
  p.then(function(v){
124
- // XXX this does not get printed for some reason...
125
- console.log('!!!!!!!!!!! then')
126
- // XXX this seems not to work/print/count a fail...
127
- assert(false, 'test fail')
128
-
129
- then = v })
222
+ then = assert(v == RESOLVE, '.then(..) handled') })
130
223
 
131
- assert(!p.isSet, '.isSet is false')
132
-
133
- var fin
134
224
  p.finally(function(){
135
- fin = true })
225
+ done = assert(true, '.finally(..) handled') })
136
226
 
137
- assert(!p.isSet, '.isSet is false')
227
+ assert(!p.isSet, 'promise unset')
138
228
 
139
229
  p.set(RESOLVE)
140
230
 
141
- assert(p.isSet, '.isSet')
142
-
143
- // XXX without setTimeout(..) these are run before the
144
- // .then(..) / .finally(..) have a chance to run...
145
- // ...not yet sure how I feel about this...
146
- // XXX with setTimeout(..) these appear not to have ANY effect,
147
- // as if setTimeout(..) did not run...
148
- setTimeout(function(){
149
- assert(false, 'test fail')
150
- assert(then == RESOLVE, '.then(..)')
151
- assert(fin, '.finally(..)')
152
- }, 0)
231
+ assert(p.isSet, 'promise set')
232
+
233
+ // allow the promise to finalize...
234
+ await p
235
+
236
+ assert(then, '.then(..): confirmed')
237
+ assert(done, '.done(..): confirmed')
238
+
239
+ // XXX
240
+
241
+ assert(await Promise.iter([1, Promise.resolve(2), [3]]), '.iter(..)')
242
+
243
+ assert.array(
244
+ await Promise.iter([1, 2, 3]),
245
+ [1, 2, 3],
246
+ 'basic array')
247
+ assert.array(
248
+ await Promise.iter([1, Promise.resolve(2), 3]),
249
+ [1, 2, 3],
250
+ 'promises as elements')
153
251
  },
154
252
 
155
253
  // Date.js