UNPKG

2.84 kBJavaScriptView Raw
1var watch = require("./watch");
2var createBundleGraphStream = require("../graph/make_graph_with_bundles").createBundleGraphStream;
3var recycle = require("../graph/recycle");
4var createServer = require("../create_websocket_server");
5var defaults = require("lodash").defaults;
6var logging = require("../logger");
7var toPromise = require("./to_promise");
8
9var WS_CONNECTING = 0;
10var WS_OPEN = 1;
11
12module.exports = function(config, options){
13 if(!options) options = {};
14 defaults(options, { quiet: true });
15 logging.setup(options, config);
16 options.localStealConfig = {
17 env: "build-development"
18 };
19
20 // Create an initial dependency graph for this config.
21 var initialGraphStream = createBundleGraphStream(config, options);
22 // Create a stream that is used to regenerate a new graph on file changes.
23 var graphStream = recycle(config, options);
24 var graphPromise = toPromise(graphStream);
25
26 // Pipe the graph stream into the recycleStream so it can get the initial
27 // graph.
28 initialGraphStream.pipe(graphStream);
29
30 // Setup the websocket connection.
31 createServer(options).then(function(wss){
32 var port = wss.options.server.address().port;
33
34 function isStaleConnection(ws, error) {
35 var rs = ws.readyState;
36 return error.errno === "ECONNRESET" &&
37 (rs !== WS_OPEN && rs !== WS_CONNECTING);
38 }
39
40 wss.on("connection", function(ws){
41 // Get the initial graph for this main,
42 // if it's not already part of the graph.
43 ws.once("message", function(moduleName){
44 graphPromise.then(function(){
45 graphStream.write(moduleName);
46 });
47 });
48
49 ws.on("error", function(err){
50 if(!isStaleConnection(ws, err)) {
51 console.error("WebSocket error:", err);
52 }
53 });
54 });
55
56 watch(graphStream).on("data", onChange);
57
58 function onInitialError(err) {
59 graphStream.emit("error", err);
60 }
61
62 initialGraphStream.once("error", onInitialError);
63
64 function onChange(moduleNames) {
65 if(moduleNames.length) {
66 console.error("Reloading", moduleNames[0].green);
67
68 // Alert all clients of the change
69 wss.clients.forEach(function(ws){
70 var msg = JSON.stringify(moduleNames);
71 ws.send(msg);
72 });
73
74 // Update our dependency graph
75 moduleNames.forEach(function(moduleName){
76 graphStream.write(moduleName);
77 });
78 } else {
79 graphStream.write("");
80 }
81 }
82
83 graphStream.once("data", function(){
84 initialGraphStream.removeListener("error", onInitialError);
85
86 console.error("Live-reload server listening on port", port);
87 });
88
89 graphStream.on("error", function(err){
90 if(err.moduleName) {
91 console.error("Oops! Error reloading", err.moduleName.red);
92 } else {
93 console.error(err);
94 }
95 });
96
97 graphStream.on("end", function(){
98 wss.close();
99 wss.server.close();
100 });
101
102 initialGraphStream.write(config.main);
103 }, function(){
104 process.exit(1);
105 });
106
107 return graphStream;
108};