ig-types 6.10.0 → 6.11.1

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
@@ -492,6 +492,7 @@ object.Mixin('ArrayProtoMixin', 'soft', {
492
492
  smap: stoppableList('map'),
493
493
  sfilter: stoppableList('filter'),
494
494
  sreduce: stoppableValue('reduce'),
495
+ sreduceRight: stoppableValue('reduceRight'),
495
496
  sforEach: stoppableValue('map', true),
496
497
 
497
498
  // Chunk iteration...
package/Promise.js CHANGED
@@ -80,12 +80,13 @@ object.Constructor('IterablePromise', Promise, {
80
80
  // NOTE: these are different to Array's equivalents in that the handler
81
81
  // is called not in the order of the elements but rather in order
82
82
  // of promise resolution...
83
- // NOTE: index of items is unknowable because items can expand on
83
+ // NOTE: index of items is unknowable because items can expand and
84
84
  // contract depending on handlrs (e.g. .filter(..) can remove
85
85
  // items)...
86
86
  // This the following can not be implemented here:
87
87
  // .slice(..)
88
88
  // .splice(..)
89
+ // .values() / .keys()
89
90
  // .at(..)
90
91
  // [Symbol.iterator]() - needs to be sync...
91
92
  // The followng methods are questionable:
@@ -93,36 +94,61 @@ object.Constructor('IterablePromise', Promise, {
93
94
  // .includes(..)
94
95
  // .some(..) / .every(..)
95
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)
96
104
  // XXX should these support STOP???
97
105
  map: function(func){
98
- return this.constructor(this.__list,
106
+ return this.constructor(this.__list.flat(),
99
107
  function(e){
100
108
  return [func(e)] }) },
101
109
  filter: function(func){
102
- return this.constructor(this.__list,
110
+ return this.constructor(this.__list.flat(),
103
111
  function(e){
104
112
  return func(e) ?
105
113
  [e]
106
114
  : [] }) },
115
+ // NOTE: this does not return an iterable promise as we can't know
116
+ // what the user reduces to...
107
117
  reduce: function(func, res){
108
- return this.constructor(this.__list,
118
+ return this.constructor(this.__list.flat(),
109
119
  function(e){
110
120
  res = func(res, e)
111
121
  return [] })
112
122
  .then(function(){
113
123
  return res }) },
124
+ /*/ XXX this is wrong...
125
+ 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()) },
114
135
  flat: function(depth=1){
115
- return this.constructor(this.__list,
136
+ return this.constructor(this.__list.flat(),
116
137
  function(e){
117
- return (e && e.flat) ?
118
- e.flat(depth)
119
- : e }) },
120
- // XXX do we need this???
121
- //iter: function(){
122
- // return this },
123
-
124
-
125
- // XXX do we need:
138
+ return (depth > 1
139
+ && e != null
140
+ && e.flat) ?
141
+ e.flat(depth-1)
142
+ : depth != 0 ?
143
+ e
144
+ : [e] }) },
145
+
146
+ // compatibility with root promise...
147
+ iter: function(){
148
+ return this.constructor(this.__list.flat()) },
149
+ //*/
150
+
151
+ // XXX do we need these?
126
152
  // .pop()
127
153
  // .shift()
128
154
  // .first() / .last()
@@ -204,9 +230,8 @@ object.Constructor('IterablePromise', Promise, {
204
230
  // - another issue here is that the stop would happen in order of
205
231
  // execution and not order of elements...
206
232
  __new__: function(_, list, handler){
207
- var promise
208
-
209
233
  // instance...
234
+ var promise
210
235
  var obj = Reflect.construct(
211
236
  IterablePromise.__proto__,
212
237
  [function(resolve, reject){
@@ -220,49 +245,29 @@ object.Constructor('IterablePromise', Promise, {
220
245
  IterablePromise)
221
246
 
222
247
  if(promise){
223
- //var __stop = false
224
- // apply handler(..) to the list...
225
- //
226
- // NOTE: the top level promises are not wrapped in arrays...
227
- list =
228
- // apply the handler...
229
- handler ?
230
- // XXX can we handle STOP here???
231
- // ...we will not be able to stop already started
232
- // promises...
233
- list.map(function(block){
234
- //* XXX STOP...
235
- return (block instanceof Array ?
236
- block
237
- : [block])
238
- /*/
239
- // NOTE: we are not using Array's .iter() so as to
240
- // keep the dependency minimal...
241
- return generator.iter(
242
- block instanceof Array ?
243
- block
244
- : [block])
245
- //*/
246
- .map(function(e){
247
- // NOTE: we are counting actual expanded
248
- // values and not the "blocks"...
249
- return (e && e.then && e.catch) ?
250
- // promise...
251
- e.then(function(v){
252
- return handler(v) })
253
- // basic value...
254
- : handler(e) }) })
255
- .flat()
256
- // XXX STOP
257
- //.toArray()
258
- // normal constructor...
259
- : handler === undefined ?
260
- list.map(function(e){
261
- return e instanceof Promise ?
262
- e
263
- : [e] })
264
- // clone...
265
- : list.slice()
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){
257
+ // NOTE: this is recursive to handle expanding nested promises...
258
+ var handle = function(elem){
259
+ // call the handler...
260
+ return (elem && elem.then) ?
261
+ elem.then(function(elems){
262
+ return elems
263
+ .map(handle)
264
+ .flat() })
265
+ : elem
266
+ .map(handler)
267
+ .flat() }
268
+
269
+ // handle the list...
270
+ list = list.map(handle) }
266
271
 
267
272
  Object.defineProperty(obj, '__list', {
268
273
  value: list,
@@ -415,6 +420,51 @@ object.Constructor('CooperativePromise', Promise, {
415
420
 
416
421
 
417
422
 
423
+ //---------------------------------------------------------------------
424
+
425
+ // XXX EXPEREMENTAL...
426
+ var ProxyPromise =
427
+ module.ProxyPromise =
428
+ object.Constructor('ProxyPromise', Promise, {
429
+ __new__: function(context, constructor){
430
+ var proto = 'prototype' in constructor ?
431
+ constructor.prototype
432
+ : constructor
433
+ var obj = Reflect.construct(
434
+ ProxyPromise.__proto__,
435
+ [function(resolve, reject){
436
+ context.then(resolve)
437
+ context.catch(reject) }],
438
+ ProxyPromise)
439
+ // populate...
440
+ // NOTE: we are not using object.deepKeys(..) here as we need
441
+ // the key origin not to trigger property getters...
442
+ var seen = new Set()
443
+ while(proto != null){
444
+ Object.entries(Object.getOwnPropertyDescriptors(proto))
445
+ .forEach(function([key, value]){
446
+ // skip overloaded keys...
447
+ if(seen.has(key)){
448
+ return }
449
+ // skip non-functions...
450
+ if(typeof(value.value) != 'function'){
451
+ return }
452
+ // skip non-enumerable except for Object.prototype.run(..)...
453
+ if(!(key == 'run'
454
+ && Object.prototype.run === value.value)
455
+ && !value.enumerable){
456
+ return }
457
+ // proxy...
458
+ obj[key] = function(...args){
459
+ // XXX should we also .catch(..) here???
460
+ return context.then(function(res){
461
+ return res[key](...args) }) } })
462
+ proto = proto.__proto__ }
463
+ return obj },
464
+ })
465
+
466
+
467
+
418
468
  //---------------------------------------------------------------------
419
469
 
420
470
  var PromiseMixin =
@@ -425,10 +475,19 @@ object.Mixin('PromiseMixin', 'soft', {
425
475
  cooperative: CooperativePromise,
426
476
  })
427
477
 
428
-
429
478
  PromiseMixin(Promise)
430
479
 
431
480
 
481
+ // XXX EXPEREMENTAL...
482
+ var PromiseProtoMixin =
483
+ module.PromiseProtoMixin =
484
+ object.Mixin('PromiseProtoMixin', 'soft', {
485
+ as: ProxyPromise,
486
+ })
487
+
488
+ PromiseProtoMixin(Promise.prototype)
489
+
490
+
432
491
 
433
492
 
434
493
  /**********************************************************************
package/README.md CHANGED
@@ -74,6 +74,9 @@ Library of JavaScript type extensions, types and utilities.
74
74
  - [`<promise-iter>.flat(..)`](#promise-iterflat)
75
75
  - [`<promise-iter>.then(..)` / `<promise-iter>.catch(..)` / `<promise-iter>.finally(..)`](#promise-iterthen--promise-itercatch--promise-iterfinally)
76
76
  - [Advanced handler](#advanced-handler)
77
+ - [Promise proxies](#promise-proxies)
78
+ - [`<promise>.as(..)`](#promiseas)
79
+ - [`<promise-proxy>.<method>(..)`](#promise-proxymethod)
77
80
  - [Generator extensions and utilities](#generator-extensions-and-utilities)
78
81
  - [The basics](#the-basics)
79
82
  - [`generator.Generator`](#generatorgenerator)
@@ -1621,6 +1624,56 @@ var p = Promise.iter(
1621
1624
  ```
1622
1625
 
1623
1626
 
1627
+ ### Promise proxies
1628
+
1629
+ _Promise proxies_ generate a set of prototype methods returning promises that when the parent promise is resolved will resolve to a specific method call.
1630
+
1631
+ Example:
1632
+ ```javascript
1633
+ var o = {
1634
+ method: function(...args){
1635
+ console.log('method:', ...args)
1636
+ },
1637
+ }
1638
+
1639
+ var p = Peomise.cooperative().as(o)
1640
+
1641
+ p.method(1, 2, 3) // returns a promise...
1642
+
1643
+ // ...
1644
+
1645
+ // resolving a promise will trigger all the proxy emthod execution, so
1646
+ // here 'method: 1, 2, 3' will get printed...
1647
+ p.set(o)
1648
+
1649
+ ```
1650
+
1651
+ #### `<promise>.as(..)`
1652
+
1653
+ Create a promise proxy
1654
+
1655
+ ```bnf
1656
+ <promise>.as(<object>)
1657
+ <promise>.as(<constructor>)
1658
+ -> <promise-proxy>
1659
+ ```
1660
+
1661
+ A proxy promise will be populated with proxy methods to all the methods of the `<object>` or `<constructor>.prototype`.
1662
+
1663
+ #### `<promise-proxy>.<method>(..)`
1664
+
1665
+ When `<promise>` resolves, call the `.<method>(..)` on the resolved value.
1666
+
1667
+ ```bnf
1668
+ <promise-proxy>.<method>(..)
1669
+ -> <method-promise>
1670
+ ```
1671
+
1672
+ `<method-promise>` will resolve the the return value of the `<method>` when
1673
+ the main `<promise>` is resolved.
1674
+
1675
+
1676
+
1624
1677
  ## Generator extensions and utilities
1625
1678
 
1626
1679
  ```javascript
package/event.js CHANGED
@@ -63,6 +63,11 @@ module.TRIGGER = module.EventCommand('TRIGGER')
63
63
  // -> true
64
64
  // -> false
65
65
  //
66
+ // trigger event handlers and overload handler arguments...
67
+ // handle(true, ...)
68
+ // -> true
69
+ // -> false
70
+ //
66
71
  // prevent event handlers from triggering...
67
72
  // handle(false)
68
73
  // -> undefined
@@ -151,11 +156,15 @@ object.Constructor('Eventful', {
151
156
  // NOTE: to explicitly disable calling the handlers func must
152
157
  // call handle(false)
153
158
  var did_handle = false
154
- var handle = function(run=true){
159
+ var handle = function(run=true, ...alt_args){
155
160
  did_handle = true
156
- var a = args[0] instanceof EventCommand ?
157
- args.slice(1)
161
+ var a = (run === true
162
+ && arguments.length > 1) ?
163
+ alt_args
158
164
  : args
165
+ a = a[0] instanceof EventCommand ?
166
+ a.slice(1)
167
+ : a
159
168
  return run ?
160
169
  handlers
161
170
  .reduce(function(res, handler){
package/generator.js CHANGED
@@ -210,6 +210,7 @@ object.Mixin('GeneratorMixin', 'soft', {
210
210
  map: makeGenerator('map'),
211
211
  filter: makeGenerator('filter'),
212
212
  reduce: makeGenerator('reduce'),
213
+ reduceRight: makeGenerator('reduceRight'),
213
214
 
214
215
  // non-generators...
215
216
  //
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ig-types",
3
- "version": "6.10.0",
3
+ "version": "6.11.1",
4
4
  "description": "Generic JavaScript types and type extensions...",
5
5
  "main": "main.js",
6
6
  "scripts": {