refacoring and cleanup...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2021-06-27 00:30:55 +03:00
parent 22d4184cfa
commit b4e0f85a4b

143
diff2.js
View File

@ -88,44 +88,30 @@ module.CONTENT =
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// XXX need to think about extension use-cases...
// XXX should we move this to a separate lib??? // XXX should we move this to a separate lib???
var Walk = var Walk =
module.Walk = module.Walk =
object.Constructor('Walk', { object.Constructor('Walk', {
options: {},
handler: undefined, handler: undefined,
listers: undefined, listers: undefined,
normalizePath: undefined, normalizePath: undefined,
// XXX revise .listers format... // NOTE: handler argument always overwrites the value given in options...
// ...do we need nesting??? __init__: function(handler, options){
// ......should it just be an object with a set of methods??
__init__: function(handler, listers, options){
// sanity check... // sanity check...
if(typeof(handler) != 'function'){ if(typeof(handler) != 'function'){
throw new Error('Walk(..): a callable handler us required.') } throw new Error('Walk(..): a callable handler us required.') }
options
&& Object.assign(this, options)
this.handler = this.handler =
handler instanceof types.Generator ? handler instanceof types.Generator ?
handler handler
: Object.assign( : Object.assign(
function*(){ yield handler(...arguments) }, function*(){ yield handler(...arguments) },
{toString: function(){ return handler.toString() }}) {toString: function(){ return handler.toString() }}) },
this.listers = listers || {}
options = options || {}
options = this.options =
!object.parentOf(this.options, options) ?
options
: Object.assign(
// inherit from .constructor.prototype.options...
{__proto__: this.options},
options)
options.normalizePath
&& (this.normalizePath = options.normalizePath) },
__call__: function*(_, obj, path=[], type='root', seen=new Map()){ __call__: function*(_, obj, path=[], type='root', seen=new Map()){
var that = this var that = this
var options = this.options
path = this.normalizePath ? path = this.normalizePath ?
this.normalizePath(path) this.normalizePath(path)
: path : path
@ -148,10 +134,12 @@ object.Constructor('Walk', {
// NOTE: we need this to support throwing STOP... // NOTE: we need this to support throwing STOP...
.iter() .iter()
.filter(function([n, h]){ .filter(function([n, h]){
return h.list return (typeof(h) == 'function' || h.list)
&& !options['no' + n.capitalize()] }) && !this['no' + n.capitalize()] })
.map(function([n, h]){ .map(function([n, h]){
var res = h.list(obj) var res = typeof(h) == 'function' ?
h.call(that.listers, obj)
: h.list(obj)
return res return res
&& [n, res] }) && [n, res] })
.filter(function(e){ .filter(function(e){
@ -181,60 +169,65 @@ object.Constructor('Walk', {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// Format:
// {
// <type>: <func>,
//
// <type>: {
// list: <func>,
// ...
// },
//
// ...
// }
//
var OBJECT_LISTERS = var OBJECT_LISTERS =
module.OBJECT_LISTERS = { module.OBJECT_LISTERS = {
// prevent dissecting null... // prevent dissecting null...
null: { null: function(obj){
list: function(obj){ if(obj === null){
if(obj === null){ throw module.STOP } },
throw module.STOP } } },
set: { set: function(obj){
list: function(obj){ return obj instanceof Set
return obj instanceof Set && [...obj.values()]
&& [...obj.values()] .entries()
.entries() .map(function([k, v]){
.map(function([k, v]){ return [[module.CONTENT, k], v] }) },
return [[module.CONTENT, k], v] }) } }, map: function(obj){
map: { return obj instanceof Map
list: function(obj){ && obj.entries()
return obj instanceof Map .map(function*([k, v], i){
&& obj.entries() yield* [
.map(function*([k, v], i){ [[module.CONTENT, i+'@key'], k],
yield* [ [[module.CONTENT, i], v],
[[module.CONTENT, i+'@key'], k], ] }) },
[[module.CONTENT, i], v],
] }) } },
/* XXX should we handle array elements differently??? /* XXX should we handle array elements differently???
// ...these to simply mark attr type for the handler(..), not // ...these to simply mark attr type for the handler(..), not
// sure if the added complexity is worth it... (???) // sure if the added complexity is worth it... (???)
array: { array: function(obj){
list: function(obj){ return obj instanceof Array
return obj instanceof Array && [...Object.entries(obj)]
&& [...Object.entries(obj)] .filter(function(e){
.filter(function(e){ return !isNaN(parseInt(e)) }) },
return !isNaN(parseInt(e)) }) }}, attr: function(obj){
attr: { return obj instanceof Array ?
list: function(obj){ [...Object.entries(obj)]
return obj instanceof Array ? .filter(function(e){
[...Object.entries(obj)] return isNaN(parseInt(e)) })
.filter(function(e){ : typeof(obj) == 'object'
return isNaN(parseInt(e)) }) && [...Object.entries(obj)] },
: typeof(obj) == 'object'
&& [...Object.entries(obj)] } },
/*/ /*/
attr: { attr: function(obj){
list: function(obj){ return typeof(obj) == 'object'
return typeof(obj) == 'object' && Object.entries(obj) },
&& Object.entries(obj) } },
//*/ //*/
proto: { proto: function(obj){
list: function(obj){ return typeof(obj) == 'object'
return typeof(obj) == 'object' && obj.constructor.prototype !== obj.__proto__
&& obj.constructor.prototype !== obj.__proto__ && [['__proto__', obj.__proto__]] },
&& [['__proto__', obj.__proto__]] }, },
} }
// XXX add function support... // XXX add function support...
@ -261,13 +254,15 @@ Walk(
{type: obj.constructor.name} {type: obj.constructor.name}
: obj, : obj,
] }, ] },
module.OBJECT_LISTERS, {
{ normalizePath: function(path){ listers: module.OBJECT_LISTERS,
return path instanceof Array ? normalizePath: function(path){
path return path instanceof Array ?
: typeof(path) == 'string' ? path
str2path(path) : typeof(path) == 'string' ?
: [] }, }) str2path(path)
: [] },
})