UNPKG

jungle-organic

Version:

The organic programming framework

140 lines (109 loc) 4.79 kB
namespace Jungle { export class ResolutionCell extends BaseCell { io:IO.ResolveIO; form:GForm; resolveCache:{ args:any, carried:any, selection:any, crowned:any, reduced:any } protected constructForm(){ return new GForm(this) } protected constructIO(iospec){ return new IO.ResolveIO(this, iospec) } protected constructCore(crown, form){ return new ResolutionCell(crown, form) } private resolveDenizen(handle, args, denizen, reference){ let mergekey = reference === undefined ? false : reference; if(denizen instanceof BaseCell && denizen !== undefined){ let denizenArg = args === undefined ? undefined : args[reference]; let resolved = denizen.resolve(denizenArg); handle.merge(resolved, mergekey); }else{ handle.merge(denizen, mergekey); } } //main recursion private resolveCell(handle:Util.Junction, node, carriedArgs, selection):any{ //log("node to resolve: ", node) //cutting dictates that we select nothing and therefore will var cut = false; if(!selection){ cut = true; }else if(selection === true && node instanceof Object){ //select all selection = Object.keys(node); } //at this stage cut determines primitives are nullified and objects empty const projectedCrown = this.crown; //TODO: projection onto selected keys; const core = this; //in here we have time to scan all Denizens and they will merge into the handle. let splitf = core.resolveDenizen.bind(core, handle, carriedArgs) Util.typeCaseSplitF(splitf)(projectedCrown); } resolve(resolveArgs){ Object.freeze(resolveArgs) // if(!this.prepared){ var pr = this.prepare(); } if (this.io.isShellBase && !this.io.specialGate){ //resolve external var sInpHook = this.io.specialInput var sInpResult = sInpHook.tractor.call(this.ctx.exposed, resolveArgs); var sResult; if(sInpResult != IO.HALT && (sInpHook.eager || sInpResult !== undefined)){ this.io.specialGate = true; sResult = this.resolve(sInpResult); this.io.specialGate = false; return sResult; }else{ //the input has failed to trigger resolution our output hook //will provide the return value on potentially undefined input return this.io.specialOutput.tractor.call(this.ctx.exposed, sInpResult); } }else{ this.resolveCache = { args:resolveArgs, carried:null, crowned:null, selection:null, reduced:null } //let [begin, raise] = this.junction.hold(); this.junction .then(this.resolveCarryThen.bind(this),false) .then(this.resolveCrownThen.bind(this),false) .then(this.resolveReduceThen.bind(this),false) .then(this.resolveCompleteThen.bind(this),false) //begin(); return this.junction.realize(); //var selection = this.form.selector.call(this.ctx.exposed, Object.keys(this.crown), this.resolveCache.resolveArgs); } } resolveCarryThen(results, handle){ //console.log("carry results:", results) this.ctx.exposed.handle = handle; return this.form.carrier.call(this.ctx.exposed, this.resolveCache.args); } resolveCrownThen(results, handle){ this.resolveCache.carried = results; return this.resolveCell(handle, this.crown, this.resolveCache.carried, true); } resolveReduceThen(results, handle){ this.resolveCache.crowned = results; this.ctx.exposed.handle = handle; return this.form.resolver.call(this.ctx.exposed, this.resolveCache.crowned, this.resolveCache.args, this.resolveCache.carried); } resolveCompleteThen(results, handle){ this.resolveCache.reduced = results; var dispached = this.io.dispatchResult(this.resolveCache.reduced); return dispached; } } }