mirror of https://github.com/status-im/metro.git
Add X-Metro-Files-Changed-Count HTTP header to the response when using Delta Bundler
Reviewed By: mjesun Differential Revision: D5793977 fbshipit-source-id: 9e0783356ca7574077d4eb06489e9837f033d986
This commit is contained in:
parent
bf64ba58d3
commit
197d885ec1
|
@ -28,6 +28,7 @@ class DeltaPatcher {
|
||||||
modules: new Map(),
|
modules: new Map(),
|
||||||
};
|
};
|
||||||
_initialized = false;
|
_initialized = false;
|
||||||
|
_lastNumModifiedFiles = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies a Delta Bundle to the current bundle.
|
* Applies a Delta Bundle to the current bundle.
|
||||||
|
@ -51,6 +52,9 @@ class DeltaPatcher {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._lastNumModifiedFiles =
|
||||||
|
deltaBundle.pre.size + deltaBundle.post.size + deltaBundle.delta.size;
|
||||||
|
|
||||||
this._patchMap(this._lastBundle.pre, deltaBundle.pre);
|
this._patchMap(this._lastBundle.pre, deltaBundle.pre);
|
||||||
this._patchMap(this._lastBundle.post, deltaBundle.post);
|
this._patchMap(this._lastBundle.post, deltaBundle.post);
|
||||||
this._patchMap(this._lastBundle.modules, deltaBundle.delta);
|
this._patchMap(this._lastBundle.modules, deltaBundle.delta);
|
||||||
|
@ -58,17 +62,27 @@ class DeltaPatcher {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of modified files in the last received Delta. This is
|
||||||
|
* currently used to populate the `X-Metro-Files-Changed-Count` HTTP header
|
||||||
|
* when metro serves the whole JS bundle, and can potentially be removed once
|
||||||
|
* we only send the actual deltas to clients.
|
||||||
|
*/
|
||||||
|
getLastNumModifiedFiles(): number {
|
||||||
|
return this._lastNumModifiedFiles;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the current delta bundle to a standard string bundle, ready to
|
* Converts the current delta bundle to a standard string bundle, ready to
|
||||||
* be interpreted by any JS VM.
|
* be interpreted by any JS VM.
|
||||||
*/
|
*/
|
||||||
stringifyCode() {
|
stringifyCode(): string {
|
||||||
const code = this._getAllModules().map(m => m.code);
|
const code = this._getAllModules().map(m => m.code);
|
||||||
|
|
||||||
return code.join('\n;');
|
return code.join('\n;');
|
||||||
}
|
}
|
||||||
|
|
||||||
stringifyMap({excludeSource}: {excludeSource?: boolean}) {
|
stringifyMap({excludeSource}: {excludeSource?: boolean}): string {
|
||||||
const mappings = fromRawMappings(this._getAllModules());
|
const mappings = fromRawMappings(this._getAllModules());
|
||||||
|
|
||||||
return mappings.toString(undefined, {excludeSource});
|
return mappings.toString(undefined, {excludeSource});
|
||||||
|
|
|
@ -92,4 +92,29 @@ describe('DeltaPatcher', () => {
|
||||||
.stringifyCode(),
|
.stringifyCode(),
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return the number of modified files in the last Delta', () => {
|
||||||
|
deltaPatcher
|
||||||
|
.applyDelta({
|
||||||
|
reset: 1,
|
||||||
|
pre: new Map([[1, {code: 'pre'}]]),
|
||||||
|
post: new Map([[2, {code: 'post'}]]),
|
||||||
|
delta: new Map([[3, {code: 'middle'}]]),
|
||||||
|
})
|
||||||
|
.stringifyCode();
|
||||||
|
|
||||||
|
expect(deltaPatcher.getLastNumModifiedFiles()).toEqual(3);
|
||||||
|
|
||||||
|
deltaPatcher
|
||||||
|
.applyDelta({
|
||||||
|
reset: 1,
|
||||||
|
pre: new Map([[1, null]]),
|
||||||
|
post: new Map(),
|
||||||
|
delta: new Map([[3, {code: 'different'}]]),
|
||||||
|
})
|
||||||
|
.stringifyCode();
|
||||||
|
|
||||||
|
// A deleted module counts as a modified file.
|
||||||
|
expect(deltaPatcher.getLastNumModifiedFiles()).toEqual(2);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -105,14 +105,20 @@ class DeltaBundler {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async buildFullBundle(options: FullBuildOptions): Promise<string> {
|
async buildFullBundle(
|
||||||
let output = (await this._getDeltaPatcher(options)).stringifyCode();
|
options: FullBuildOptions,
|
||||||
|
): Promise<{bundle: string, numModifiedFiles: number}> {
|
||||||
|
const deltaPatcher = await this._getDeltaPatcher(options);
|
||||||
|
let bundle = deltaPatcher.stringifyCode();
|
||||||
|
|
||||||
if (options.sourceMapUrl) {
|
if (options.sourceMapUrl) {
|
||||||
output += '//# sourceMappingURL=' + options.sourceMapUrl;
|
bundle += '//# sourceMappingURL=' + options.sourceMapUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return {
|
||||||
|
bundle,
|
||||||
|
numModifiedFiles: deltaPatcher.getLastNumModifiedFiles(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async buildFullSourceMap(options: FullBuildOptions): Promise<string> {
|
async buildFullSourceMap(options: FullBuildOptions): Promise<string> {
|
||||||
|
|
|
@ -924,12 +924,13 @@ class Server {
|
||||||
);
|
);
|
||||||
|
|
||||||
let bundle;
|
let bundle;
|
||||||
|
let numModifiedFiles;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
bundle = await this._deltaBundler.buildFullBundle({
|
({bundle, numModifiedFiles} = await this._deltaBundler.buildFullBundle({
|
||||||
...options,
|
...options,
|
||||||
deltaBundleId: this.optionsHash(options),
|
deltaBundleId: this.optionsHash(options),
|
||||||
});
|
}));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this._handleError(res, this.optionsHash(options), error);
|
this._handleError(res, this.optionsHash(options), error);
|
||||||
|
|
||||||
|
@ -947,14 +948,13 @@ class Server {
|
||||||
debug('Responding with 304');
|
debug('Responding with 304');
|
||||||
res.writeHead(304);
|
res.writeHead(304);
|
||||||
res.end();
|
res.end();
|
||||||
|
} else {
|
||||||
return;
|
res.setHeader(FILES_CHANGED_COUNT_HEADER, String(numModifiedFiles));
|
||||||
}
|
|
||||||
|
|
||||||
res.setHeader('Content-Type', 'application/javascript');
|
res.setHeader('Content-Type', 'application/javascript');
|
||||||
res.setHeader('ETag', etag);
|
res.setHeader('ETag', etag);
|
||||||
res.setHeader('Content-Length', String(Buffer.byteLength(bundle)));
|
res.setHeader('Content-Length', String(Buffer.byteLength(bundle)));
|
||||||
res.end(bundle);
|
res.end(bundle);
|
||||||
|
}
|
||||||
|
|
||||||
this._reporter.update({
|
this._reporter.update({
|
||||||
buildID,
|
buildID,
|
||||||
|
@ -962,7 +962,10 @@ class Server {
|
||||||
});
|
});
|
||||||
|
|
||||||
debug('Finished response');
|
debug('Finished response');
|
||||||
log(createActionEndEntry(requestingBundleLogEntry));
|
log({
|
||||||
|
...createActionEndEntry(requestingBundleLogEntry),
|
||||||
|
outdated_modules: numModifiedFiles,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async _processSourceMapUsingDeltaBundler(
|
async _processSourceMapUsingDeltaBundler(
|
||||||
|
|
Loading…
Reference in New Issue