[react-packager] onchange endpoint that informs of changes
This commit is contained in:
parent
b9207a3095
commit
c99284bfdf
|
@ -45,6 +45,7 @@ describe('processRequest', function() {
|
|||
var invalidatorFunc = jest.genMockFunction();
|
||||
var watcherFunc = jest.genMockFunction();
|
||||
var requestHandler;
|
||||
var triggerFileChange;
|
||||
|
||||
beforeEach(function() {
|
||||
Packager = require('../../Packager');
|
||||
|
@ -61,7 +62,15 @@ describe('processRequest', function() {
|
|||
});
|
||||
};
|
||||
|
||||
FileWatcher.prototype.on = watcherFunc;
|
||||
|
||||
FileWatcher.prototype.on = function(eventType, callback) {
|
||||
if (eventType !== 'all') {
|
||||
throw new Error('Can only handle "all" event in watcher.');
|
||||
}
|
||||
watcherFunc.apply(this, arguments);
|
||||
triggerFileChange = callback;
|
||||
return this;
|
||||
};
|
||||
|
||||
Packager.prototype.invalidateFile = invalidatorFunc;
|
||||
|
||||
|
@ -109,17 +118,6 @@ describe('processRequest', function() {
|
|||
|
||||
|
||||
describe('file changes', function() {
|
||||
var triggerFileChange;
|
||||
beforeEach(function() {
|
||||
FileWatcher.prototype.on = function(eventType, callback) {
|
||||
if (eventType !== 'all') {
|
||||
throw new Error('Can only handle "all" event in watcher.');
|
||||
}
|
||||
triggerFileChange = callback;
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
||||
pit('invalides files in package when file is updated', function() {
|
||||
return makeRequest(
|
||||
requestHandler,
|
||||
|
@ -175,4 +173,36 @@ describe('processRequest', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('/onchange endpoint', function() {
|
||||
var EventEmitter;
|
||||
var req;
|
||||
var res;
|
||||
|
||||
beforeEach(function() {
|
||||
EventEmitter = require.requireActual('events').EventEmitter;
|
||||
req = new EventEmitter();
|
||||
req.url = '/onchange';
|
||||
res = {
|
||||
writeHead: jest.genMockFn(),
|
||||
end: jest.genMockFn()
|
||||
};
|
||||
});
|
||||
|
||||
it('should hold on to request and inform on change', function() {
|
||||
server.processRequest(req, res);
|
||||
triggerFileChange('all', 'path/file.js', options.projectRoots[0]);
|
||||
jest.runAllTimers();
|
||||
expect(res.end).toBeCalledWith(JSON.stringify({changed: true}));
|
||||
});
|
||||
|
||||
it('should not inform changes on disconnected clients', function() {
|
||||
server.processRequest(req, res);
|
||||
req.emit('close');
|
||||
jest.runAllTimers();
|
||||
triggerFileChange('all', 'path/file.js', options.projectRoots[0]);
|
||||
jest.runAllTimers();
|
||||
expect(res.end).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -50,6 +50,7 @@ function Server(options) {
|
|||
this._projectRoots = opts.projectRoots;
|
||||
this._packages = Object.create(null);
|
||||
this._packager = new Packager(opts);
|
||||
this._changeWatchers = [];
|
||||
|
||||
this._fileWatcher = options.nonPersistent
|
||||
? FileWatcher.createDummyWatcher()
|
||||
|
@ -65,6 +66,7 @@ Server.prototype._onFileChange = function(type, filepath, root) {
|
|||
// Make sure the file watcher event runs through the system before
|
||||
// we rebuild the packages.
|
||||
setImmediate(this._rebuildPackages.bind(this, absPath));
|
||||
setImmediate(this._informChangeWatchers.bind(this));
|
||||
};
|
||||
|
||||
Server.prototype._rebuildPackages = function() {
|
||||
|
@ -83,6 +85,20 @@ Server.prototype._rebuildPackages = function() {
|
|||
});
|
||||
};
|
||||
|
||||
Server.prototype._informChangeWatchers = function() {
|
||||
var watchers = this._changeWatchers;
|
||||
var headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
};
|
||||
|
||||
watchers.forEach(function(w) {
|
||||
w.res.writeHead(205, headers);
|
||||
w.res.end(JSON.stringify({ changed: true }));
|
||||
});
|
||||
|
||||
this._changeWatchers = [];
|
||||
};
|
||||
|
||||
Server.prototype.end = function() {
|
||||
q.all([
|
||||
this._fileWatcher.end(),
|
||||
|
@ -142,6 +158,24 @@ Server.prototype._processDebugRequest = function(reqUrl, res) {
|
|||
}
|
||||
};
|
||||
|
||||
Server.prototype._processOnChangeRequest = function(req, res) {
|
||||
var watchers = this._changeWatchers;
|
||||
|
||||
watchers.push({
|
||||
req: req,
|
||||
res: res,
|
||||
});
|
||||
|
||||
req.on('close', function() {
|
||||
for (var i = 0; i < watchers.length; i++) {
|
||||
if (watchers[i] && watchers[i].req === req) {
|
||||
watchers.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Server.prototype.processRequest = function(req, res, next) {
|
||||
var urlObj = url.parse(req.url, true);
|
||||
var pathname = urlObj.pathname;
|
||||
|
@ -154,6 +188,9 @@ Server.prototype.processRequest = function(req, res, next) {
|
|||
} else if (pathname.match(/^\/debug/)) {
|
||||
this._processDebugRequest(req.url, res);
|
||||
return;
|
||||
} else if (pathname.match(/^\/onchange\/?$/)) {
|
||||
this._processOnChangeRequest(req, res);
|
||||
return;
|
||||
} else {
|
||||
next();
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue