mirror of
https://github.com/flynx/object.js.git
synced 2025-10-29 18:40:08 +00:00
moved code to ig-stoppable...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
dcb1321e6a
commit
6d85d8718c
132
object.js
132
object.js
@ -21,6 +21,12 @@
|
|||||||
(function(require){ var module={} // make module AMD/node compatible...
|
(function(require){ var module={} // make module AMD/node compatible...
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
|
var STOP =
|
||||||
|
module.STOP =
|
||||||
|
require('ig-stoppable').STOP
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
// Function methods to link into a constructor producing a callable
|
// Function methods to link into a constructor producing a callable
|
||||||
// defined via .__call__(..)
|
// defined via .__call__(..)
|
||||||
@ -344,18 +350,6 @@ function(obj){
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Helper objects/constructors...
|
// Helper objects/constructors...
|
||||||
|
|
||||||
// NOTE: these are missing from JavaScript for some reason...
|
|
||||||
//
|
|
||||||
// XXX should these be global???
|
|
||||||
var Generator =
|
|
||||||
module.Generator =
|
|
||||||
(function*(){}).constructor
|
|
||||||
|
|
||||||
var AsyncGenerator =
|
|
||||||
module.AsyncGenerator =
|
|
||||||
(async function*(){}).constructor
|
|
||||||
|
|
||||||
|
|
||||||
BOOTSTRAP(function(){
|
BOOTSTRAP(function(){
|
||||||
|
|
||||||
// Error with some JS quirks fixed...
|
// Error with some JS quirks fixed...
|
||||||
@ -377,119 +371,9 @@ BOOTSTRAP(function(){
|
|||||||
//return Reflect.construct(Error, args, this.constructor) },
|
//return Reflect.construct(Error, args, this.constructor) },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// Value trigger iteration stop and to carry results...
|
|
||||||
//
|
|
||||||
module.STOP =
|
|
||||||
Constructor('STOP', {
|
|
||||||
doc: 'stop iteration.',
|
|
||||||
__init__: function(value){
|
|
||||||
this.value = value },
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// Wrap a callable in a STOP handler
|
|
||||||
//
|
|
||||||
// stoppable(func)
|
|
||||||
// -> func
|
|
||||||
//
|
|
||||||
// stoppable(gen)
|
|
||||||
// -> gen
|
|
||||||
//
|
|
||||||
// stoppable(asyncgen)
|
|
||||||
// -> asyncgen
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// The client callable can be one of:
|
|
||||||
// - function
|
|
||||||
// - generator
|
|
||||||
// - async generator
|
|
||||||
//
|
|
||||||
// The returned callable will be of the same type as the input callable.
|
|
||||||
//
|
|
||||||
// The wrapper handles STOP slightly differently if the client is a
|
|
||||||
// function or if it is a generator / async generator:
|
|
||||||
// - function
|
|
||||||
// STOP returned / thrown
|
|
||||||
// -> return undefined
|
|
||||||
// STOP(value) returned / thrown
|
|
||||||
// -> return value
|
|
||||||
// - generator / async generator
|
|
||||||
// STOP yielded / thrown
|
|
||||||
// -> iteration stops
|
|
||||||
// STOP(value) yielded / thrown
|
|
||||||
// -> value yielded and iteration stops
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// NOTE: this repeats the same code at lest twice, not sure yet how to avoid
|
|
||||||
// this...
|
|
||||||
//
|
|
||||||
// XXX user doc!!!
|
|
||||||
var stoppable =
|
|
||||||
module.stoppable =
|
|
||||||
function(func){
|
|
||||||
return Object.assign(
|
|
||||||
func instanceof Generator ?
|
|
||||||
// NOTE: the only difference between Generator/AsyncGenerator
|
|
||||||
// versions of this is the async keyword -- keep them
|
|
||||||
// in sync...
|
|
||||||
function*(){
|
|
||||||
try{
|
|
||||||
for(var res of func.call(this, ...arguments)){
|
|
||||||
if(res === STOP){
|
|
||||||
return }
|
|
||||||
if(res instanceof STOP){
|
|
||||||
yield res.value
|
|
||||||
return }
|
|
||||||
yield res }
|
|
||||||
} catch(err){
|
|
||||||
if(err === STOP){
|
|
||||||
return
|
|
||||||
} else if(err instanceof STOP){
|
|
||||||
yield err.value
|
|
||||||
return }
|
|
||||||
throw err } }
|
|
||||||
: func instanceof AsyncGenerator ?
|
|
||||||
// NOTE: the only difference between Generator/AsyncGenerator
|
|
||||||
// versions of this is the async keyword -- keep them
|
|
||||||
// in sync...
|
|
||||||
async function*(){
|
|
||||||
try{
|
|
||||||
for(var res of func.call(this, ...arguments)){
|
|
||||||
if(res === STOP){
|
|
||||||
return }
|
|
||||||
if(res instanceof STOP){
|
|
||||||
yield res.value
|
|
||||||
return }
|
|
||||||
yield res }
|
|
||||||
} catch(err){
|
|
||||||
if(err === STOP){
|
|
||||||
return
|
|
||||||
} else if(err instanceof STOP){
|
|
||||||
yield err.value
|
|
||||||
return }
|
|
||||||
throw err } }
|
|
||||||
: function(){
|
|
||||||
try{
|
|
||||||
var res = func.call(this, ...arguments)
|
|
||||||
// NOTE: this is here for uniformity...
|
|
||||||
if(res === STOP){
|
|
||||||
return }
|
|
||||||
if(res instanceof STOP){
|
|
||||||
return res.value }
|
|
||||||
return res
|
|
||||||
} catch(err){
|
|
||||||
if(err === STOP){
|
|
||||||
return
|
|
||||||
} else if(err instanceof STOP){
|
|
||||||
return err.value }
|
|
||||||
throw err } },
|
|
||||||
{ toString: function(){
|
|
||||||
return func.toString() }, }) }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Prototype chain content access...
|
// Prototype chain content access...
|
||||||
@ -523,7 +407,7 @@ function*(obj, name, props=false){
|
|||||||
&& name == '__call__'
|
&& name == '__call__'
|
||||||
&& typeof(obj) == 'function' ?
|
&& typeof(obj) == 'function' ?
|
||||||
obj
|
obj
|
||||||
: obj[name]
|
: obj[name],
|
||||||
] }}
|
] }}
|
||||||
|
|
||||||
// XXX
|
// XXX
|
||||||
@ -1448,6 +1332,8 @@ function(base, ...objects){
|
|||||||
// NOTE: this will also match base...
|
// NOTE: this will also match base...
|
||||||
// NOTE: if base matches directly callback(..) will get undefined as parent
|
// NOTE: if base matches directly callback(..) will get undefined as parent
|
||||||
// NOTE: for more docs on the callback(..) see sources(..)
|
// NOTE: for more docs on the callback(..) see sources(..)
|
||||||
|
//
|
||||||
|
// XXX should this be a generator???
|
||||||
var mixins =
|
var mixins =
|
||||||
module.mixins =
|
module.mixins =
|
||||||
function(base, object, callback){
|
function(base, object, callback){
|
||||||
|
|||||||
@ -28,5 +28,8 @@
|
|||||||
"c8": "^7.3.5",
|
"c8": "^7.3.5",
|
||||||
"colors": "1.4.0",
|
"colors": "1.4.0",
|
||||||
"ig-test": "^1.4.8"
|
"ig-test": "^1.4.8"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ig-stoppable": "^2.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
test.js
32
test.js
@ -328,21 +328,22 @@ var setups = test.Setups({
|
|||||||
method: function(){
|
method: function(){
|
||||||
var x, y
|
var x, y
|
||||||
assert.array(
|
assert.array(
|
||||||
object.values(c, 'x'),
|
[...object._values(c, 'x')],
|
||||||
['c', 'a', 'b'],
|
['c', 'a', 'b'],
|
||||||
'reach all values of attr')
|
'reach all values of attr')
|
||||||
assert.array(
|
assert.array(
|
||||||
object.values(c, 'x', function(v, o){
|
[...object._values(c, 'x')]
|
||||||
return v.toUpperCase() }),
|
.map(function(v){
|
||||||
|
return v.toUpperCase() }),
|
||||||
['C', 'A', 'B'],
|
['C', 'A', 'B'],
|
||||||
'reach all values of attr')
|
'reach all values of attr')
|
||||||
assert.array(
|
assert.array(
|
||||||
object.sources(c, 'method'),
|
[...object._sources(c, 'method')],
|
||||||
// NOTE: not passing an explicit list as we need
|
// NOTE: not passing an explicit list as we need
|
||||||
// to account for mixins...
|
// to account for mixins...
|
||||||
object.sources(c)
|
[...object._sources(c)]
|
||||||
.filter(function(s){
|
.filter(function(s){
|
||||||
return s.hasOwnProperty('method') }),
|
return s.hasOwnProperty('method') }),
|
||||||
'reach all values of method')
|
'reach all values of method')
|
||||||
assert(
|
assert(
|
||||||
(x = object.parent(c, 'x')) == 'b',
|
(x = object.parent(c, 'x')) == 'b',
|
||||||
@ -376,16 +377,17 @@ var setups = test.Setups({
|
|||||||
method(){
|
method(){
|
||||||
// XXX this is almost the same as for js_prototype...
|
// XXX this is almost the same as for js_prototype...
|
||||||
assert.array(
|
assert.array(
|
||||||
object.values(c, 'x'),
|
[...object._values(c, 'x')],
|
||||||
['z', 'y', 'x'],
|
['z', 'y', 'x'],
|
||||||
'reach all values of attr (class)')
|
'reach all values of attr (class)')
|
||||||
assert.array(
|
assert.array(
|
||||||
object.values(c, 'x', function(v, o){
|
[...object._values(c, 'x')]
|
||||||
return v.toUpperCase() }),
|
.map(function(v){
|
||||||
|
return v.toUpperCase() }),
|
||||||
['C', 'A', 'B'],
|
['C', 'A', 'B'],
|
||||||
'reach all values of attr (class)')
|
'reach all values of attr (class)')
|
||||||
assert.array(
|
assert.array(
|
||||||
object.sources(c, 'method'),
|
[...object._sources(c, 'method')],
|
||||||
[Z.prototype, X.prototype],
|
[Z.prototype, X.prototype],
|
||||||
'reach all values of method (class)')
|
'reach all values of method (class)')
|
||||||
assert(
|
assert(
|
||||||
@ -578,12 +580,12 @@ var tests = test.Tests({
|
|||||||
var test = function(obj, name){
|
var test = function(obj, name){
|
||||||
var a, b
|
var a, b
|
||||||
return assert(arrayCmp(
|
return assert(arrayCmp(
|
||||||
a = object.values(obj, '__call__')
|
a = [...object._values(obj, '__call__')]
|
||||||
.map(function(func){
|
.map(function(func){
|
||||||
return func.call(obj) })
|
return func.call(obj) })
|
||||||
.flat(),
|
.flat(),
|
||||||
// get all callables in prototype chain and call them...
|
// get all callables in prototype chain and call them...
|
||||||
b = object.sources(obj)
|
b = [...object._sources(obj)]
|
||||||
.filter(function(o){
|
.filter(function(o){
|
||||||
return typeof(o) == 'function'
|
return typeof(o) == 'function'
|
||||||
|| o.hasOwnProperty('__call__') })
|
|| o.hasOwnProperty('__call__') })
|
||||||
@ -661,11 +663,12 @@ var cases = test.Cases({
|
|||||||
obj.x = 321
|
obj.x = 321
|
||||||
|
|
||||||
assert.array(
|
assert.array(
|
||||||
object.values(obj, 'x', true)
|
[...object._values(obj, 'x', true)]
|
||||||
.map(function(e){ return e.value }),
|
.map(function(e){ return e.value }),
|
||||||
// XXX assert ignores the order here -- this should fail...
|
// XXX assert ignores the order here -- this should fail...
|
||||||
[123, 321], '.values(.., true) ')
|
[123, 321], '.values(.., true) ')
|
||||||
|
|
||||||
|
/* XXX GENERATOR not relevant...
|
||||||
assert(
|
assert(
|
||||||
object.values(obj, 'x', function(){ return object.STOP })[0] == 321,
|
object.values(obj, 'x', function(){ return object.STOP })[0] == 321,
|
||||||
// XXX assert ignores the order here -- this should fail...
|
// XXX assert ignores the order here -- this should fail...
|
||||||
@ -678,6 +681,7 @@ var cases = test.Cases({
|
|||||||
object.values(obj, 'x', function(){ return object.STOP(555) }, true)[0] == 555,
|
object.values(obj, 'x', function(){ return object.STOP(555) }, true)[0] == 555,
|
||||||
// XXX assert ignores the order here -- this should fail...
|
// XXX assert ignores the order here -- this should fail...
|
||||||
'.values(.., func, true) with explicit stop value')
|
'.values(.., func, true) with explicit stop value')
|
||||||
|
//*/
|
||||||
|
|
||||||
},
|
},
|
||||||
deepKeys: function(assert){
|
deepKeys: function(assert){
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user