Make the DeltaCalculator and the DeltaTransformer emit change events

Reviewed By: jeanlauliac

Differential Revision: D5765042

fbshipit-source-id: 5b45cc425b6afb4f8cead80ce967263936baa8c1
This commit is contained in:
Rafael Oleza 2017-09-05 07:10:42 -07:00 committed by Facebook Github Bot
parent 8b6d69b645
commit 387a55de40
4 changed files with 58 additions and 10 deletions

View File

@ -12,6 +12,8 @@
'use strict';
const {EventEmitter} = require('events');
import type Bundler, {BundlingOptions} from '../Bundler';
import type {Options as JSTransformerOptions} from '../JSTransformer/worker';
import type Resolver from '../Resolver';
@ -31,7 +33,7 @@ export type DeltaResult = {
* traverse the files that have been changed between calls and avoid having to
* traverse the whole dependency tree for trivial small changes.
*/
class DeltaCalculator {
class DeltaCalculator extends EventEmitter {
_bundler: Bundler;
_resolver: Resolver;
_options: BundleOptions;
@ -46,6 +48,8 @@ class DeltaCalculator {
_inverseDependencies: Map<string, Set<string>> = new Map();
constructor(bundler: Bundler, resolver: Resolver, options: BundleOptions) {
super();
this._bundler = bundler;
this._options = options;
this._resolver = resolver;
@ -166,8 +170,11 @@ class DeltaCalculator {
}): mixed => {
this._modifiedFiles.add(filePath);
// TODO: Check if path is in current dependencies. If so, send an updated
// bundle event.
// Notify users that there is a change in some of the bundle files. This
// way the client can choose to refetch the bundle.
if (this._dependencies.has(filePath)) {
this.emit('change');
}
};
async _getDelta(modifiedFiles: Set<string>): Promise<DeltaResult> {

View File

@ -14,6 +14,8 @@
const DeltaCalculator = require('./DeltaCalculator');
const {EventEmitter} = require('events');
import type Bundler from '../Bundler';
import type {Options as JSTransformerOptions} from '../JSTransformer/worker';
import type Resolver from '../Resolver';
@ -49,7 +51,7 @@ type Options = {|
* },
* }
*/
class DeltaTransformer {
class DeltaTransformer extends EventEmitter {
_bundler: Bundler;
_getPolyfills: ({platform: ?string}) => $ReadOnlyArray<string>;
_polyfillModuleNames: $ReadOnlyArray<string>;
@ -64,12 +66,16 @@ class DeltaTransformer {
options: Options,
bundleOptions: BundleOptions,
) {
super();
this._bundler = bundler;
this._deltaCalculator = deltaCalculator;
this._getPolyfills = options.getPolyfills;
this._polyfillModuleNames = options.polyfillModuleNames;
this._getModuleId = this._bundler.getGetModuleIdFn();
this._bundleOptions = bundleOptions;
this._deltaCalculator.on('change', this._onFileChange);
}
static async create(
@ -95,6 +101,8 @@ class DeltaTransformer {
* clean up memory and resources once this instance is not used anymore.
*/
end() {
this._deltaCalculator.removeListener('change', this._onFileChange);
return this._deltaCalculator.end();
}
@ -348,6 +356,10 @@ class DeltaTransformer {
return await module.read(transformOptions);
}
_onFileChange = () => {
this.emit('change');
};
}
module.exports = DeltaTransformer;

View File

@ -187,4 +187,26 @@ describe('DeltaCalculator', () => {
deleted: new Set(['/bar', '/baz']),
});
});
it('should emit an event when there is a relevant file change', async done => {
await deltaCalculator.getDelta();
deltaCalculator.on('change', () => done());
fileWatcher.emit('change', {eventsQueue: [{filePath: '/foo'}]});
});
it('should not emit an event when there is a file changed outside the bundle', async () => {
jest.useFakeTimers();
const onChangeFile = jest.fn();
await deltaCalculator.getDelta();
deltaCalculator.on('change', onChangeFile);
fileWatcher.emit('change', {eventsQueue: [{filePath: '/another'}]});
jest.runAllTimers();
expect(onChangeFile.mock.calls.length).toBe(0);
});
});

View File

@ -58,10 +58,19 @@ class DeltaBundler {
this._options = options;
}
/**
* Main method to build a Delta Bundler
*/
async build(options: Options): Promise<DeltaBundle> {
const {deltaTransformer, id} = await this.getDeltaTransformer(options);
const response = await deltaTransformer.getDelta();
return {
...response,
id,
};
}
async getDeltaTransformer(
options: Options,
): Promise<{deltaTransformer: DeltaTransformer, id: string}> {
let bundleId = options.deltaBundleId;
// If no bundle id is passed, generate a new one (which is going to be
@ -83,10 +92,8 @@ class DeltaBundler {
this._deltaTransformers.set(bundleId, deltaTransformer);
}
const response = await deltaTransformer.getDelta();
return {
...response,
deltaTransformer,
id: bundleId,
};
}