| @@ -0,0 +1,318 @@ | |||
| var utils = require("../bbhverse-pb-wip/utils") | |||
| var js = utils.js; | |||
| function asyncDynamicTaskStream(opts){ | |||
| const design = { | |||
| create(){ | |||
| var conceptspace = 0; // 32 bit to start with. | |||
| var next = 1; | |||
| var all = 0; | |||
| var segments = []; | |||
| var __concepts = {}; | |||
| var __entagledRefs = new WeakMap(); | |||
| function assert(concept, multi){ return __concepts[concept].spin ? !(concept.id & multi) : (concept.id & multi) } | |||
| function define_exclusions(exclusions, tangle){ | |||
| // Note : Do not store references to concept.entanglement as this is switched on update. | |||
| if(exclusions.length < 2) throw 'Why would we call define_exclusions on a single or no item ? At the least 2 items are needed for mutual exclusion.' | |||
| var results = []; | |||
| // if any 2 concepts were setup as independent concpts they can later be entangled as mutual exclusion here. | |||
| var entanglement = { unsync : 0 }; // Set of entagled bits including self. | |||
| var entaglements = []; | |||
| var maskForSet = 0; | |||
| __entagledRefs.set(entanglement, entaglements); | |||
| var __entangledFn = (exclusion)=>{ // entaglement object has been fixed for all => collapse all previous. | |||
| entanglement.unsync |= exclusion.entanglement.unsync | exclusion.id ; | |||
| var collapsibles = __entagledRefs.get(exclusion.entanglement); | |||
| if(collapsibles) { collapsibles.forEach(collapsible => { collapsible.entanglement = entanglement; }) } | |||
| __entagledRefs.delete(exclusion.entanglement); | |||
| exclusion.entanglement = entanglement; | |||
| entaglements.push(exclusion); | |||
| } | |||
| var entangledFn = (exclusion)=>{ // entaglement object has not yet been fixed => replace. | |||
| exclusion.entanglement.unsync |= entanglement.unsync | exclusion.id ; | |||
| var collapsibles = __entagledRefs.get(entanglement); | |||
| if(collapsibles){ collapsibles.forEach(collapsible => { collapsible.entanglement = exclusion.entanglement; }) } | |||
| __entagledRefs.delete(entanglement); | |||
| entanglement = exclusion.entanglement; | |||
| entaglements = __entagledRefs.get(entanglement); | |||
| entangledFn = __entangledFn; | |||
| } | |||
| var __tangle = Object.assign({}, tangle); | |||
| // __tangle.unsync = __tangle.unsync & ~__tangle.insync; | |||
| // __tangle.insync |= __concept.results[0].id; | |||
| for(var i = 0; i < exclusions.length; i++) { | |||
| var innerexclusions = __concepts[exclusions[i]] ? __concepts[exclusions[i]] : define(exclusions[i], __tangle); | |||
| __tangle.unsync |= innerexclusions.results[0].id //| innerexclusions.results[0].entanglement.insync; | |||
| innerexclusions.results.forEach(exclusion=>{ | |||
| (exclusion.entanglement) ? entangledFn(exclusion) // previously entangled. | |||
| : (()=>{ | |||
| entanglement.unsync |= exclusion.id; | |||
| exclusion.entanglement = entanglement; | |||
| entaglements.push(exclusion) | |||
| })() | |||
| results.push(exclusion) | |||
| maskForSet |= exclusion.id; | |||
| }); | |||
| } | |||
| return { results : results, maskForSet : maskForSet} ; | |||
| } | |||
| function define_string(concept, tangle) { | |||
| all |= next; | |||
| __concepts[concept] = { id : next, entanglement : Object.assign({}, tangle) }; // self is included in entanglement. | |||
| __entagledRefs.set(__concepts[concept].entanglement, [__concepts[concept]] ) | |||
| next = next << 1; | |||
| return { results : [__concepts[concept]], maskForSet : __concepts[concept].id }; | |||
| } | |||
| function define_array(concepts, tangle) { | |||
| if(concepts.length > 1) return define_exclusions(concepts, tangle); | |||
| else return define(concepts[0], tangle) | |||
| } | |||
| function define_object(concepts, tangle){ | |||
| var results = []; | |||
| var maskForSet = 0; | |||
| tangle = tangle || {}; | |||
| Object.keys(concepts).forEach(concept => { | |||
| var __concept = define(concept, tangle); | |||
| results.push.apply(results, __concept.results) | |||
| var __tangle = Object.assign({}, __concept.results[0].entanglement); | |||
| __tangle.insync |= __concept.results[0].id | tangle.insync; | |||
| __tangle.unsync |= tangle.unsync; | |||
| var isconcept = define( concepts[concept][0], __tangle ) | |||
| __tangle = Object.assign({}, __concept.results[0].entanglement); | |||
| __tangle.unsync |= tangle.unsync | __concept.results[0].id; | |||
| var notconcept = define( concepts[concept][1], __tangle ) | |||
| if(notconcept && notconcept.results) { | |||
| __concept.results[0].entanglement.unsync |= notconcept.maskForSet; | |||
| maskForSet |= __concept.maskForSet | notconcept.maskForSet ; | |||
| } | |||
| if(isconcept && isconcept.results) { | |||
| __concept.results[0].entanglement.insync |= isconcept.maskForSet; | |||
| maskForSet |= __concept.maskForSet | isconcept.maskForSet ; | |||
| } | |||
| }); | |||
| results[0].entanglement.insync = maskForSet; | |||
| return { results : results, maskForSet : maskForSet }; | |||
| } | |||
| const conceptvariants = Object.assign(utils.__TPL__typeHandlers, { | |||
| '[object String]' : define_string | |||
| , '[object Array]' : define_array | |||
| , '[object Object]' : define_object | |||
| , '[object Undefined]' : ()=>{} // Ignore | |||
| }) | |||
| function define(concept, tangle){ | |||
| return conceptvariants[Object.prototype.toString.call(concept)](concept, tangle); | |||
| } | |||
| function reveal(){ console.dir(__concepts) } | |||
| return { define, reveal } | |||
| } | |||
| } | |||
| const coexstates = { | |||
| create(){ | |||
| var conceptspace = 0; // 32 bit to start with. | |||
| var next = 1; | |||
| var all = 0; | |||
| var segments = []; | |||
| var __concepts = {}; | |||
| var __entagledRefs = new WeakMap(); | |||
| var __tango = { // JS : Need a hash with integer keys for performance | |||
| // Eg: | |||
| // number matches key as a mask | |||
| // all bits in assertions bits get turned on and negations are turned off. | |||
| // number doesn't match key as a mask | |||
| // independents ? or | |||
| // all bits in assertions bits get turned off and negations are turned on. | |||
| // 0b1011110 : [ | |||
| // 0b1010000 // assertions : bits that are in sync. | |||
| // , 0b0001110 // negations : bits that are off sync. | |||
| // ] | |||
| } | |||
| // Tango Entaglement internal model Specs - These are permissable constraints for 2^n bit variations. | |||
| // Key = any concept bit | |||
| var t = { 0b00100000 /* a concept bit */ : [ | |||
| /* concept bit is on - entangled coexistence with the state of concept bit.. */ | |||
| [ | |||
| // all these bits must be turned off i.e these bits cannot co exist when the primary bit is turned on. | |||
| /* cannot coexit */ 0b00100110 // index 0 => 0 bits in this mask can coexit except for one bit which is the main concept bit which is included in this mask. | |||
| // Group constraints are not relevant here so not an array. | |||
| , /* any one bit within a group can coexit */ [ 0b00101001 /*, ...othergroups Eg: 0b11000000*/ ] | |||
| // each item in the array represents a constrained group of bits. | |||
| // index 1 => 1 bit in this mask can coexit with the main concept bit which is included in this mask. | |||
| // /*any n bits can coexit */ // index n => n bits in this mask can coexit with the main concept bit which is included in this mask. | |||
| // index i=1 to n each have 2^i variations each. At this level we have abstract nondeterministic view until all the bits computation results fix and reduce the result domain. | |||
| // Until such time they remain potential possibilities and which specific bits are on is ambiguious. | |||
| // all these bits must be turned on. | |||
| , /*all these bits have to exist with this state (must coexit)*/ 0b00110000 | |||
| // can be collapsed to 1 single group. | |||
| ] | |||
| // independent bits where there is no entanglement are not stored. There can be an infinite or a large number of independent bits. | |||
| , /* concept bit is off */ | |||
| [ | |||
| 0 // all these bits must be turned off. | |||
| // one or more permissible | |||
| , [0] // Index 1 - any one is permissible from the none can coexit category since main bit is off. | |||
| // /*index (1 -> n) =>any n bits may be turned on in opposition */ | |||
| //all these bits must be turned on. | |||
| , /*all these bits have to exist with this state in opposition*/ 0b11000000 | |||
| ] | |||
| ] | |||
| } | |||
| (()=>{ | |||
| var cannotCoexist = 0; | |||
| for(var i = 1; i < t[0b00100000][0].length; i++) { cannotCoexist |= t[0b00100000][0][i] } | |||
| t[0b00100000][1][0] |= cannotCoexist; | |||
| })() | |||
| (()=>{ | |||
| var cannotCoexist = 0; | |||
| for(var i = 1; i < t[0b00100000][1].length; i++) { cannotCoexist |= t[0b00100000][1][i] } | |||
| t[0b00100000][0][0] |= cannotCoexist; | |||
| })() | |||
| t[0b00100000][1][1] |= t[0b00100000][0][0] | |||
| function define_exclusions(exclusions, tangle){ | |||
| // Note : Do not store references to concept.entanglement as this is switched on update. | |||
| if(exclusions.length < 2) throw 'Why would we call define_exclusions on a single or no item ? At the least 2 items are needed for mutual exclusion.' | |||
| var results = []; | |||
| // if any 2 concepts were setup as independent concpts they can later be entangled as mutual exclusion here. | |||
| var entanglement = { unsync : 0 }; // Set of entagled bits including self. | |||
| var entaglements = []; | |||
| var maskForSet = 0; | |||
| __entagledRefs.set(entanglement, entaglements); | |||
| var __entangledFn = (exclusion)=>{ // entaglement object has been fixed for all => collapse all previous. | |||
| entanglement.unsync |= exclusion.entanglement.unsync | exclusion.id ; | |||
| var collapsibles = __entagledRefs.get(exclusion.entanglement); | |||
| if(collapsibles) { collapsibles.forEach(collapsible => { collapsible.entanglement = entanglement; }) } | |||
| __entagledRefs.delete(exclusion.entanglement); | |||
| exclusion.entanglement = entanglement; | |||
| entaglements.push(exclusion); | |||
| } | |||
| var entangledFn = (exclusion)=>{ // entaglement object has not yet been fixed => replace. | |||
| exclusion.entanglement.unsync |= entanglement.unsync | exclusion.id ; | |||
| var collapsibles = __entagledRefs.get(entanglement); | |||
| if(collapsibles){ collapsibles.forEach(collapsible => { collapsible.entanglement = exclusion.entanglement; }) } | |||
| __entagledRefs.delete(entanglement); | |||
| entanglement = exclusion.entanglement; | |||
| entaglements = __entagledRefs.get(entanglement); | |||
| entangledFn = __entangledFn; | |||
| } | |||
| var __tangle = Object.assign({}, tangle); | |||
| // __tangle.unsync = __tangle.unsync & ~__tangle.insync; | |||
| // __tangle.insync |= __concept.results[0].id; | |||
| for(var i = 0; i < exclusions.length; i++) { | |||
| var innerexclusions = __concepts[exclusions[i]] ? __concepts[exclusions[i]] : define(exclusions[i], __tangle); | |||
| __tangle.unsync |= innerexclusions.results[0].id //| innerexclusions.results[0].entanglement.insync; | |||
| innerexclusions.results.forEach(exclusion=>{ | |||
| (exclusion.entanglement) ? entangledFn(exclusion) // previously entangled. | |||
| : (()=>{ | |||
| entanglement.unsync |= exclusion.id; | |||
| exclusion.entanglement = entanglement; | |||
| entaglements.push(exclusion) | |||
| })() | |||
| results.push(exclusion) | |||
| maskForSet |= exclusion.id; | |||
| }); | |||
| } | |||
| return { results : results, maskForSet : maskForSet} ; | |||
| } | |||
| function define_string(concept, containing) { | |||
| all |= next; | |||
| __concepts[concept] = { id : next, ex : 0, in : 0, entanglement : Object.assign({}, tangle) }; // self is included in entanglement. | |||
| next = next << 1; | |||
| return { results : [__concepts[concept]], maskForSet : __concepts[concept].id }; | |||
| } | |||
| function define_array(concepts, tangle) { | |||
| if(concepts.length > 1) return define_exclusions(concepts, tangle); | |||
| else return define(concepts[0], tangle) | |||
| } | |||
| function define_object(concepts, tangle){ | |||
| var results = []; | |||
| var maskForSet = 0; | |||
| tangle = tangle || {}; | |||
| Object.keys(concepts).forEach(concept => { | |||
| var __concept = define(concept, tangle); | |||
| results.push.apply(results, __concept.results) | |||
| var __tangle = Object.assign({}, __concept.results[0].entanglement); | |||
| __tangle.insync |= __concept.results[0].id | tangle.insync; | |||
| __tangle.unsync |= tangle.unsync; | |||
| var isconcept = define( concepts[concept][0], __tangle ) | |||
| __tangle = Object.assign({}, __concept.results[0].entanglement); | |||
| __tangle.unsync |= tangle.unsync | __concept.results[0].id; | |||
| var notconcept = define( concepts[concept][1], __tangle ) | |||
| if(notconcept && notconcept.results) { | |||
| __concept.results[0].entanglement.unsync |= notconcept.maskForSet; | |||
| maskForSet |= __concept.maskForSet | notconcept.maskForSet ; | |||
| } | |||
| if(isconcept && isconcept.results) { | |||
| __concept.results[0].entanglement.insync |= isconcept.maskForSet; | |||
| maskForSet |= __concept.maskForSet | isconcept.maskForSet ; | |||
| } | |||
| }); | |||
| results[0].entanglement.insync = maskForSet; | |||
| return { results : results, maskForSet : maskForSet }; | |||
| } | |||
| const conceptvariants = Object.assign(utils.__TPL__typeHandlers, { | |||
| '[object String]' : define_string | |||
| , '[object Array]' : define_array | |||
| , '[object Object]' : define_object | |||
| , '[object Undefined]' : ()=>{} // Ignore | |||
| }) | |||
| function define(concept, tangle){ | |||
| return conceptvariants[Object.prototype.toString.call(concept)](concept, tangle); | |||
| } | |||
| function reveal(){ console.dir(__concepts) } | |||
| return { define, reveal } | |||
| } | |||
| } | |||
| // 'created' is implied by existence. | |||
| var states = { | |||
| 'running' : [ | |||
| /* assertions */ [ ] | |||
| , /* negations = not running */ [ { | |||
| 'unstarted' : [[ /* unstarted */] | |||
| , /* not unstarted = started at some point */ [ | |||
| 'paused' // can be resumed from interrupted (=incomplete or in progress) | |||
| // , sleeping -> ran a little and is now paused same as parent state. | |||
| // , waiting on other things | |||
| // ... sleeping, interrupted ... | |||
| , { 'stopped' : [[ // unlike paused cannot be resumed can be restarted i.e rerun from the beginning. | |||
| 'succeded' // - completed -> process completed | |||
| , 'failed' // - Either processing failed or prematurely exited with exception -> with an error. Non exception cases may have run to completion and failed. | |||
| , 'aborted' // - terminated -> was not allowd to completed. Cannot say succeded or failed. | |||
| // incomplete result ( neither success nor failure ) was stopped and abandoned befeore it could run to completion. | |||
| ], [] ]} | |||
| ] | |||
| ]} ] | |||
| ] | |||
| // unassociated independent co-existence to 'running'. Sibling level in an object. | |||
| } | |||
| var stateFactory = design.create(); | |||
| var x = stateFactory.define(states); | |||
| stateFactory.reveal(); | |||
| // console.dir(JSON.stringify(x)); | |||
| } | |||
| module.exports = asyncDynamicTaskStream; | |||
| asyncDynamicTaskStream(); | |||
| @@ -0,0 +1,240 @@ | |||
| // ------------------------------- | |||
| // Command line option parsing | |||
| // ------------------------------- | |||
| function cliargs(args, opts) { | |||
| if (!opts) opts = {}; | |||
| var flags = { bools : {}, strings : {}, unknownFn: null }; | |||
| if (typeof opts['unknown'] === 'function') { | |||
| flags.unknownFn = opts['unknown']; | |||
| } | |||
| if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { | |||
| flags.allBools = true; | |||
| } else { | |||
| [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { | |||
| flags.bools[key] = true; | |||
| }); | |||
| } | |||
| var aliases = {}; | |||
| Object.keys(opts.alias || {}).forEach(function (key) { | |||
| aliases[key] = [].concat(opts.alias[key]); | |||
| aliases[key].forEach(function (x) { | |||
| aliases[x] = [key].concat(aliases[key].filter(function (y) { | |||
| return x !== y; | |||
| })); | |||
| }); | |||
| }); | |||
| [].concat(opts.string).filter(Boolean).forEach(function (key) { | |||
| flags.strings[key] = true; | |||
| if (aliases[key]) { | |||
| flags.strings[aliases[key]] = true; | |||
| } | |||
| }); | |||
| var defaults = opts['default'] || {}; | |||
| var argv = { _ : [] }; | |||
| Object.keys(flags.bools).forEach(function (key) { | |||
| setArg(key, defaults[key] === undefined ? false : defaults[key]); | |||
| }); | |||
| var notFlags = []; | |||
| if (args.indexOf('--') !== -1) { | |||
| notFlags = args.slice(args.indexOf('--')+1); | |||
| args = args.slice(0, args.indexOf('--')); | |||
| } | |||
| function argDefined(key, arg) { | |||
| return (flags.allBools && /^--[^=]+$/.test(arg)) || | |||
| flags.strings[key] || flags.bools[key] || aliases[key]; | |||
| } | |||
| function setArg (key, val, arg) { | |||
| if (arg && flags.unknownFn && !argDefined(key, arg)) { | |||
| if (flags.unknownFn(arg) === false) return; | |||
| } | |||
| var value = !flags.strings[key] && isNumber(val) | |||
| ? Number(val) : val | |||
| ; | |||
| setKey(argv, key.split('.'), value); | |||
| (aliases[key] || []).forEach(function (x) { | |||
| setKey(argv, x.split('.'), value); | |||
| }); | |||
| } | |||
| function setKey (obj, keys, value) { | |||
| var o = obj; | |||
| keys.slice(0,-1).forEach(function (key) { | |||
| if (o[key] === undefined) o[key] = {}; | |||
| o = o[key]; | |||
| }); | |||
| var key = keys[keys.length - 1]; | |||
| if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { | |||
| o[key] = value; | |||
| } | |||
| else if (Array.isArray(o[key])) { | |||
| o[key].push(value); | |||
| } | |||
| else { | |||
| o[key] = [ o[key], value ]; | |||
| } | |||
| } | |||
| function aliasIsBoolean(key) { | |||
| return aliases[key].some(function (x) { | |||
| return flags.bools[x]; | |||
| }); | |||
| } | |||
| for (var i = 0; i < args.length; i++) { | |||
| var arg = args[i]; | |||
| if (/^--.+=/.test(arg)) { | |||
| // Using [\s\S] instead of . because js doesn't support the | |||
| // 'dotall' regex modifier. See: | |||
| // http://stackoverflow.com/a/1068308/13216 | |||
| var m = arg.match(/^--([^=]+)=([\s\S]*)$/); | |||
| var key = m[1]; | |||
| var value = m[2]; | |||
| if (flags.bools[key]) { | |||
| value = value !== 'false'; | |||
| } | |||
| setArg(key, value, arg); | |||
| } | |||
| else if (/^--no-.+/.test(arg)) { | |||
| var key = arg.match(/^--no-(.+)/)[1]; | |||
| setArg(key, false, arg); | |||
| } | |||
| else if (/^--.+/.test(arg)) { | |||
| var key = arg.match(/^--(.+)/)[1]; | |||
| var next = args[i + 1]; | |||
| if (next !== undefined && !/^-/.test(next) | |||
| && !flags.bools[key] | |||
| && !flags.allBools | |||
| && (aliases[key] ? !aliasIsBoolean(key) : true)) { | |||
| setArg(key, next, arg); | |||
| i++; | |||
| } | |||
| else if (/^(true|false)$/.test(next)) { | |||
| setArg(key, next === 'true', arg); | |||
| i++; | |||
| } | |||
| else { | |||
| setArg(key, flags.strings[key] ? '' : true, arg); | |||
| } | |||
| } | |||
| else if (/^-[^-]+/.test(arg)) { | |||
| var letters = arg.slice(1,-1).split(''); | |||
| var broken = false; | |||
| for (var j = 0; j < letters.length; j++) { | |||
| var next = arg.slice(j+2); | |||
| if (next === '-') { | |||
| setArg(letters[j], next, arg) | |||
| continue; | |||
| } | |||
| if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { | |||
| setArg(letters[j], next.split('=')[1], arg); | |||
| broken = true; | |||
| break; | |||
| } | |||
| if (/[A-Za-z]/.test(letters[j]) | |||
| && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { | |||
| setArg(letters[j], next, arg); | |||
| broken = true; | |||
| break; | |||
| } | |||
| if (letters[j+1] && letters[j+1].match(/\W/)) { | |||
| setArg(letters[j], arg.slice(j+2), arg); | |||
| broken = true; | |||
| break; | |||
| } | |||
| else { | |||
| setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); | |||
| } | |||
| } | |||
| var key = arg.slice(-1)[0]; | |||
| if (!broken && key !== '-') { | |||
| if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) | |||
| && !flags.bools[key] | |||
| && (aliases[key] ? !aliasIsBoolean(key) : true)) { | |||
| setArg(key, args[i+1], arg); | |||
| i++; | |||
| } | |||
| else if (args[i+1] && /true|false/.test(args[i+1])) { | |||
| setArg(key, args[i+1] === 'true', arg); | |||
| i++; | |||
| } | |||
| else { | |||
| setArg(key, flags.strings[key] ? '' : true, arg); | |||
| } | |||
| } | |||
| } | |||
| else { | |||
| if (!flags.unknownFn || flags.unknownFn(arg) !== false) { | |||
| argv._.push( | |||
| flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) | |||
| ); | |||
| } | |||
| if (opts.stopEarly) { | |||
| argv._.push.apply(argv._, args.slice(i + 1)); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| Object.keys(defaults).forEach(function (key) { | |||
| if (!hasKey(argv, key.split('.'))) { | |||
| setKey(argv, key.split('.'), defaults[key]); | |||
| (aliases[key] || []).forEach(function (x) { | |||
| setKey(argv, x.split('.'), defaults[key]); | |||
| }); | |||
| } | |||
| }); | |||
| if (opts['--']) { | |||
| argv['--'] = new Array(); | |||
| notFlags.forEach(function(key) { | |||
| argv['--'].push(key); | |||
| }); | |||
| } | |||
| else { | |||
| notFlags.forEach(function(key) { | |||
| argv._.push(key); | |||
| }); | |||
| } | |||
| return argv; | |||
| }; | |||
| function hasKey (obj, keys) { | |||
| var o = obj; | |||
| keys.slice(0,-1).forEach(function (key) { | |||
| o = (o[key] || {}); | |||
| }); | |||
| var key = keys[keys.length - 1]; | |||
| return key in o; | |||
| } | |||
| function isNumber (x) { | |||
| if (typeof x === 'number') return true; | |||
| if (/^0x[0-9a-f]+$/i.test(x)) return true; | |||
| return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); | |||
| } | |||
| module.exports = cliargs; | |||
| @@ -2,53 +2,107 @@ | |||
| // -------------- | |||
| // elxr | |||
| // A cli tool for elixr. | |||
| const processedArgs = minimist(process.argv.slice(2)); | |||
| const { spawn } = require('child_process'); | |||
| const cliargs = require('../elxr/cliargs'); // Use minimist... | |||
| const processedArgs = cliargs(process.argv.slice(2)); | |||
| console.dir(processedArgs) | |||
| var cli = 'elxr'; | |||
| var ver = '#unversioned'; | |||
| var help = '#unkown list of commands... please refer dveloper documentation for ' + cli; | |||
| nodeShellExec('echo', ['elxr'], { inherit : true}) //, {stdio: "inherit"} | |||
| // grep -qxF 'alias elxr="node elxr/index.js"' ~/.bash_profile || echo 'alias elxr="node elxr/index.js"' >> ~/.bash_profile | |||
| // nodeShellExec('echo', ['elxr'], { inherit : true}) //, {stdio: "inherit"} | |||
| var __runcmd = function(label){ | |||
| // var child = nodeShellExec('mkdir', ['-p', label], { inherit : true} ); | |||
| // console.log('Starting directory: ' + process.cwd()); | |||
| // try { | |||
| // child = child.on('close', () => { process.chdir(label) } ); | |||
| // console.log('New directory: ' + process.cwd()); | |||
| // } | |||
| // catch (err) { | |||
| // console.log('chdir: ' + err); | |||
| // } | |||
| // child.on('close', function(){ | |||
| // var options = { | |||
| // shell : true | |||
| // , inherit : true | |||
| // // , cwd : '' + process.cwd | |||
| // // , env : process.env | |||
| // }; | |||
| // nodeShellExec('git', ['init'], { inherit : true}); | |||
| nodeShellExec('pwd', { inherit : true}); | |||
| //$ "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory="Profile 1" http://localhost:4200/tests/index.html?grep=loopback | |||
| nodeShellExec("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe", [ | |||
| "--profile-directory=Profile 1" | |||
| , 'http://localhost:4200/tests/index.html?grep=model convert ember to loopback' + '&filter=none' /*+ '&filter=model convert ember to loopback'*/]); | |||
| // nodeShellExec('npm', ['init', '-y'], options); | |||
| // nodeShellExec('npm', ['init', '-y'], options); | |||
| // }) | |||
| var op = { | |||
| 'h' : ()=>{ console.log(cli + ' ' + ver + ' ' + help); return '-h' } | |||
| , 'devmysql' : ()=>{ | |||
| console.log('Starting Elixir Server.'); | |||
| var env = Object.assign({}, process.env); // Shallow clone it. | |||
| // console.dir(env) | |||
| env.NODE_ENV = 'devmysql'; | |||
| env.DEBUG = 'loopback:connector:mysql' | |||
| nodeShellExec('node', ['sage-rw/server.js'], { | |||
| shell: true, detached: true, | |||
| cwd : 'loopback', | |||
| env: env, | |||
| shell : true | |||
| }) | |||
| // nodeShellExec('c:/Program Files/nodejs/node.exe', { inherit : true, cwd : '../loopback'}); | |||
| // nodeShellExec('pwd', { | |||
| // inherit : true | |||
| // , cwd : '../loopback' | |||
| // , env : env | |||
| // }) | |||
| // nodeShellExec('node', ['sage-rw/server.js'], { | |||
| // inherit : true | |||
| // , cwd : '../loopback' | |||
| // , env : env | |||
| // }) //, {stdio: "inherit"} | |||
| } | |||
| , 'g' : ()=>{ | |||
| if(processedArgs.h) { | |||
| console.log('elxr g [modelname] => generate a model named [modelname]'); | |||
| console.log('elxr g => regenerate all known models'); | |||
| return | |||
| } | |||
| // var child = nodeShellExec('mkdir', ['-p', label], { inherit : true} ); | |||
| // console.log('Starting directory: ' + process.cwd()); | |||
| // try { | |||
| // child = child.on('close', () => { process.chdir(label) } ); | |||
| // console.log('New directory: ' + process.cwd()); | |||
| // } | |||
| // catch (err) { | |||
| // console.log('chdir: ' + err); | |||
| // } | |||
| // child.on('close', function(){ | |||
| // var options = { | |||
| // shell : true | |||
| // , inherit : true | |||
| // // , cwd : '' + process.cwd | |||
| // // , env : process.env | |||
| // }; | |||
| // nodeShellExec('git', ['init'], { inherit : true}); | |||
| nodeShellExec('pwd', { inherit : true}); | |||
| //$ "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory="Profile 1" http://localhost:4200/tests/index.html?grep=loopback | |||
| nodeShellExec("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe", [ | |||
| "--profile-directory=Profile 1" | |||
| , 'http://localhost:4200/tests/index.html?grep=model convert ember to loopback' + '&filter=none' /*+ '&filter=model convert ember to loopback'*/]); | |||
| // nodeShellExec('npm', ['init', '-y'], options); | |||
| // nodeShellExec('npm', ['init', '-y'], options); | |||
| // }) | |||
| } | |||
| } | |||
| return op[label](); | |||
| } | |||
| __runcmd(processedArgs.label || processedArgs._[0] || (function(){ console.log(cli + ' ' + ver + ' ' + help); return '-h' } )()); | |||
| // mysqldump --add-drop-table --no-data -u root -p db_name | grep 'DROP TABLE' ) > drop_all_tables.sql | |||
| // mysql -u root -p db_name < drop_all_tables.sql | |||
| var mysql = '../xampp/mysql/bin/mysql' | |||
| var mysqldump = '../xampp/mysql/bin/mysqldump' | |||
| __runcmd(processedArgs.label || processedArgs._[0] || '-h'); | |||
| // nodeShellExec('git', ['status']); | |||
| function nodeShellExec() { | |||
| const { spawn } = require('child_process'); | |||
| const child = spawn(...arguments); | |||
| // use child.stdout.setEncoding('utf8'); if you want text chunks | |||
| child.stdout.setEncoding('utf8'); | |||
| console.log('here') | |||
| // console.log('here') | |||
| child.stdout.on('data', (chunk) => console.log(chunk)); | |||
| @@ -59,241 +113,3 @@ function nodeShellExec() { | |||
| return child; | |||
| } | |||
| // ------------------------------- | |||
| // Command line option parsing | |||
| // ------------------------------- | |||
| function minimist(args, opts) { | |||
| if (!opts) opts = {}; | |||
| var flags = { bools : {}, strings : {}, unknownFn: null }; | |||
| if (typeof opts['unknown'] === 'function') { | |||
| flags.unknownFn = opts['unknown']; | |||
| } | |||
| if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { | |||
| flags.allBools = true; | |||
| } else { | |||
| [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { | |||
| flags.bools[key] = true; | |||
| }); | |||
| } | |||
| var aliases = {}; | |||
| Object.keys(opts.alias || {}).forEach(function (key) { | |||
| aliases[key] = [].concat(opts.alias[key]); | |||
| aliases[key].forEach(function (x) { | |||
| aliases[x] = [key].concat(aliases[key].filter(function (y) { | |||
| return x !== y; | |||
| })); | |||
| }); | |||
| }); | |||
| [].concat(opts.string).filter(Boolean).forEach(function (key) { | |||
| flags.strings[key] = true; | |||
| if (aliases[key]) { | |||
| flags.strings[aliases[key]] = true; | |||
| } | |||
| }); | |||
| var defaults = opts['default'] || {}; | |||
| var argv = { _ : [] }; | |||
| Object.keys(flags.bools).forEach(function (key) { | |||
| setArg(key, defaults[key] === undefined ? false : defaults[key]); | |||
| }); | |||
| var notFlags = []; | |||
| if (args.indexOf('--') !== -1) { | |||
| notFlags = args.slice(args.indexOf('--')+1); | |||
| args = args.slice(0, args.indexOf('--')); | |||
| } | |||
| function argDefined(key, arg) { | |||
| return (flags.allBools && /^--[^=]+$/.test(arg)) || | |||
| flags.strings[key] || flags.bools[key] || aliases[key]; | |||
| } | |||
| function setArg (key, val, arg) { | |||
| if (arg && flags.unknownFn && !argDefined(key, arg)) { | |||
| if (flags.unknownFn(arg) === false) return; | |||
| } | |||
| var value = !flags.strings[key] && isNumber(val) | |||
| ? Number(val) : val | |||
| ; | |||
| setKey(argv, key.split('.'), value); | |||
| (aliases[key] || []).forEach(function (x) { | |||
| setKey(argv, x.split('.'), value); | |||
| }); | |||
| } | |||
| function setKey (obj, keys, value) { | |||
| var o = obj; | |||
| keys.slice(0,-1).forEach(function (key) { | |||
| if (o[key] === undefined) o[key] = {}; | |||
| o = o[key]; | |||
| }); | |||
| var key = keys[keys.length - 1]; | |||
| if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { | |||
| o[key] = value; | |||
| } | |||
| else if (Array.isArray(o[key])) { | |||
| o[key].push(value); | |||
| } | |||
| else { | |||
| o[key] = [ o[key], value ]; | |||
| } | |||
| } | |||
| function aliasIsBoolean(key) { | |||
| return aliases[key].some(function (x) { | |||
| return flags.bools[x]; | |||
| }); | |||
| } | |||
| for (var i = 0; i < args.length; i++) { | |||
| var arg = args[i]; | |||
| if (/^--.+=/.test(arg)) { | |||
| // Using [\s\S] instead of . because js doesn't support the | |||
| // 'dotall' regex modifier. See: | |||
| // http://stackoverflow.com/a/1068308/13216 | |||
| var m = arg.match(/^--([^=]+)=([\s\S]*)$/); | |||
| var key = m[1]; | |||
| var value = m[2]; | |||
| if (flags.bools[key]) { | |||
| value = value !== 'false'; | |||
| } | |||
| setArg(key, value, arg); | |||
| } | |||
| else if (/^--no-.+/.test(arg)) { | |||
| var key = arg.match(/^--no-(.+)/)[1]; | |||
| setArg(key, false, arg); | |||
| } | |||
| else if (/^--.+/.test(arg)) { | |||
| var key = arg.match(/^--(.+)/)[1]; | |||
| var next = args[i + 1]; | |||
| if (next !== undefined && !/^-/.test(next) | |||
| && !flags.bools[key] | |||
| && !flags.allBools | |||
| && (aliases[key] ? !aliasIsBoolean(key) : true)) { | |||
| setArg(key, next, arg); | |||
| i++; | |||
| } | |||
| else if (/^(true|false)$/.test(next)) { | |||
| setArg(key, next === 'true', arg); | |||
| i++; | |||
| } | |||
| else { | |||
| setArg(key, flags.strings[key] ? '' : true, arg); | |||
| } | |||
| } | |||
| else if (/^-[^-]+/.test(arg)) { | |||
| var letters = arg.slice(1,-1).split(''); | |||
| var broken = false; | |||
| for (var j = 0; j < letters.length; j++) { | |||
| var next = arg.slice(j+2); | |||
| if (next === '-') { | |||
| setArg(letters[j], next, arg) | |||
| continue; | |||
| } | |||
| if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { | |||
| setArg(letters[j], next.split('=')[1], arg); | |||
| broken = true; | |||
| break; | |||
| } | |||
| if (/[A-Za-z]/.test(letters[j]) | |||
| && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { | |||
| setArg(letters[j], next, arg); | |||
| broken = true; | |||
| break; | |||
| } | |||
| if (letters[j+1] && letters[j+1].match(/\W/)) { | |||
| setArg(letters[j], arg.slice(j+2), arg); | |||
| broken = true; | |||
| break; | |||
| } | |||
| else { | |||
| setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); | |||
| } | |||
| } | |||
| var key = arg.slice(-1)[0]; | |||
| if (!broken && key !== '-') { | |||
| if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) | |||
| && !flags.bools[key] | |||
| && (aliases[key] ? !aliasIsBoolean(key) : true)) { | |||
| setArg(key, args[i+1], arg); | |||
| i++; | |||
| } | |||
| else if (args[i+1] && /true|false/.test(args[i+1])) { | |||
| setArg(key, args[i+1] === 'true', arg); | |||
| i++; | |||
| } | |||
| else { | |||
| setArg(key, flags.strings[key] ? '' : true, arg); | |||
| } | |||
| } | |||
| } | |||
| else { | |||
| if (!flags.unknownFn || flags.unknownFn(arg) !== false) { | |||
| argv._.push( | |||
| flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) | |||
| ); | |||
| } | |||
| if (opts.stopEarly) { | |||
| argv._.push.apply(argv._, args.slice(i + 1)); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| Object.keys(defaults).forEach(function (key) { | |||
| if (!hasKey(argv, key.split('.'))) { | |||
| setKey(argv, key.split('.'), defaults[key]); | |||
| (aliases[key] || []).forEach(function (x) { | |||
| setKey(argv, x.split('.'), defaults[key]); | |||
| }); | |||
| } | |||
| }); | |||
| if (opts['--']) { | |||
| argv['--'] = new Array(); | |||
| notFlags.forEach(function(key) { | |||
| argv['--'].push(key); | |||
| }); | |||
| } | |||
| else { | |||
| notFlags.forEach(function(key) { | |||
| argv._.push(key); | |||
| }); | |||
| } | |||
| return argv; | |||
| }; | |||
| function hasKey (obj, keys) { | |||
| var o = obj; | |||
| keys.slice(0,-1).forEach(function (key) { | |||
| o = (o[key] || {}); | |||
| }); | |||
| var key = keys[keys.length - 1]; | |||
| return key in o; | |||
| } | |||
| function isNumber (x) { | |||
| if (typeof x === 'number') return true; | |||
| if (/^0x[0-9a-f]+$/i.test(x)) return true; | |||
| return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); | |||
| } | |||
| @@ -0,0 +1,170 @@ | |||
| // vValueHelper Tests | |||
| var proxiedDescriptor = (()=> { | |||
| var __values = []; | |||
| class proxiedDescriptorClass { | |||
| get [Symbol.toStringTag]() { return 'proxiedDescriptor';} | |||
| valueOf(){return 'pdc'} | |||
| } | |||
| var __composite = { a : '__composite'}; | |||
| console.dir(__composite) | |||
| function composite(){ | |||
| var o = js.isUndefined(__values[0]) ? __values[0] : js.assign(js.getTypeInfo(__values[0]).create(), ...__values) | |||
| return o; | |||
| } | |||
| let mutableTarget; | |||
| let mutableHandler; | |||
| function setHandler(handler) { | |||
| Object.keys(handler).forEach(key => { | |||
| const value = handler[key]; | |||
| if (typeof value !== 'function') { | |||
| // handler[key] = Reflect[key]; | |||
| throw new Error(`Trap "${key}: ${value}" is not a function`); | |||
| } | |||
| if (!Reflect[key]) { | |||
| throw new Error(`Trap "${key}: ${value}" is not a valid trap`); | |||
| } | |||
| }); | |||
| // mutableHandler = js.assign({}, Reflect, mutableHandler || {}, handler); | |||
| mutableHandler = js.assign(mutableHandler || {}, handler); | |||
| // mutableHandler = handler | |||
| } | |||
| function setTarget(target) { | |||
| // if (!(target instanceof Object)) { | |||
| // throw new Error(`Target "${target}" is not an object`); | |||
| // } | |||
| mutableTarget = target; | |||
| } | |||
| setTarget(() => {}); | |||
| // setHandler(Reflect); | |||
| console.log('-----MT---------') | |||
| console.dir(mutableTarget) | |||
| console.log('-----MT---------') | |||
| // Dynamically forward all the traps to the associated methods on the mutable handler | |||
| const handler = new Proxy({}, { | |||
| get(target, property) { | |||
| console.log('-----marker---------') | |||
| setTarget(composite()) | |||
| // console.dir(target) | |||
| // console.dir(Reflect.ownKeys) | |||
| console.log(property) | |||
| if(mutableHandler[property]) return (...args) => mutableHandler[property].apply(null, [mutableTarget, ...args.slice(1)]); | |||
| // else return (...args) => Reflect[property].apply(null, [mutableTarget, ...args.slice(1)]); | |||
| } | |||
| }); | |||
| var mutableProxyInstance = { | |||
| setHandler, | |||
| getTarget() { | |||
| return mutableTarget; | |||
| }, | |||
| getHandler() { | |||
| return mutableHandler; | |||
| }, | |||
| proxy: new Proxy(mutableTarget, handler) | |||
| }; | |||
| setHandler({ | |||
| getOwnPropertyDescriptor: function(target, prop) { | |||
| console.log('accessing prop : ') | |||
| console.dir(prop) | |||
| // console.dir(this) | |||
| o = composite() | |||
| console.dir(target) | |||
| var a = {value : undefined, configurable : true}; | |||
| if(!js.isUndefined(o)) a= Object.getOwnPropertyDescriptor(o, prop); | |||
| // if (a) a.value = this.get(o, prop); | |||
| return a; | |||
| // return function(){ | |||
| // console.log('in toString ....') | |||
| // var o = composite(); | |||
| // console.dir(o) | |||
| // return o | |||
| // } | |||
| } | |||
| , | |||
| // ownKeys : function(){ | |||
| // return Reflect.ownKeys(composite()) | |||
| // } | |||
| // , | |||
| get: function(target, name) { | |||
| console.log('accessing name : ') | |||
| console.dir(name) | |||
| console.log('target is now') | |||
| console.dir(target) | |||
| // console.log('' + (name == Symbol.toStringTag)) | |||
| // if(name == 'ownKeys') { | |||
| // return composite().ownKeys; | |||
| // } | |||
| if(js.isUndefined(target)) return Reflect[name]; | |||
| if( | |||
| name == util.inspect.custom | |||
| // || name == 'inspect' | |||
| // || name == Symbol.toStringTag | |||
| // || name == Symbol.iterator /*|| name == 'constructor' || name == 'toString' || name == 'valueOf'*/ | |||
| // || name == 'valueOf' | |||
| // && name != 'name' | |||
| ) { | |||
| return function(){ | |||
| console.log('in toString ....') | |||
| var o = composite(); | |||
| console.dir(o) | |||
| return o | |||
| } | |||
| } | |||
| // else if( | |||
| // name == Symbol.toStringTag | |||
| // // || | |||
| // // name == 'toString' | |||
| // || name == 'valueOf' | |||
| // || name == Symbol.iterator /*|| name == 'constructor' || name == 'toString' || name == 'valueOf'*/ | |||
| // ) | |||
| // return JSON.stringify((function(){ | |||
| // console.log('in toString ....') | |||
| // var o = composite(); | |||
| // // console.dir(o) | |||
| // return o | |||
| // })() | |||
| // ) | |||
| // else | |||
| return (name == 'composite' ? composite() | |||
| // : name == 'toString' || name == 'valueOf' ? (function(){ | |||
| // console.log('in toString') | |||
| // // console.dir((js.isUndefined(__values[0]) ? __values[0] : js.assign(js.getTypeInfo(__values[0]).create(), ...__values))) | |||
| // return composite() | |||
| // }) | |||
| // : name == 'toValue' ? js.assign(js.getTypeInfo(__values[0]).create(), ...__values) | |||
| : name == 'current' ? Ref.isRef(__values[0]) ? __values[0].getValue() : __values[0] | |||
| : name == 'previous' ? Ref.isRef(__values[1]) ? __values[1].getValue() : __values[1] | |||
| : composite()[name] //Ref.isRef(__values[name]) ? __values[name].getValue() : __values[name] | |||
| ) | |||
| } | |||
| , set: function(target, name, value) { | |||
| mutabletarget = __composite = composite(); | |||
| name == 'revise' ? (__values.splice(0, 0, value), value) | |||
| : name == 'precede' ? (__values.push(value), value) | |||
| : name == 'current' ? __values[0] = value | |||
| : __values[name] = value; | |||
| return __composite; | |||
| } | |||
| }) | |||
| var p = new Proxy(__composite, handler); | |||
| p.toString = function() { return 'ps tostring' } | |||
| return { | |||
| get : function(){ return p} | |||
| , set : function(value) { p.revise = value} | |||
| } | |||
| })() | |||
| @@ -0,0 +1,363 @@ | |||
| // var assert = require('assert'); | |||
| var assert = require('chai').assert | |||
| const util = require('util'); | |||
| var utils = require("../bbhverse-pb-wip/utils") | |||
| var js = utils.js; | |||
| const proxiedDescriptor = js.proxiedDescriptor; | |||
| const Ref = js.Ref; | |||
| const valueBackedAccessor = js.valueBackedAccessor; | |||
| describe('proxy', function() { | |||
| it('is not possible for', function() { | |||
| console.log(js.nonproxyable) | |||
| assert.ok(true) | |||
| }); | |||
| it('is possible for', function() { | |||
| console.log(js.proxyable) | |||
| assert.ok(true) | |||
| }); | |||
| }) | |||
| describe('mutableproxy', function() { | |||
| it('blank creation should be possible.', function() { | |||
| var mutableProxy = js.mutableProxy.create(); | |||
| console.dir(mutableProxy) | |||
| assert.ok(true) | |||
| }); | |||
| it('target should be switchable', function() { | |||
| var mutableProxy = js.mutableProxy.create({original : 'target at create time'}); | |||
| console.dir(mutableProxy) | |||
| js.mutableProxy.setTarget({'switched' : 'switched'}, mutableProxy) | |||
| assert.ok(true) | |||
| }); | |||
| it('handler should be switchable', function() { | |||
| var mutableProxy = js.mutableProxy.create({original : 'target at create time'}); | |||
| js.mutableProxy.setHandler({ | |||
| get : function(target, key){ | |||
| console.log('handler switch invoked : ') | |||
| // console.dir(meta.target) | |||
| // console.dir(arguments) | |||
| var args = Array.prototype.slice.call(arguments, 0); | |||
| args[0] = target; | |||
| return target[key] | |||
| return Reflect.apply(Reflect[key], target, args) | |||
| // var args = Array.prototype.slice.call(arguments, 0); | |||
| // args[0] = meta.target; | |||
| // return Reflect[key](...args) | |||
| } | |||
| }, mutableProxy) | |||
| console.dir(mutableProxy) | |||
| assert.ok(true) | |||
| }); | |||
| it('handler should be called', function() { | |||
| var mutableProxy = js.mutableProxy.create(); | |||
| // console.dir(mutableProxy); | |||
| // console.log(mutableProxy); | |||
| // js.mutableProxy.setTarget({ switched : 'switched'}, mutableProxy) | |||
| // console.dir(mutableProxy); | |||
| // console.log(mutableProxy); | |||
| var x = {} | |||
| js.mutableProxy.setHandler({ | |||
| get : function(target, key){ | |||
| console.log('handler switch invoked : ') | |||
| // console.dir(meta.target) | |||
| // console.dir(arguments) | |||
| var args = Array.prototype.slice.call(arguments, 0); | |||
| args[0] = target; | |||
| x = 'handler was called' | |||
| return target[key] | |||
| return Reflect.apply(Reflect[key], target, args) | |||
| // var args = Array.prototype.slice.call(arguments, 0); | |||
| // args[0] = meta.target; | |||
| // return Reflect[key](...args) | |||
| } | |||
| }, mutableProxy) | |||
| console.dir(mutableProxy); | |||
| console.log(mutableProxy); | |||
| js.mutableProxy.setTarget({ switched : 'handlerswitched'}, mutableProxy) | |||
| console.dir(mutableProxy); | |||
| console.log(mutableProxy); | |||
| assert.strictEqual('handler was called', x), 'but is not'; | |||
| }); | |||
| }) | |||
| describe('proxiedDescriptor', function() { | |||
| var o = {} | |||
| Object.defineProperty(o, 'vV', proxiedDescriptor.create()); | |||
| it('on create should be undefined', function() { | |||
| // console.log(o.vV) | |||
| // console.dir(o.vV) | |||
| assert.isUndefined(o.vV); | |||
| }); | |||
| it('after revision current should be {a : 4}', function() { | |||
| var x = { a: 5 } | |||
| o.vV = x; | |||
| console.dir(o.vV) | |||
| // console.log("" + (o.vV.current=== x)) | |||
| assert.deepEqual(o.vV, x); | |||
| // assert.strictEqual(o.vV.current, x), 'but is not'; | |||
| x = { a: 4 } | |||
| o.vV.revision = x | |||
| console.dir(o.vV) | |||
| assert.deepEqual(o.vV, x); | |||
| // assert.strictEqual(o.vV.previous, x), 'but is not'; | |||
| }); | |||
| it('valueBackedAccessor is unrevisioned unless revision is explicitly called.', function() { | |||
| var vValue = js.vValue; | |||
| var o1 = {} | |||
| Object.defineProperty(o1, 'vV', valueBackedAccessor.create()); | |||
| // initial uninitialized state... | |||
| console.log('console.log(cloned.vV)') | |||
| console.log(o1.vV) | |||
| console.log(Object.prototype.toString.call(o1.vV)) | |||
| console.log('---------------------------------------------') | |||
| console.log('console.dir(o1.vV)') | |||
| console.dir(o1.vV) | |||
| console.log(Object.prototype.toString.call(o1.vV)) | |||
| // throw 'done' | |||
| console.log('---------------------------------------------') | |||
| console.log('util.inspect(o1.vV)') | |||
| console.log(util.inspect(o1.vV)) | |||
| console.log(Object.prototype.toString.call(o1.vV)) | |||
| console.log('---------------------------------------------') | |||
| o1.vV = { d : 7 } | |||
| o1.vV = { e : 8 } | |||
| o1.vV = { f : "9 Nine" } | |||
| var ten = { g : "10" } | |||
| o1.vV = ten | |||
| // console.log(o1.vV === ten) | |||
| assert.deepEqual(o1.vV, ten); | |||
| assert.strictEqual(o1.vV.current, ten); | |||
| assert.strictEqual(o1.vV, ten), 'but is not vV[Proxy] cannot be equal to original object. Use vv[proxy].current === original value for comparison. '; | |||
| }); | |||
| it('proxiedDescriptor switch to composite revision', function() { | |||
| var ten = { g : "10" } | |||
| // proxiedDescriptor.ten = ten; | |||
| var o1 = js.Versioned.create(); | |||
| // Object.defineProperty(o1, 'vV', proxiedDescriptor.create(proxiedDescriptor.current)); | |||
| // o1.vV = null; | |||
| // initial uninitialized state... | |||
| console.log('console.log(cloned.vV)') | |||
| console.log(o1.vV) | |||
| console.log(Object.prototype.toString.call(o1.vV)) | |||
| console.log('---------------------------------------------') | |||
| console.log('console.dir(o1.vV)') | |||
| console.dir(o1.vV) | |||
| console.log(Object.prototype.toString.call(o1.vV)) | |||
| // throw 'done' | |||
| console.log('---------------------------------------------') | |||
| console.log('util.inspect(o1.vV)') | |||
| console.log(util.inspect(o1.vV)) | |||
| console.log(Object.prototype.toString.call(o1.vV)) | |||
| console.log('---------------------------------------------') | |||
| o1.vV = { d : 7 } | |||
| console.dir(o1.vV) | |||
| o1.vV = { e : 8 } | |||
| console.dir(o1.vV) | |||
| o1.vV = { f : "9 Nine" } | |||
| console.dir(o1.vV) | |||
| debugger | |||
| o1.vV = ten | |||
| var a = o1.vV; | |||
| o1.vV = ten | |||
| // console.log(util.inspect(o1.vV)) | |||
| // console.log((o1.vV === ten)) | |||
| console.dir(o1.vV) | |||
| console.dir(o1.vV.g) | |||
| assert.deepEqual(o1.vV, ten); | |||
| assert.strictEqual(o1.vV, a); // Self identity via proxy === proxy. Instead of target === target which is effectively the same.. | |||
| console.dir((ten == (+o1.vV))) // false Doesn't work. Throws exception when valueOf and toString return non primitives. | |||
| console.dir((ten === o1.vV)) // false Doesn't work. coz getter always returns a proxy and not the target. The target indeed is === ten. | |||
| // The options therefore as alternative or === which fails for proxies are as below. | |||
| // Explicitly call valueOf or use a helper which gets the real target of the proxy | |||
| console.dir((o1.vV.valueOf() === ten)) | |||
| assert.strictEqual(o1.vV.valueOf(), ten); | |||
| assert.strictEqual(js.Proxied.getTarget(o1.vV), ten); | |||
| // assert.strictEqual(o1.vV, ten); | |||
| var d = Object.getOwnPropertyDescriptor(o1, "vV"); | |||
| proxiedDescriptor.switchTo(d, proxiedDescriptor['composite revision']) | |||
| o1.vV = { eleven : '11'} | |||
| console.dir(o1.vV) | |||
| assert.deepEqual(o1.vV, { g : "10", eleven : '11' } ); | |||
| }); | |||
| it('series of changes should match', function() { | |||
| o.vV = { d : 7 } | |||
| o.vV.revision = { b: 6 } | |||
| o.vV.firstrevision = { c: 4 } | |||
| // console.log("" + (o.vV.current=== x)) | |||
| // console.dir(o.vV) | |||
| assert.deepEqual(o.vV.current, {b : 6} ); | |||
| o.vV.revision = { a : '4'} | |||
| assert.deepEqual(o.vV.previous, {b : 6}); | |||
| }); | |||
| }); | |||
| describe('Ref', function() { | |||
| var o = { a : "aaaaa", b : "bbbbb" } | |||
| var ref = js.Ref.create(o,'a') | |||
| // console.log('---------------------s assignment---') | |||
| var aaa = ref; | |||
| // console.log('---------------------e assignment---') | |||
| // console.dir(aaa) | |||
| it('ref should return transparent proxy', function() { | |||
| assert.strictEqual(ref, aaa, 'but does not'); | |||
| }); | |||
| it('ref() should return referenced value', function() { | |||
| assert.deepEqual(ref(), 'aaaaa', 'but does not'); | |||
| }); | |||
| }); | |||
| describe('exercise some calls', function() { | |||
| it('series of calls should not throw exceptions.', function() { | |||
| var cobj = { d : 'd', e : 5}; | |||
| var original = { a : 'a', b : 'b', cobj : cobj | |||
| , arrayContainingObjects : [ { o: 'o', arr : [1,2]}, cobj ] | |||
| , objectContainingArrays : { arr0 : ['o', 1, 'asd'], arr1 : [1,2]} | |||
| }; | |||
| // PB : TODO -- Test accessor descriptor and valueBackedAccessorDescriptor cases. | |||
| original.fobj = original.cobj; | |||
| original.orig = original; | |||
| Object.defineProperty(original, 'vba', js.valueBackedAccessor.create()); | |||
| original.vba = 'value set using setter' | |||
| console.log('original.vba : ') | |||
| console.dir(original.vba) | |||
| console.dir(original) | |||
| var d = Object.getOwnPropertyDescriptor(original, 'vba') | |||
| // console.log('valueBackedAccessor.isValueBackedAccessor(d)' + js.valueBackedAccessor.isValueBackedAccessor(d)); | |||
| // console.log('valueBackedAccessor.isValueBackedAccessor(d)' + js.valueBackedAccessor.isValueBackedAccessor({})); | |||
| var cloned = js.clone(false, original); | |||
| console.log('cloned.vba : ') | |||
| console.dir(cloned.vba) | |||
| console.dir(cloned) | |||
| console.log("isClone = " + (original !== cloned)) | |||
| console.log("isClone = " + (original.cobj !== cloned.cobj)) | |||
| console.log("isClone = " + (original.fobj !== cloned.fobj)) | |||
| console.log("isClone = " + (original.cobj === original.fobj)) | |||
| console.log("isClone = " + (cloned.cobj === cloned.fobj)) // Ref cloning. | |||
| console.log("descriptorRetrivalYieldsSameDescriptor = " + (Object.getOwnPropertyDescriptor(original, 'a') === Object.getOwnPropertyDescriptor(original, "a"))) | |||
| var linkedUsingAssign = {} | |||
| js.assign(linkedUsingAssign, cloned, cloned) | |||
| console.log('linkedUsingAssign.vba : ') | |||
| console.dir(linkedUsingAssign.vba) | |||
| console.dir(linkedUsingAssign) | |||
| // var a = { | |||
| // valueOf : function(){ return 'I am a'} | |||
| // , toString : function(){ return 'I am a'} | |||
| // } | |||
| // console.dir('' + a) | |||
| // vValueHelper Tests | |||
| // var proxiedDescriptor = js.proxiedDescriptor; | |||
| var vValue = js.vValue; | |||
| Object.defineProperty(cloned, 'vV', vValue.create()); | |||
| console.log('vValueHelper') | |||
| // initial uninitialized state... | |||
| console.log('console.log(cloned.vV)') | |||
| console.log(cloned.vV) | |||
| console.log(Object.prototype.toString.call(cloned.vV)) | |||
| console.log('---------------------------------------------') | |||
| console.log('console.dir(cloned.vV)') | |||
| console.dir(cloned.vV) | |||
| console.log(Object.prototype.toString.call(cloned.vV)) | |||
| // throw 'done' | |||
| console.log('---------------------------------------------') | |||
| console.log('util.inspect(cloned.vV)') | |||
| console.log(util.inspect(cloned.vV)) | |||
| console.log(Object.prototype.toString.call(cloned.vV)) | |||
| console.log('---------------------------------------------') | |||
| cloned.vV = { d : 7 } | |||
| // cloned.vV = { e : 8 } | |||
| // cloned.vV = { f : "9 Nine" } | |||
| // cloned.vV = { g : "10" } | |||
| cloned.vV.revision = { a: 5 } | |||
| cloned.vV.revision = { a: 6 } | |||
| cloned.vV.firstrevision = { c: 4 } | |||
| cloned.vV.previous = { c0: 'c0' } | |||
| cloned.vV.previous = { a: '4' } | |||
| console.log('console.log(cloned.vV)') | |||
| console.log(cloned.vV) | |||
| console.log('---------------------------------------------') | |||
| console.dir('console.dir(cloned.vV)') | |||
| console.dir(cloned.vV) | |||
| console.log('---------------------------------------------') | |||
| console.log('util.inspect(cloned.vV)') | |||
| console.log(util.inspect(cloned.vV)) | |||
| console.log('---------------------------------------------') | |||
| console.log('console.dir(cloned.vV.composite)') | |||
| console.dir(cloned.vV.composite) | |||
| console.dir(cloned.vV.previous) | |||
| console.dir(cloned.vV.current) | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,341 @@ | |||
| var assert = require('chai').assert | |||
| const util = require('util'); | |||
| var utils = require("../bbhverse-pb-wip/utils") | |||
| var js = utils.js; | |||
| const proxiedDescriptor = js.proxiedDescriptor; | |||
| const Ref = js.Ref; | |||
| const valueBackedAccessor = js.valueBackedAccessor; | |||
| var vValue = js.vValue; | |||
| // var o = {} | |||
| // Object.defineProperty(o, 'vV', proxiedDescriptor.create()); | |||
| // var x = { a: 5 } | |||
| // o.vV = x; | |||
| // console.dir(o.vV) | |||
| // // console.log("" + (o.vV.current=== x)) | |||
| // assert.strictEqual(o.vV.current, x); | |||
| // o.vV.revision = { a : '4'} | |||
| // assert.strictEqual(o.vV.previous, x); | |||
| console.dir(Reflect.ownKeys(Reflect)); | |||
| // Find proxyable types | |||
| (()=>{ | |||
| utils.js.typeInstances.forEach((instance)=>{ | |||
| try { | |||
| new Proxy(instance,{}) | |||
| js.proxyable.push(js.nativeType(instance)) | |||
| } | |||
| catch(e){ | |||
| js.nonproxyable.push(js.nativeType(instance)) | |||
| // console.log('Proxy not possible for : ' + js.nativeType(instance)) | |||
| // console.log(e); | |||
| } | |||
| }) | |||
| return; | |||
| })() | |||
| console.dir('console.dir(js.proxyable)'); | |||
| console.dir(js.proxyable) | |||
| console.dir('console.dir(js.nonproxyable)'); | |||
| console.dir(js.nonproxyable); | |||
| // Getter Setter test. | |||
| var vstore = ''; | |||
| var r = {} | |||
| Object.defineProperty(r, 'p',{ get : function(){ return 'u got me : ' + vstore }, set : function(v){ vstore = v}, enumerable:true }) | |||
| console.dir(r) | |||
| console.dir('***************-------- ') | |||
| r.p = 'Pvalue' | |||
| var ref = js.Ref.create(r, 'p') | |||
| console.dir(ref) | |||
| ref.y ='sadasdf' | |||
| console.dir(ref) | |||
| ref.assign('u set me') | |||
| ref.x = 'asd' | |||
| console.dir(ref) | |||
| console.dir(r) | |||
| r = {} | |||
| ref = js.Ref.create(r, 'p') | |||
| console.dir('***************-------- ') | |||
| console.dir(ref) | |||
| console.dir(typeof(ref)) | |||
| r.p = 'initialP' | |||
| console.dir(ref) | |||
| console.dir(typeof(ref)) | |||
| // PB : TODO -- Test | |||
| // r.p preexisting value or with data descriptor | |||
| // r.p with accessor that has side effects. | |||
| // r.p is an object. | |||
| r = { p : 'p'} | |||
| ref = js.Ref.create(r, 'p') | |||
| console.dir('***************-------- ') | |||
| console.dir(ref) | |||
| console.dir(typeof(ref)) | |||
| console.dir(typeof(new String('abc'))) | |||
| // console.dir('ref() -------- ') | |||
| // console.dir(ref()) | |||
| // console.dir('ref() -------- ') | |||
| ref.assign("P") | |||
| console.dir(ref) | |||
| // console.dir(Object.prototype.toString.call('astring')) | |||
| console.dir(r) | |||
| ref.assign("PP") | |||
| console.dir(ref) | |||
| console.dir(Object.prototype.toString.call(ref)) | |||
| console.dir(new String('asdfasdf')) | |||
| console.dir(Object.prototype.toString.call(new String('asdfasdf'))) | |||
| // console.dir(Object.prototype.toString.call(new Proxy(new String('rawproxy'), {}))) | |||
| console.dir(r) | |||
| r.p = "original replaced" | |||
| console.dir(ref) | |||
| console.dir(r) | |||
| // PB : TODO -- enable when ref extensions are implemented. | |||
| console.dir('ref.x') | |||
| console.dir(ref.x) | |||
| ref.x = 'X'; | |||
| console.dir(ref.x) | |||
| console.dir(ref) | |||
| console.dir(r) | |||
| console.dir(ref.substring(2,5)) | |||
| r.p = 'x after pchanged' | |||
| // ref.assign(Object.assign(new String('sdsd'), { p : r.p}) ) | |||
| console.dir(ref.x) | |||
| console.dir(ref) | |||
| console.dir(r) | |||
| ref.assign(new String('ref.assign')); | |||
| console.dir(ref.x) | |||
| console.dir(ref) | |||
| console.dir(r) | |||
| var ns = new String('sdsd') | |||
| console.dir(ns) | |||
| ns.x = 'X' | |||
| console.dir(ns) | |||
| // ref.p = "PLOP" | |||
| // console.dir(r) | |||
| // console.dir(ref.p) | |||
| // var o = js.Versioned.create(proxiedDescriptor['versioned current']) | |||
| var o = js.Versioned.create() | |||
| // o = 5; // This will destroy the reference to the prooxy received from Versioned.create. | |||
| // we cannot override assignment operator... | |||
| // therefore provision made for assign etc. methods for these types at the object level. | |||
| // to achieve a switch to the underlying content for the reference. | |||
| // property level assignment is possible through accessors or proxied descriptors. | |||
| o.assign(new String('ddd')); | |||
| console.dir('console.dir(o).......................') | |||
| // Object.keys(o) | |||
| console.dir(o) | |||
| console.dir('ssss' + o) | |||
| o.x = 'xtttt' | |||
| console.dir(o) | |||
| console.dir('sssfff : ' + o) | |||
| console.dir('console.dir(o).......................') | |||
| o.assign(new Number(5)); | |||
| console.dir('console.dir(o).......................') | |||
| console.dir(o) | |||
| console.dir('ssss' + o) | |||
| console.dir(3 + o) | |||
| console.dir('console.dir(o).......................') | |||
| // throw 'done' | |||
| o.assign(new Boolean(true)); | |||
| console.dir('console.dir(o).......................') | |||
| console.dir('ssss' + true) | |||
| console.dir(o) | |||
| console.dir('ssss' + o) | |||
| console.dir(3 + o) | |||
| console.dir(3 + true) | |||
| console.dir('console.dir(o).......................') | |||
| // throw 'here' | |||
| o = js.Versioned.create(o) // Doesn't work. | |||
| var x = { a: 5 } | |||
| o.vV = x; | |||
| console.dir(o.vV) | |||
| console.dir('console.dir(o).......................') | |||
| console.dir(o) | |||
| console.dir('console.dir(o).......................') | |||
| console.dir(o.vV) | |||
| // console.log("" + (o.vV.current=== x)) | |||
| console.log(assert.deepEqual(o.vV, x)); | |||
| // console.log(assert.strictEqual(o.vV, x, 'o being a Versioned o.vV and { a : 5 } found not strict equal')); | |||
| console.log(assert.strictEqual(o.vV.current, x, 'but is not')); | |||
| x = { a: 4 } | |||
| o.vV.revision = x | |||
| console.dir(o.vV) | |||
| assert.deepEqual(o.vV, x); | |||
| // assert.strictEqual(o.vV, x); // Strictequal will not match coz we get a proxy... | |||
| // If we expect this to match use x = js.Versioned.create(x) which will be the proxy that will allways match. | |||
| // PB : TODO -- We don't necessarily need to convert every property in x to a versioned property... | |||
| assert.strictEqual(o.vV.current, x), 'but is not'; | |||
| o = js.Versioned.create() | |||
| x = { a: 5 } | |||
| o.vV = x; | |||
| console.dir(o.vV) | |||
| // console.log("" + (o.vV.current=== x)) | |||
| assert.deepEqual(o.vV, x, 'o.vV and { a : 5} found equal'); | |||
| // assert.strictEqual(o.vV.current, x), 'but is not'; | |||
| x = { a: 4 } | |||
| o.vV = x | |||
| console.dir(o.vV) | |||
| assert.deepEqual(o.vV, x); | |||
| var ten = { g : "10" } | |||
| // proxiedDescriptor.ten = ten; | |||
| var o1 = js.Versioned.create(); | |||
| // Object.defineProperty(o1, 'vV', proxiedDescriptor.create(o1, 'vV', null, proxiedDescriptor.current)); | |||
| // o1.vV = null; | |||
| // initial uninitialized state... | |||
| console.log('console.log(cloned.vV)') | |||
| console.log(o1.vV) | |||
| console.log(Object.prototype.toString.call(o1.vV)) | |||
| console.log('---------------------------------------------') | |||
| console.log('console.dir(o1.vV)') | |||
| console.dir(o1.vV) | |||
| console.log(Object.prototype.toString.call(o1.vV)) | |||
| // throw 'done' | |||
| console.log('---------------------------------------------') | |||
| console.log('util.inspect(o1.vV)') | |||
| console.log(util.inspect(o1.vV)) | |||
| console.log(Object.prototype.toString.call(o1.vV)) | |||
| console.log('---------------------------------------------') | |||
| o1.vV = { d : 7 } | |||
| console.dir(o1.vV) | |||
| o1.vV = { e : 8 } | |||
| console.dir(o1.vV) | |||
| o1.vV = { f : "9 Nine" } | |||
| console.dir(o1.vV) | |||
| debugger | |||
| o1.vV = ten | |||
| var a = o1.vV; | |||
| o1.vV = ten | |||
| // console.log(util.inspect(o1.vV)) | |||
| // console.log((o1.vV === ten)) | |||
| console.dir(o1.vV) | |||
| console.dir(o1.vV.g) | |||
| assert.deepEqual(o1.vV, ten); | |||
| assert.strictEqual(o1.vV, a); // Self identity via proxy === proxy. Instead of target === target which is effectively the same.. | |||
| console.dir('(ten == (+o1.vV))') | |||
| // console.dir((ten == (+o1.vV))) // false Doesn't work. Throws exception when valueOf and toString return non primitives. | |||
| console.dir((ten == o1.vV)) | |||
| console.dir((ten === o1.vV)) // false Doesn't work. coz getter always returns a proxy and not the target. The target indeed is === ten. | |||
| // The options therefore as alternative or === which fails for proxies are as below. | |||
| // Explicitly call valueOf or use a helper which gets the real target of the proxy | |||
| console.dir('(o1.vV.valueOf() === ten)') | |||
| console.dir((o1.vV.valueOf() === ten)) | |||
| assert.strictEqual(o1.vV.valueOf(), ten); | |||
| assert.strictEqual(js.Proxied.getTarget(o1.vV), ten); | |||
| // assert.strictEqual(o1.vV, ten); | |||
| // Test descriptor | |||
| var c = proxiedDescriptor.create(o1, 'dD', null, proxiedDescriptor.current); | |||
| Object.defineProperty(o1, 'dD', c); | |||
| var dD = Object.getOwnPropertyDescriptor(o1, "dD"); | |||
| console.dir('console.dir(c === dD)') | |||
| console.dir(c === dD) | |||
| console.log((dD.get === c.get) + ' ' + 'dD.get === c.get') | |||
| var d = Object.getOwnPropertyDescriptor(o1, "vV"); | |||
| console.dir(d); | |||
| console.dir('switching proxiedDescriptor type to composite revision') | |||
| proxiedDescriptor.switchTo(d, proxiedDescriptor['composite revision']) | |||
| o1.vV = { eleven : '11'} | |||
| console.dir('o1.vV') | |||
| console.dir(o1.vV) | |||
| assert.deepEqual(o1.vV, { g : "10", eleven : '11' } ); | |||
| // Direct access test... | |||
| var vV = o1.vV; | |||
| vV.revision = { "12" : 12 } | |||
| console.dir(vV); | |||
| console.dir(vV.composite); | |||
| assert.deepEqual(vV, o1.vV ); | |||
| var v = ['a', 'b', 'c']; | |||
| var b = v.valueOf() | |||
| console.log(v===b) | |||
| console.dir(b) | |||
| // Deref Tests. | |||
| var proxT = { a : 'A', b : { bv : 'bv'}, c : ['e', 4, { x : 'x'}]} | |||
| var prox = js.mutableProxy.create(proxT) | |||
| prox = js.mutableProxy.create(prox) | |||
| prox = js.mutableProxy.create(prox) | |||
| console.dir(prox) | |||
| console.dir(proxT === prox) | |||
| prox = js.mutableProxy.create(prox) | |||
| prox = js.mutableProxy.create(prox) | |||
| prox = js.mutableProxy.create(prox) | |||
| console.dir(js.dereference(prox)) | |||
| console.dir(proxT === js.dereference(prox)) | |||
| elxr = utils.elxr | |||
| // var bitsToset = 0 | |||
| // for(var i=0; i<32; i++) {bitsToset = js.setBit(i, bitsToset)} | |||
| // console.dir('' + elxr.toBitString(bitsToset) + ' (' + elxr.toBitString(bitsToset).length + ')') | |||
| // var unusedmasks = [] | |||
| // console.dir(unusedmasks.pop()) | |||
| // elxr.generateBitMaskedSequence([4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29]) | |||
| // elxr.insertBits(16, [1,2]) | |||
| console.dir(elxr.bitIndices) | |||
| console.dir(elxr.toBitString(elxr.bitIndices[31])) | |||
| console.dir(elxr.toBitString(elxr.insertBitsForMask(16, 6))) | |||
| var nwM = elxr.nextWithMask(6) | |||
| console.dir(elxr.toBitString(nwM.next().value)) | |||
| console.dir(elxr.toBitString(nwM.next().value)) | |||
| console.dir(elxr.toBitString(nwM.next().value)) | |||
| console.dir(elxr.toBitString(nwM.next().value)) | |||