const devbug = { outs: {}, url: 'http://localhost:8000/', api_key: false, out(key, what, group=false){ console.log(this) if ( group ){ if ( !Object.keys(this.outs).includes(group) ) this.outs[group] = {} this.outs[group][key] = what return this; } this.outs[key] = what return this; }, script(addr, then){ var sc = document.createElement('script'); sc.src = addr; sc.type = 'text/javascript'; sc.onload = then; document.getElementsByTagName('head')[0].appendChild(sc); return this; }, load_dc: function(then){ this.script(this.url+'assets/cycle.js', then); return this; }, load_jq: function(then){ this.script('https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js', () => { $ = window.jQuery; $(then); }); return this; }, libs: function(then){ // need both if ( typeof JSON.rmref !== 'function' && typeof window.jQuery !== 'function' ) this.load_dc(() => this.load_jq(then)) // need decycle else if ( typeof JSON.rmref !== 'function' ) this.load_dc(then) // need jquery else if ( typeof window.jQuery !== 'function' ) this.load_jq(then) else then() return this; }, json(data){ return JSON.stringify(JSON.rmref(JSON.decycle(data))); }, breakpoint(except = false, name){ var e = new Error(); this.libs(() => { var s = e.stack.split('at'); var caller = ''; if ( s.length < 3 ) s = e.stack.split('@') if ( s.length > 2 ) caller = s[2].trim() else if ( s.length > 1 ) caller = s[1] else caller = 'Unable to determine stacktrace' var data = new FormData(); data.append('data', this.json({ brief: (name ? name : 'Breakpoint')+`: ${caller}`, data: this.outs, })) $.ajax({ url: this.url+'api/v1/out/'+this.api_key, data, cache: false, contentType: false, processData: false, method: 'POST', type: 'POST', success: (res) => { console.log('DevBug POST Completed'); console.debug(res); } }) }) if ( exception ) throw e return this } } window.devbug = devbug; window.out = window.devbug.out.bind(window.devbug); window.breakpoint = window.devbug.breakpoint.bind(window.devbug);