var cl = global.botanLoader; var Dragonfly = global.Dragonfly; var util = require( "util" ); var events = require( "events" ); var zlib = require( "zlib" ); var http = require( "http" ); var conf = cl.load( "config.all" ).botanjs; var Session = cl.load( "botansx.modular.session" ); var hash = cl.load( "botansx.utils.hash" ); var rand = cl.load( "botansx.utils.random" ); var BotanJS = function() { events.EventEmitter.call( this ); this.sv = {}; this.kv = {}; this.embed = {}; this._nonce = {}; }; util.inherits( BotanJS, events.EventEmitter ); var _trim = function( s ) { if( 100 < s.length ) { return "[BLOB: " + s.substr( 0, 20 ) + " ...]"; } return s; }; BotanJS.prototype.unshift = function() { for( var i in arguments ) { var mod = arguments[i]; this.sv[ mod ] = true; this.remove( mod ); } }; BotanJS.prototype.push = function() { for( var i in arguments ) { this.kv[ arguments[i] ] = true; } }; BotanJS.prototype.remove = function( mod ) { delete this.kv[ mod ]; }; BotanJS.prototype.storeForRender = function( rainet, type, ch ) { var _self = this; if( ch.endsWith( "." + type ) ) { _self[ type ] = rainet + ch; } else { _self.embed[ type ] = ch; } }; BotanJS.prototype.nonce = function( type ) { return ( this._nonce[ type ] ||= rand.randstr( 8 ) ); }; BotanJS.prototype.compile = function( type ) { var _self = this; var j = conf.debug ? [ "Components.Console" ] : []; for( var i in this.sv ) if( this.sv[ i ] ) j.push( i ); for( var i in this.kv ) if( this.kv[ i ] ) j.push( i ); var rainet = conf.rinet || conf.serviceUri; if( conf.type && "or".indexOf( conf.type ) != -1 ) { this[ type ] = rainet + conf.type + type + "/" + j.join( "/" ); this.emit( "complete" ); return; } var gErr = function( mesg ) { Dragonfly.Error( mesg ); _self.emit( "complete" ); }; var q = j.join( "," ); var lookupKey = hash.md5( q ); var fastCache = new Session( lookupKey, "BOTAN_JCACHE", true ); var deflateComplete = function( err, data ) { if( err ) { gErr( err.message ); return; } var suri = conf.serviceUri + type + "/?p=" + encodeURIComponent( data.toString( "base64" ) ); var req = http.get( suri , function( res ) { res.setEncoding( "utf8" ); var ch = ""; res.on( "data", ( x ) => ch += x ); res.on( "end", function() { _self.storeForRender( rainet, type, ch ); Dragonfly.Debug( "Storing " + _trim( ch ) + " to fastcache[ " + fastCache.id + " ]" ); fastCache.spawn( 10 ); fastCache.set({ type: ch }); if( res.statusCode != 200 ) { _self.emit( "error", "Service calling failed: " + suri, ch ); return; } _self.emit( "complete" ); } ); } ).on( "error", gErr ); }; fastCache.addListener( "ready", function( fCache ) { var k = fCache.get( type ); if( k ) { Dragonfly.Debug( "FastCache: " + k ); fCache.expire( 30 ); _self.storeForRender( rainet, type, k ); _self.emit( "complete" ); } else { zlib.deflate( q, deflateComplete ); } } ); }; module.exports = BotanJS;