UNPKG

miru

Version:

web development server for bundlers and/or static files, parses terminal and DOM errors ( inline sourcemaps supported )

1 lines 14.5 kB
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).miru=e()}}(function(){return function e(t,o,r){function n(s,c){if(!o[s]){if(!t[s]){var a="function"==typeof require&&require;if(!c&&a)return a(s,!0);if(i)return i(s,!0);var l=new Error("Cannot find module '"+s+"'");throw l.code="MODULE_NOT_FOUND",l}var f=o[s]={exports:{}};t[s][0].call(f.exports,function(e){var o=t[s][1][e];return n(o||e)},f,f.exports,e,t,o,r)}return o[s].exports}for(var i="function"==typeof require&&require,s=0;s<r.length;s++)n(r[s]);return n}({1:[function(e,t,o){"use strict";t.exports=function(t){function o(){q&&console.log.apply(this,arguments)}function r(){d.writeFileSync(X,n()),o("miru-connect.js saved to: "+X)}function n(){var e=d.readFileSync(Q,"utf8");return e="\n ;(function () {\n window.__miru = {\n verbose: "+!!q+",\n forceReload: "+!!A.reload+",\n styleFlicker: "+!A.noflicker+",\n targets: "+JSON.stringify(b.getWatched())+"\n }\n })();\n "+e+"\n ",Buffer.from(e)}function i(e){var t=p.parse(e),o="";return o+=t.os.name,o+=" "+t.os.version,o+=" "+t.browser.name,o+=" "+t.browser.version,o+=" "+t.device.vendor,o+=" "+t.device.model,o+=" "+t.device.type,o=o.split(/\s+/).filter(function(e){var t=e.toLowerCase().trim();return"other"!==t&&"0.0.0"!==t&&"undefined"!==t&&t}).join(" ").trim()}function s(){console.log("LAN addresses: "+function(){var e,t,o=W.networkInterfaces(),r=[];for(e in o)for(t in o[e]){var n=o[e][t];"IPv4"!==n.family||n.internal||r.push(n.address)}return r}().join(","))}function c(e){e.rw&&(o("closing recovery watcher, files watched: "+e.rw.getWatched().length),e.rw.clear(),e.rw.close(),0===e.rw.getWatched().length&&console.log("recovery watcher closed"),N=[],delete e.rw);var t=e.command,r=g.resolve(e.target);"string"==typeof t&&(t=t.split(/\s+/));var n=t[0],i=t.slice(1);o("spawning: "+n+" "+i.join(" "));var s,l=m.spawn(n,i),f="",u=function(t){var n=t.toString("utf8");f+=n,clearTimeout(s),s=setTimeout(function(){var t=!1,n=f.split("\n");if(f="",n.forEach(function(e){-1!==e.toLowerCase().indexOf("error")&&(t=!0)}),n=n.filter(function(e){return-1===e.indexOf("node_modules")}),t){o(" == Errors found == ");var i=n.join("\n");a(r,i)}else n.forEach(function(e){console.log(e)}),d.stat(g.resolve(e.target),function(t,o){t&&("ENOENT"===t.code?console.error("warning: watcher target file does not exist: "+e.target):console.error("warning: could not access watcher target file: "+e.target))})},B)};l.stdout.on("data",u),l.stderr.on("data",u),l.on("exit",function(){setTimeout(function(){console.log(" watcher exited [ "+e.command+" ], target: "+e.target),function(e){function t(t,n){switch("init"===t&&e.rw&&(clearTimeout(i),i=setTimeout(function(){N=e.rw.getWatched().slice(),console.log("recovery watcher watching "+N.length+" files - type 'recovery' to see list")},300)),t){case"add":case"change":o("recovery watcher change detected: "+n),clearTimeout(r),r=setTimeout(function(){e.rw&&(o("closing recovery watcher, files watched: "+e.rw.getWatched().length),e.rw.clear(),e.rw.close(),0===e.rw.getWatched().length&&o("recovery watcher closed"),N=[],delete e.rw),c(e)},1500)}}console.log("launching recovery watcher for [ "+e.command+" ], target: "+e.target);var r,n=e.target;n.indexOf(".css")>0||n.indexOf(".styl")>0||n.indexOf(".sass")>0||n.indexOf(".scss")>0||n.indexOf(".less")>0?(o("recovering style watcher"),e.rw=v.watch(t),e.rw.add("**/*.css"),e.rw.add("**/*.styl"),e.rw.add("**/*.sass"),e.rw.add("**/*.scss"),e.rw.add("**/*.less")):n.indexOf(".js")>0||n.indexOf(".jsx")>0?(o("recovering javascript watcher"),e.rw=v.watch(t),e.rw.add("**/*.js"),e.rw.add("**/*.jsx")):o("failed to setup recovery watcher, target not recognized: "+n);var i}(e)},100)})}function a(e,t,r){var n=Date.now(),i={time:Date.now(),raw:t,target:e,ranking:r||0};if(A["no-wooster"])i.text=t;else{var s=w.parse(t);if(s){i.text=s.text,i.context=s.context;var c=s.filename;c&&(i.filename=c)}else i.text=t}var a=U.history[U.history.length-1],u=!1;if(a){n-a.time<U.THROTTLE&&(a.raw===i.raw||a.text===i.text||i.context&&a.context===i.context)&&(i.ranking>a.ranking&&(a.text=i.text,o("duplicate error outranked")),o(_.blackBright("ignoring duplicate error")),u=!0)}return u?o("skipping error"):(U.history.push(i),H[g.resolve(e)]={error:i},U.history.length>20&&U.history.shift(),o("debouncing error"),clearTimeout(U.timeout),U.timeout=setTimeout(function(){var t="";t+=function(){ee=(ee+1)%te;for(var e="",t=0;t<te;t++)e+=t===ee?_.bgMagentaBright(" "):" ";return e}()+"\n",t+=i.text,f(),l(t);var o=Date.now();D.emit("terminal-error",{target:e,timestamp:o,output:t,error:i}),[33,100,300,500].forEach(function(e){setTimeout(function(){D.emit("terminal-error",{timestamp:o,output:t,error:i})},e)});var r=H[g.resolve(e)];r&&(r.output=t)},U.DEBOUNCE)),i}function l(e){L=e;var t=e.split("\n"),o=process.stdout.columns-1;A.nolimit&&(o=999),t.forEach(function(e){for(var t=!1;E(e)>o;)t=!0,e=e.slice(0,-1);t&&(e+=_.bgWhite(">")),"\n"!==e[e.length-1]&&(e+=_.white("\n")),process.stdout.write(e)})}function f(){var e=(new Date).toTimeString().split(" ")[0];q||process.env.MIRU_NOCLEAR?(console.log(),console.log(" === CLEAR === "+e),console.log()):process.stdout.write("c")}var u,d=e("fs"),g=e("path"),m=e("child_process"),h=[],p={parse:e("ua-parser-js")},v=e("miteru"),w=e("wooster"),x=[],y=v.watch(function(e,t){if(clearTimeout(u),u=setTimeout(function(){console.log("number of --files watched: "+y.getWatched().length)},1e3),"add"===e||"change"===e){var o=g.relative(process.cwd(),t);x.forEach(function(t){console.log("command: "+t),t=t.split("$evt").join(e).split("$file").join(o),console.log("executing: "+t),m.exec(t,function(e,t,o){e?console.error("exec error: "+e):(t&&console.log(t),o&&console.log(o))})})}}),b=v.watch(function(e,t){switch(o("evt: "+e+", filepath: "+t),e){case"add":case"change":d.readFile(t,"utf8",function(e,r){var n=!1,i=r.slice(0,500);if(-1!==i.toLowerCase().indexOf("error")&&w(i)!==i&&(n=!0),!1===n)(c=g.resolve(t))&&H[c]&&(H[c].error=void 0,H[c].output=void 0),console.log("sending target build success: "+g.relative(process.cwd(),t)),D.emit("target-build",{target:t});else{o(" === target error detected === ");var s=a(c,i,-1),c=g.resolve(t);H[c].error||(o("target error attached"),H[c].error=s)}})}}),E=e("string-width"),j=(e("assert"),e("http")),O=e("express"),k=e("cors"),T=e("body-parser"),M=O(),S=j.createServer(M),D=e("kiite")(S),W=e("os"),_=e("cli-color"),C=JSON.parse(t.packageJson),N=[],L="",F=!1,A=e("subarg")(process.argv.slice(2),{alias:{watch:["w","watcher","watched"],file:["f","files"],execute:["e","ex","exe","exec"],targets:["t","targets"],reload:["r"],debounce:[],throttle:[],"public-path":["public","p","path"],"no-wooster":[],"no-miru-connect":[],"no-clear":[],development:["D"],verbose:["v"],version:["V"],help:["h"]},boolean:["noflicker","nolimit","version","verbose","help","no-wooster","no-miru-connect","no-clear","development"],unknown:function(e){console.log("uknown argument: "+e)}}),q=!!A.verbose;if(A.targets){"string"==typeof($=A.targets)&&($=[$]),$ instanceof Array||(console.error("-t, --targets <string> parse error - missing file names?"),process.exit(1)),$.forEach(function(e){o("adding watch target: "+e),b.add(e)}),o("target files watched :"),o(b.getWatched())}o("verbose: "+q);var R=A["public-path"];R||(R=process.cwd(),o("-p, --public-path, --path, --public was unset, defaulting to process.cwd()")),o("publicPath is: "+(R=g.resolve(R)));var B=33,U={DEBOUNCE:33,THROTTLE:1e3,history:[]},H={},I={},J=A.port||4040,z=A.address||"0.0.0.0";if(A.version&&(console.log("miru version: "+C.version),process.exit(0)),A.help){var P=t.usage;console.log(P),process.exit(0)}if(A.file){var $=A.file;"string"==typeof $&&($=[$]),$ instanceof Array||(console.error("-f, --file, --files <string> parse error - missing file names?"),process.exit(1)),$.forEach(function(e){o("adding watch file: "+e),y.add(e)}),o("watched files:"),o(y.getWatched())}if(A.execute){var V=A.execute;"string"==typeof V&&(V=[V]),V instanceof Array||(console.error("-e, --execute <string> parse error - missing commands?"),process.exit(1)),x=V}o("executions: "),o(x);var G=[];if(A.watch){(G=A.watch)instanceof Array||(G=[G]),o(G);var K=[];G.forEach(function(e){var t=e._.join(" ").split(",");2!==t.length&&(console.error("-w, --watch [ <command>, <file> ] parse error - invalid format?"),console.error("samples:"),console.error(" miru -w [ npm run watch:js, dist/bundle.js ]"),console.error(" miru -w [ webpack --watch src/main.js -o dist/bundle.js, dist/bundle.js ]"),process.exit(1));o("command: "+(e={command:t[0].trim(),target:t[1].trim()}).command),o("target file: "+e.target),K.push(e);var r=g.resolve(e.target);o("initializing target: "+e.target),H[r]={},b.add(r);try{d.statSync(g.resolve(e.target))}catch(t){"ENOENT"===t.code?console.error("warning: watcher target file does not exist: "+e.target):console.error("warning: could not access watcher target file: "+e.target)}}),G=K}o("watchers: "),o(G);var Q=t.miruConnectSource,X=g.join(R,"miru-connect.js");try{if(A["no-miru-connect"]||r(),d.readFileSync(X).equals(n()),o("up to date miru-connect.js found at: "+X),A.development){v.watch(Q,function(e,t){switch(e){case"add":case"change":r(),console.log("emitting reload on miru-connect.js change"),function(e,t){console.log("emitting: "+e+", "+t),D.emit(e,t)}("reload")}});console.log("watching miru-connect.js")}}catch(e){throw o("failed to load or save miru-connect.js to users project"),e}o("[express]: cors"),M.use(k()),M.get("/favicon*",function(e,o){o.sendFile(t.favicon)}),M.get("/__miru/pesticide.css",function(e,o){o.sendFile(t.pesticide)}),M.post("/__miru/woosterify",T.json(),function(e,t){var o=e.body,r=w.parseContext({prettify:!0,text:o.text,filename:o.filename,lineno:o.lineno,colno:o.colno}),n=i(e.headers["user-agent"]),s=w.createMessage({postintro:" "+_.bgWhite("DOM Error")+" ["+n+"]",message:o.message,filename:r.filename,ctx:r}),c=void 0;if(r.usedSourceMap){var a=w.parseContext({prettify:!0,disableSourceMaps:!0,text:o.text,filename:o.filename,lineno:o.lineno,colno:o.colno});c=w.createMessage({message:o.message,filename:a.filename,ctx:a})}f(),l(s),t.status(200).json({target:"DOM",name:"Error",message:s,origin:c}).end()}),M.post("/__miru/console",T.json(),function(e,t){e.body.host;var o=i(e.get("user-agent"));I[o].logs=logs}),o("[express]: static directory: "+R),M.use(O.static(R)),M.get("/",function(e,o,r){o.sendFile(t.indexHTML)});var Y={};D.on("connect",function(e){var t=i(e.request.headers["user-agent"]),r={id:t};I[t]=r,e.miru={client:r},console.log("client connected: "+t),F&&e.emit("pesticide",F),Object.keys(H).forEach(function(t){var r=H[t];r.output&&r.error&&(o("emitting unresolved error to new connection"),e.emit("terminal-error",{timestamp:Date.now(),output:r.output,error:r.error}))}),e.on("ack",function(e){Y[e]=!0,setTimeout(function(){delete Y[e]},3e4)}),e.on("woosterify",function(t,o,r){if(!Y[t]){Y[t]=!0;var n=w.parseContext({prettify:!0,text:o.text,filename:o.filename,lineno:o.lineno,colno:o.colno}),i=e.miru.client.id,s=w.createMessage({postintro:" "+_.bgWhite("DOM Error")+" ["+i+"]",message:o.message,filename:n.filename,ctx:n}),c=void 0;if(n.usedSourceMap){var a=w.parseContext({prettify:!0,disableSourceMaps:!0,text:o.text,filename:o.filename,lineno:o.lineno,colno:o.colno});c=w.createMessage({message:o.message,filename:a.filename,ctx:a})}f(),l(s),r({target:"DOM",name:"Error",message:s,origin:c})}}),e.on("console",function(t){t.host;var o=e.miru.client.id,r=I[o],n=t.logs;n.forEach(function(e){}),r.logs=n}),e.on("disconnect",function(){e.miru.client.id})});var Z=!1;setTimeout(function(){b.getWatched().length>0?(o("[express]: starting server at "+z+":"+J),Z=!0,S.listen(J,z,function(){var e=S.address();console.log("server listening at *:"+e.port+" ( "+e.family+" "+e.address+" )"),s()})):(console.log("[miru]: no --targets ( or --watch ) specified"),console.log("[miru]: -> no need for server, server not started."))},500),G.forEach(function(e){c(e)});var ee=-1,te=4;process.on("exit",function(){h.forEach(function(e){try{e.kill()}catch(e){}})});var oe,re={devices:function(e){f(),Object.keys(I).forEach(function(e,t){var o=I[e];console.log(" "+t+": "+o.id)})},logs:function(e){var t=e[0];f(),Object.keys(I).forEach(function(e,o){if(!t||o==t){var r=I[e];console.log(" "+ +o+": "+r.id+" -- logs: ");(r.logs||[]).forEach(function(e){console.log.apply(this,[e.type+":"].concat(e.args))})}})},reload:function(){D.emit("reload")},recovery:function(){var e=N;e.forEach(function(e){console.log(" "+e)}),console.log("recovery watcher watching "+e.length+" files")},previous:function(){L&&(f(),l(L))},pesticide:function(e){var t=!1;switch(String(e[0]||"").trim()){case"false":case"off":case"0":case"":t=!1;break;default:t=!0}console.log("sending pesticide: "+t),F=t,D.emit("pesticide",t)},address:s,ip:s,lan:s,watchers:function(e){console.log(" watchers: ");var t=0;G.forEach(function(e){e.command.length>t&&(t=e.command.length)}),G.forEach(function(e){var o=t-e.command.length+4;process.stdout.write(" "+e.command);for(var r=0;r<o;r++)process.stdout.write(" ");process.stdout.write(e.target+"\n")})},targets:function(e){var t=b.getWatched();t.forEach(function(e){console.log(" "+e)}),console.log("watched --targets: "+t.length)},error:function(e){Object.keys(H).forEach(function(e){var t=H[e];t.output&&t.error&&(D.emit("terminal-error",{timestamp:Date.now(),output:t.output,error:t.error}),l(t.output))})},executions:function(){console.log("executions: "+x.length),console.log(x)},files:function(){var e=y.getWatched();e.forEach(function(e){console.log(" "+e)}),console.log("watched --files: "+e.length)}};process.stdin.on("data",function(e){var t=e.toString("utf8").toLowerCase().trim().split(/\s+/),o=t[0];if(!o&&oe)return oe();var r=t.slice(1),n=Object.keys(re).filter(function(e){return e.indexOf(o)>=0}).sort(function(e,t){return e.indexOf(o)-t.indexOf(o)}),i=re[n[0]];"function"==typeof i?(oe=function(){i(r)},i(r)):console.log("unknown command: "+o)})}},{assert:void 0,"body-parser":void 0,child_process:void 0,"cli-color":void 0,cors:void 0,express:void 0,fs:void 0,http:void 0,kiite:void 0,miteru:void 0,os:void 0,path:void 0,"string-width":void 0,subarg:void 0,"ua-parser-js":void 0,wooster:void 0}]},{},[1])(1)});