[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 invalidatorFunc = jest.genMockFunction();
|
||||||
var watcherFunc = jest.genMockFunction();
|
var watcherFunc = jest.genMockFunction();
|
||||||
var requestHandler;
|
var requestHandler;
|
||||||
|
var triggerFileChange;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
Packager = require('../../Packager');
|
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;
|
Packager.prototype.invalidateFile = invalidatorFunc;
|
||||||
|
|
||||||
|
@ -109,17 +118,6 @@ describe('processRequest', function() {
|
||||||
|
|
||||||
|
|
||||||
describe('file changes', 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() {
|
pit('invalides files in package when file is updated', function() {
|
||||||
return makeRequest(
|
return makeRequest(
|
||||||
requestHandler,
|
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._projectRoots = opts.projectRoots;
|
||||||
this._packages = Object.create(null);
|
this._packages = Object.create(null);
|
||||||
this._packager = new Packager(opts);
|
this._packager = new Packager(opts);
|
||||||
|
this._changeWatchers = [];
|
||||||
|
|
||||||
this._fileWatcher = options.nonPersistent
|
this._fileWatcher = options.nonPersistent
|
||||||
? FileWatcher.createDummyWatcher()
|
? FileWatcher.createDummyWatcher()
|
||||||
|
@ -65,6 +66,7 @@ Server.prototype._onFileChange = function(type, filepath, root) {
|
||||||
// Make sure the file watcher event runs through the system before
|
// Make sure the file watcher event runs through the system before
|
||||||
// we rebuild the packages.
|
// we rebuild the packages.
|
||||||
setImmediate(this._rebuildPackages.bind(this, absPath));
|
setImmediate(this._rebuildPackages.bind(this, absPath));
|
||||||
|
setImmediate(this._informChangeWatchers.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
Server.prototype._rebuildPackages = function() {
|
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() {
|
Server.prototype.end = function() {
|
||||||
q.all([
|
q.all([
|
||||||
this._fileWatcher.end(),
|
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) {
|
Server.prototype.processRequest = function(req, res, next) {
|
||||||
var urlObj = url.parse(req.url, true);
|
var urlObj = url.parse(req.url, true);
|
||||||
var pathname = urlObj.pathname;
|
var pathname = urlObj.pathname;
|
||||||
|
@ -154,6 +188,9 @@ Server.prototype.processRequest = function(req, res, next) {
|
||||||
} else if (pathname.match(/^\/debug/)) {
|
} else if (pathname.match(/^\/debug/)) {
|
||||||
this._processDebugRequest(req.url, res);
|
this._processDebugRequest(req.url, res);
|
||||||
return;
|
return;
|
||||||
|
} else if (pathname.match(/^\/onchange\/?$/)) {
|
||||||
|
this._processOnChangeRequest(req, res);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue