ig-types 6.11.1 → 6.12.0

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 (4) hide show
  1. package/Promise.js +121 -55
  2. package/README.md +106 -19
  3. package/RegExp.js +2 -1
  4. package/package.json +1 -1
package/Promise.js CHANGED
@@ -94,46 +94,43 @@ object.Constructor('IterablePromise', Promise, {
94
94
  // .includes(..)
95
95
  // .some(..) / .every(..)
96
96
  // .sort(..)
97
- // XXX BUG:
98
- // Promise.iter([1,2,3])
99
- // .map(e => e)
100
- // is not the same as:
101
- // Promise.iter([1,2,3])
102
- // .map(e => e)
103
- // .map(e => e)
97
+ //
104
98
  // XXX should these support STOP???
105
99
  map: function(func){
106
- return this.constructor(this.__list.flat(),
100
+ return this.constructor(this,
107
101
  function(e){
108
102
  return [func(e)] }) },
109
103
  filter: function(func){
110
- return this.constructor(this.__list.flat(),
104
+ return this.constructor(this,
111
105
  function(e){
112
106
  return func(e) ?
113
107
  [e]
114
108
  : [] }) },
115
109
  // NOTE: this does not return an iterable promise as we can't know
116
110
  // what the user reduces to...
111
+ // XXX we could look at the initial state though...
112
+ // NOTE: the items can be handled out of order because the nested
113
+ // promises can resolve in any order.
114
+ // XXX write how to go around this...
115
+ // NOTE: since order of execution can not be guaranteed there is no
116
+ // point in implementing .reduceRight(..)
117
117
  reduce: function(func, res){
118
- return this.constructor(this.__list.flat(),
118
+ return this.constructor(this,
119
119
  function(e){
120
120
  res = func(res, e)
121
121
  return [] })
122
122
  .then(function(){
123
123
  return res }) },
124
- /*/ XXX this is wrong...
124
+ /* // XXX since order of execution is not fixed there is no point in
125
+ // adding this.
125
126
  reduceRight: function(func, res){
126
- return this.constructor(this.__list.flat().reverse(),
127
- function(e){
128
- res = func(res, e)
129
- return [] })
130
- .then(function(){
131
- return res }) },
132
- // XXX this is wrong...
133
- reverse: function(){
134
- return this.constructor(this.__list.flat().reverse()) },
127
+ return this
128
+ .reverse()
129
+ .reduce(...arguments)
130
+ .reverse() },
131
+ //*/
135
132
  flat: function(depth=1){
136
- return this.constructor(this.__list.flat(),
133
+ return this.constructor(this,
137
134
  function(e){
138
135
  return (depth > 1
139
136
  && e != null
@@ -142,24 +139,66 @@ object.Constructor('IterablePromise', Promise, {
142
139
  : depth != 0 ?
143
140
  e
144
141
  : [e] }) },
142
+ reverse: function(){
143
+ var lst = this.__list
144
+ return this.constructor(
145
+ lst instanceof Promise ?
146
+ lst.then(function(elems){
147
+ return elems instanceof Array ?
148
+ elems.slice()
149
+ .reverse()
150
+ : elems })
151
+ : lst
152
+ .map(function(elems){
153
+ return elems instanceof Array ?
154
+ elems.slice()
155
+ .reverse()
156
+ : elems instanceof Promise ?
157
+ elems.then(function(elems){
158
+ return elems.reverse() })
159
+ : elems })
160
+ .reverse(),
161
+ 'raw') },
162
+
163
+ // NOTE: these can create an unresolved promise from a resolved
164
+ // promise...
165
+ // XXX EXPEREMENTAL...
166
+ // ....can we remove a level of indirection here???
167
+ // would be better to use the raw mode...
168
+ 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),
188
+ 'raw') },
189
+ push: function(elem){
190
+ return this.concat([elem]) },
191
+ unshift: function(elem){
192
+ return this.constructor([elem])
193
+ .concat(this) },
145
194
 
146
- // compatibility with root promise...
147
- iter: function(){
148
- return this.constructor(this.__list.flat()) },
149
- //*/
150
-
151
195
  // XXX do we need these?
152
196
  // .pop()
153
197
  // .shift()
154
198
  // .first() / .last()
155
- // XXX these can change the "resolved" state...
156
- // ...i.e. return a pending promise when called from a fulfilled
157
- // promise....
158
- // .concat(..)
159
- // .push(..)
160
- // .unshift(..)
161
- // .first(..) / .last(..)
162
-
199
+ // ...would be nice if these could stop everything that's not
200
+ // needed to execute...
201
+
163
202
 
164
203
  // Overload .then(..), .catch(..) and .finally(..) to return a plain
165
204
  // Promise instnace...
@@ -208,8 +247,8 @@ object.Constructor('IterablePromise', Promise, {
208
247
  //
209
248
  // Spectial cases usefull for extending this constructor...
210
249
  //
211
- // Clone the iterator...
212
- // Promise.iter([ .. ], false)
250
+ // Set raw .__list without any pre-processing...
251
+ // Promise.iter([ .. ], 'raw')
213
252
  // -> iterable-promise
214
253
  //
215
254
  // Create a rejected iterator...
@@ -245,29 +284,47 @@ object.Constructor('IterablePromise', Promise, {
245
284
  IterablePromise)
246
285
 
247
286
  if(promise){
248
- // clone/normalize...
249
- list = list
250
- .map(function(e){
251
- return (e && e.then) ?
252
- e.then(function(e){
253
- return [e] })
254
- : [e] })
255
-
256
- if(handler){
287
+
288
+ if(handler != 'raw'){
289
+ handler = handler
290
+ ?? function(e){
291
+ return [e] }
292
+
257
293
  // NOTE: this is recursive to handle expanding nested promises...
258
294
  var handle = function(elem){
259
295
  // call the handler...
260
296
  return (elem && elem.then) ?
261
- elem.then(function(elems){
262
- return elems
263
- .map(handle)
264
- .flat() })
265
- : elem
266
- .map(handler)
267
- .flat() }
297
+ //elem.then(function(elem){
298
+ // return handler(elem) })
299
+ elem.then(handler)
300
+ : handler(elem) }
268
301
 
269
302
  // handle the list...
270
- list = list.map(handle) }
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) }
271
328
 
272
329
  Object.defineProperty(obj, '__list', {
273
330
  value: list,
@@ -275,9 +332,14 @@ object.Constructor('IterablePromise', Promise, {
275
332
  })
276
333
 
277
334
  // handle promise state...
278
- Promise.all(list)
335
+ ;(list instanceof Promise ?
336
+ // special case: promised list...
337
+ list
338
+ : Promise.all([list].flat()))
279
339
  .then(function(res){
280
- promise.resolve(res.flat()) })
340
+ promise.resolve(handler ?
341
+ res.flat()
342
+ : res) })
281
343
  .catch(promise.reject) }
282
344
 
283
345
  return obj },
@@ -483,6 +545,10 @@ var PromiseProtoMixin =
483
545
  module.PromiseProtoMixin =
484
546
  object.Mixin('PromiseProtoMixin', 'soft', {
485
547
  as: ProxyPromise,
548
+
549
+ // XXX
550
+ iter: function(){
551
+ return IterablePromise(this) },
486
552
  })
487
553
 
488
554
  PromiseProtoMixin(Promise.prototype)
package/README.md CHANGED
@@ -70,8 +70,13 @@ Library of JavaScript type extensions, types and utilities.
70
70
  - [`<promise-coop>.then(..)`](#promise-coopthen)
71
71
  - [Promise iteration](#promise-iteration)
72
72
  - [`Promise.iter(..)` / `promise.IterablePromise(..)`](#promiseiter--promiseiterablepromise)
73
+ - [`<promise>.iter()`](#promiseiter)
74
+ - [`<promise-iter>.iter()`](#promise-iteriter)
73
75
  - [`<promise-iter>.map(..)` / `<promise-iter>.filter(..)` / `<promise-iter>.reduce(..)`](#promise-itermap--promise-iterfilter--promise-iterreduce)
74
76
  - [`<promise-iter>.flat(..)`](#promise-iterflat)
77
+ - [`<promise-iter>.reverse()`](#promise-iterreverse)
78
+ - [`<promise-iter>.concat(..)`](#promise-iterconcat)
79
+ - [`<promise-iter>.push(..)` / `<promise-iter>.unshift(..)`](#promise-iterpush--promise-iterunshift)
75
80
  - [`<promise-iter>.then(..)` / `<promise-iter>.catch(..)` / `<promise-iter>.finally(..)`](#promise-iterthen--promise-itercatch--promise-iterfinally)
76
81
  - [Advanced handler](#advanced-handler)
77
82
  - [Promise proxies](#promise-proxies)
@@ -1452,8 +1457,8 @@ promise, and it is similar to a _generator_ in that it allows iteration over the
1452
1457
  contained values and chaining of operations but unlike `Promise.all(..)` this
1453
1458
  iteration occurs depth-first instead of breadth first.
1454
1459
 
1455
- Essentially one can think of _promise iterators_ vs. _generators_ as the former
1456
- being internally controlled and asynchronous while the later being externally
1460
+ One can think of _promise iterators_ vs. _generators_ as the former being
1461
+ internally controlled and asynchronous while the later being externally
1457
1462
  controlled and synchronous.
1458
1463
 
1459
1464
  Here is a traditional example using `Promise.all(..)`:
@@ -1515,8 +1520,32 @@ XXX should we support infinite generators as input?
1515
1520
  #### `Promise.iter(..)` / `promise.IterablePromise(..)`
1516
1521
 
1517
1522
  Create an _iterable promise_
1523
+
1518
1524
  ```bnf
1519
1525
  Promise.iter(<array>)
1526
+ Promise.iter(<promise>)
1527
+ -> <promise-iter>
1528
+ ```
1529
+
1530
+ #### `<promise>.iter()`
1531
+
1532
+ Wrap a promise in an promise iterator.
1533
+
1534
+ ```bnf
1535
+ <promise>.iter()
1536
+ -> <promise-iter>
1537
+ ```
1538
+
1539
+ If `<promise>` resolves to a non-array value it will be treated as a single
1540
+ element, otherwise the array will be iterated over.
1541
+
1542
+
1543
+ #### `<promise-iter>.iter()`
1544
+
1545
+ Return a shallow copy of the current promise iterator.
1546
+
1547
+ ```bnf
1548
+ <promise-iter>.iter()
1520
1549
  -> <promise-iter>
1521
1550
  ```
1522
1551
 
@@ -1545,7 +1574,7 @@ and [`.reduce(..)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe
1545
1574
 
1546
1575
  ```bnf
1547
1576
  <promise-iter>.reduce(<handler>, <state>)
1548
- -> <promise-iter>
1577
+ -> <promise>
1549
1578
 
1550
1579
  <handler>(<state>, <elem>)
1551
1580
  -> <state>
@@ -1558,6 +1587,15 @@ Note that these are different to `Array`'s equivalents in some details:
1558
1587
  this is because the index with _out-of-order_ and _depth-first_ execution the
1559
1588
  index is unknowable and the container is a promise/black-box.
1560
1589
 
1590
+ This is especially critical for `.reduce(..)` as iteration in an order different
1591
+ from the order of elements _can_ affect actual result if this is not expected.
1592
+
1593
+ `.reduce(..)` is also a bit different here in that it will return a basic
1594
+ `<promise>` object as we can't know what will it will reduce to.
1595
+
1596
+ Note that since `.reduce(..)` order can not be guaranteed there is no point
1597
+ in implementing `.reduceRigth(..)`.
1598
+
1561
1599
 
1562
1600
  #### `<promise-iter>.flat(..)`
1563
1601
 
@@ -1570,6 +1608,44 @@ Note that these are different to `Array`'s equivalents in some details:
1570
1608
  This is similar to [`<array>.flat(..)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) see it for more info.
1571
1609
 
1572
1610
 
1611
+ #### `<promise-iter>.reverse()`
1612
+
1613
+ ```bnf
1614
+ <promise-iter>.reverse()
1615
+ -> <promise-iter>
1616
+ ```
1617
+
1618
+ This is deferent from `<array>.reverse()` in that it will _not_ reverse in-place,
1619
+ but rather a _reversed copy_ will be created.
1620
+
1621
+ This is similar to [`<array>.reverse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) see it for more info.
1622
+
1623
+
1624
+ #### `<promise-iter>.concat(..)`
1625
+
1626
+ ```bnf
1627
+ <promise-iter>.concat(<other>)
1628
+ -> <promise-iter>
1629
+ ```
1630
+
1631
+ This is similar to [`<array>.concat(..)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) see it for more info.
1632
+
1633
+
1634
+ #### `<promise-iter>.push(..)` / `<promise-iter>.unshift(..)`
1635
+
1636
+ ```bnf
1637
+ <promise-iter>.push(<elem>)
1638
+ -> <promise-iter>
1639
+
1640
+ <promise-iter>.unshift(<elem>)
1641
+ -> <promise-iter>
1642
+ ```
1643
+
1644
+ These are similar to [`<array>.push(..)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push)
1645
+ and [`<array>.unshift(..)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift)
1646
+ see them for more info.
1647
+
1648
+
1573
1649
  #### `<promise-iter>.then(..)` / `<promise-iter>.catch(..)` / `<promise-iter>.finally(..)`
1574
1650
 
1575
1651
  An extension to
@@ -1587,40 +1663,51 @@ can be useful to hide the extended promise API from further code.
1587
1663
  #### Advanced handler
1588
1664
 
1589
1665
  ```bnf
1590
- Promise.iter(<block-array>, <handler>)
1666
+ Promise.iter(<block>, <handler>)
1591
1667
  -> <iterable-promise>
1668
+ ```
1592
1669
 
1593
- <handler>(<elem>)
1594
- -> [ <elems> ]
1670
+ The `<handler>` will get passed each resolved `<value>` of the input `<block>`
1671
+ as soon as it's available/resolved.
1672
+
1673
+ The `<handler>` return value is unwrapped into the resulting array, allowing
1674
+ each call to both remove elements (i.e. returning `[]`) from the resulting
1675
+ `<block>` as well as insert multiple items (by returning an array of items).
1676
+
1677
+ <!-- XXX returning promises from handler needs to be documented/tested... -->
1678
+
1679
+ ```bnf
1680
+ <handler>(<value>)
1681
+ -> []
1682
+ -> [ <elem>, .. ]
1683
+ -> <non-array>
1595
1684
  ```
1596
1685
 
1597
1686
  ```bnf
1598
- <block-array> ::=
1687
+ <block> ::=
1599
1688
  []
1600
- | [ <block-elem>, .. ]
1689
+ | [ <elem>, .. ]
1601
1690
 
1602
- <block-elem> ::=
1603
- []
1604
- | [ <value>, .. ]
1605
- | <promise>
1606
- | <non-array>
1691
+ <elem> ::=
1692
+ <value>
1693
+ | <promise>(<value>)
1607
1694
  ```
1608
1695
 
1609
1696
  Example:
1610
1697
  ```javascript
1611
1698
  var p = Promise.iter(
1612
- // NOTE: if you want an element to explicitly be an array wrap it in
1613
- // an array -- like the last element here...
1614
- [[1, 2], 3, Promise.resolve(4), [[5, 6]]],
1699
+ [1, 2, 3, Promise.resolve(4), [5, 6]],
1615
1700
  function(elem){
1701
+ // duplicate even numbers...
1616
1702
  return elem % 2 == 0 ?
1617
1703
  [elem, elem]
1704
+ // return arrays as-is...
1618
1705
  : elem instanceof Array ?
1619
- [elem]
1706
+ [elem]
1707
+ // remove other elements...
1620
1708
  : [] })
1621
1709
  .then(function(lst){
1622
- console.log(lst) // -> [2, 2, 4, 4, [5, 6]]
1623
- })
1710
+ console.log(lst) }) // -> [2, 2, 4, 4, [5, 6]]
1624
1711
  ```
1625
1712
 
1626
1713
 
package/RegExp.js CHANGED
@@ -64,7 +64,8 @@ object.Mixin('RegExpProtoMixin', 'soft', {
64
64
 
65
65
 
66
66
  RegExpMixin(RegExp)
67
- RegExpProtoMixin(RegExp.prototype)
67
+ // XXX EXPEREMENTAL...
68
+ //RegExpProtoMixin(RegExp.prototype)
68
69
 
69
70
 
70
71
  var quoteRegExp =
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ig-types",
3
- "version": "6.11.1",
3
+ "version": "6.12.0",
4
4
  "description": "Generic JavaScript types and type extensions...",
5
5
  "main": "main.js",
6
6
  "scripts": {