From 1b2af7505f836f1524a0561029c1bbcc23ef7d00 Mon Sep 17 00:00:00 2001 From: Jimmy Au Date: Fri, 28 Dec 2018 22:33:17 +0800 Subject: [PATCH] Enable ADVANCED_OPTIMIZATIONS in Closure Compiler --- javascript/net/grpc/web/abstractclientbase.js | 6 +-- javascript/net/grpc/web/error.js | 15 +++---- javascript/net/grpc/web/grpcwebclientbase.js | 2 + .../grpc/web/grpcwebclientreadablestream.js | 6 ++- javascript/net/grpc/web/status.js | 21 ++++++---- javascript/net/grpc/web/statuscode.js | 34 ++++++++-------- .../web/streambodyclientreadablestream.js | 2 + packages/grpc-web/exports.js | 17 ++++++++ packages/grpc-web/externs.js | 1 + packages/grpc-web/scripts/build.js | 20 +++------- packages/grpc-web/test/export_test.js | 39 +++++++++++++++++++ 11 files changed, 112 insertions(+), 51 deletions(-) create mode 100644 packages/grpc-web/exports.js create mode 100644 packages/grpc-web/externs.js create mode 100644 packages/grpc-web/test/export_test.js diff --git a/javascript/net/grpc/web/abstractclientbase.js b/javascript/net/grpc/web/abstractclientbase.js index d39befcba..1d4ec50c5 100644 --- a/javascript/net/grpc/web/abstractclientbase.js +++ b/javascript/net/grpc/web/abstractclientbase.js @@ -51,11 +51,11 @@ AbstractClientBase.MethodInfo = function( responseType, requestSerializeFn, responseDeserializeFn) { - /** @const */ + /** @const @export */ this.responseType = responseType; - /** @const */ + /** @const @export */ this.requestSerializeFn = requestSerializeFn; - /** @const */ + /** @const @export */ this.responseDeserializeFn = responseDeserializeFn; }; diff --git a/javascript/net/grpc/web/error.js b/javascript/net/grpc/web/error.js index 79f8ec26f..c10c28db9 100644 --- a/javascript/net/grpc/web/error.js +++ b/javascript/net/grpc/web/error.js @@ -28,12 +28,13 @@ goog.module.declareLegacyNamespace(); -/** - * @typedef {{ - * code: (number|undefined), - * message: (string|undefined), - * }} - */ -let Error; +/** @record */ +function Error() {} + +/** @export {(number|undefined)} */ +Error.prototype.code; + +/** @export {(string|undefined)} */ +Error.prototype.message; exports = Error; diff --git a/javascript/net/grpc/web/grpcwebclientbase.js b/javascript/net/grpc/web/grpcwebclientbase.js index d5ae0ef42..9836e66be 100644 --- a/javascript/net/grpc/web/grpcwebclientbase.js +++ b/javascript/net/grpc/web/grpcwebclientbase.js @@ -61,6 +61,7 @@ const GrpcWebClientBase = function(opt_options) { /** * @override + * @export */ GrpcWebClientBase.prototype.rpcCall = function( method, request, metadata, methodInfo, callback) { @@ -116,6 +117,7 @@ GrpcWebClientBase.prototype.rpcCall = function( /** * @override + * @export */ GrpcWebClientBase.prototype.serverStreaming = function( method, request, metadata, methodInfo) { diff --git a/javascript/net/grpc/web/grpcwebclientreadablestream.js b/javascript/net/grpc/web/grpcwebclientreadablestream.js index a4149a7f6..095b8b96d 100644 --- a/javascript/net/grpc/web/grpcwebclientreadablestream.js +++ b/javascript/net/grpc/web/grpcwebclientreadablestream.js @@ -164,11 +164,11 @@ const GrpcWebClientReadableStream = function(genericTransportInterface) { grpcStatusMessage = trailers[GRPC_STATUS_MESSAGE]; } if (self.onStatusCallback_) { - self.onStatusCallback_({ + self.onStatusCallback_(/** @type {!Status} */({ code: Number(grpcStatusCode), details: grpcStatusMessage, metadata: trailers, - }); + })); } } } @@ -207,6 +207,7 @@ const GrpcWebClientReadableStream = function(genericTransportInterface) { /** * @override + * @export */ GrpcWebClientReadableStream.prototype.on = function( eventType, callback) { @@ -238,6 +239,7 @@ GrpcWebClientReadableStream.prototype.setResponseDeserializeFn = /** * @override + * @export */ GrpcWebClientReadableStream.prototype.cancel = function() { this.xhr_.abort(); diff --git a/javascript/net/grpc/web/status.js b/javascript/net/grpc/web/status.js index f8ac7bd2b..26cfcbed3 100644 --- a/javascript/net/grpc/web/status.js +++ b/javascript/net/grpc/web/status.js @@ -28,11 +28,16 @@ goog.module.declareLegacyNamespace(); -/** - * @typedef {{ - * code: number, - * details: string, - * metadata: (!Object|undefined) - * }} - */ -exports.Status; +/** @record */ +function Status() {} + +/** @export {number} */ +Status.prototype.code; + +/** @export {string} */ +Status.prototype.details; + +/** @export {(!Object|undefined)} */ +Status.prototype.metadata; + +exports.Status = Status; diff --git a/javascript/net/grpc/web/statuscode.js b/javascript/net/grpc/web/statuscode.js index 8cac2ff5c..0c253deb5 100644 --- a/javascript/net/grpc/web/statuscode.js +++ b/javascript/net/grpc/web/statuscode.js @@ -35,51 +35,51 @@ goog.module.declareLegacyNamespace(); */ const StatusCode = { // Not an error; returned on success. - OK: 0, + 'OK': 0, // The operation was cancelled (typically by the caller). - CANCELLED: 1, + 'CANCELLED': 1, // Unknown error. An example of where this error may be returned is if a // Status value received from another address space belongs to an error-space // that is not known in this address space. Also errors raised by APIs that // do not return enough error information may be converted to this error. - UNKNOWN: 2, + 'UNKNOWN': 2, // Client specified an invalid argument. Note that this differs from // FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are // problematic regardless of the state of the system (e.g., a malformed file // name). - INVALID_ARGUMENT: 3, + 'INVALID_ARGUMENT': 3, // Deadline expired before operation could complete. For operations that // change the state of the system, this error may be returned even if the // operation has completed successfully. For example, a successful response // from a server could have been delayed long enough for the deadline to // expire. - DEADLINE_EXCEEDED: 4, + 'DEADLINE_EXCEEDED': 4, // Some requested entity (e.g., file or directory) was not found. - NOT_FOUND: 5, + 'NOT_FOUND': 5, // Some entity that we attempted to create (e.g., file or directory) already // exists. - ALREADY_EXISTS: 6, + 'ALREADY_EXISTS': 6, // The caller does not have permission to execute the specified operation. // PERMISSION_DENIED must not be used for rejections caused by exhausting // some resource (use RESOURCE_EXHAUSTED instead for those errors). // PERMISSION_DENIED must not be used if the caller can not be identified // (use UNAUTHENTICATED instead for those errors). - PERMISSION_DENIED: 7, + 'PERMISSION_DENIED': 7, // The request does not have valid authentication credentials for the // operation. - UNAUTHENTICATED: 16, + 'UNAUTHENTICATED': 16, // Some resource has been exhausted, perhaps a per-user quota, or perhaps the // entire file system is out of space. - RESOURCE_EXHAUSTED: 8, + 'RESOURCE_EXHAUSTED': 8, // Operation was rejected because the system is not in a state required for // the operation's execution. For example, directory to be deleted may be @@ -99,14 +99,14 @@ const StatusCode = { // REST Get/Update/Delete on a resource and the resource on the // server does not match the condition. E.g., conflicting // read-modify-write on the same resource. - FAILED_PRECONDITION: 9, + 'FAILED_PRECONDITION': 9, // The operation was aborted, typically due to a concurrency issue like // sequencer check failures, transaction aborts, etc. // // See litmus test above for deciding between FAILED_PRECONDITION, ABORTED, // and UNAVAILABLE. - ABORTED: 10, + 'ABORTED': 10, // Operation was attempted past the valid range. E.g., seeking or reading // past end of file. @@ -121,24 +121,24 @@ const StatusCode = { // OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error) // when it applies so that callers who are iterating through a space can // easily look for an OUT_OF_RANGE error to detect when they are done. - OUT_OF_RANGE: 11, + 'OUT_OF_RANGE': 11, // Operation is not implemented or not supported/enabled in this service. - UNIMPLEMENTED: 12, + 'UNIMPLEMENTED': 12, // Internal errors. Means some invariants expected by underlying System has // been broken. If you see one of these errors, Something is very broken. - INTERNAL: 13, + 'INTERNAL': 13, // The service is currently unavailable. This is a most likely a transient // condition and may be corrected by retrying with a backoff. // // See litmus test above for deciding between FAILED_PRECONDITION, ABORTED, // and UNAVAILABLE. - UNAVAILABLE: 14, + 'UNAVAILABLE': 14, // Unrecoverable data loss or corruption. - DATA_LOSS: 15, + 'DATA_LOSS': 15, }; diff --git a/javascript/net/grpc/web/streambodyclientreadablestream.js b/javascript/net/grpc/web/streambodyclientreadablestream.js index b4bb25c0c..efe5a0e83 100644 --- a/javascript/net/grpc/web/streambodyclientreadablestream.js +++ b/javascript/net/grpc/web/streambodyclientreadablestream.js @@ -139,6 +139,7 @@ const StreamBodyClientReadableStream = function(genericTransportInterface) { /** * @override + * @export */ StreamBodyClientReadableStream.prototype.on = function( eventType, callback) { @@ -182,6 +183,7 @@ StreamBodyClientReadableStream.prototype.setRpcStatusParseFn = function(rpcStatu /** * @override + * @export */ StreamBodyClientReadableStream.prototype.cancel = function() { this.xhr_.abort(); diff --git a/packages/grpc-web/exports.js b/packages/grpc-web/exports.js new file mode 100644 index 000000000..a51dcff5c --- /dev/null +++ b/packages/grpc-web/exports.js @@ -0,0 +1,17 @@ +/** + * @fileoverview Export symbols needed by generated code in CommonJS style. + * + * Note that public methods called by generated code are exposed + * using Closure Compiler's @export annotation + */ +goog.module('grpc.web.Exports'); + +const AbstractClientBase = goog.require('grpc.web.AbstractClientBase'); +const GrpcWebClientBase = goog.require('grpc.web.GrpcWebClientBase'); +const StatusCode = goog.require('grpc.web.StatusCode'); + +const exports = module['exports']; + +exports['AbstractClientBase'] = {'MethodInfo': AbstractClientBase.MethodInfo}; +exports['GrpcWebClientBase'] = GrpcWebClientBase; +exports['StatusCode'] = StatusCode; diff --git a/packages/grpc-web/externs.js b/packages/grpc-web/externs.js new file mode 100644 index 000000000..35283723c --- /dev/null +++ b/packages/grpc-web/externs.js @@ -0,0 +1 @@ +var module; diff --git a/packages/grpc-web/scripts/build.js b/packages/grpc-web/scripts/build.js index fdfec4263..07a6cb143 100644 --- a/packages/grpc-web/scripts/build.js +++ b/packages/grpc-web/scripts/build.js @@ -24,29 +24,21 @@ const cwd = process.cwd(); const indexPath = path.relative(cwd, path.resolve(__dirname, "../index.js")); const jsPaths = [ + "../exports.js", "../../../javascript", "../../../third_party/closure-library", - "../../../third_party/grpc/third_party/protobuf/js", ].map(jsPath => path.relative(cwd, path.resolve(__dirname, jsPath))); -const grpcWebExports = [ - "grpc.web.AbstractClientBase", - "grpc.web.ClientReadableStream", - "grpc.web.Error", - "grpc.web.GrpcWebClientBase", - "grpc.web.GrpcWebClientReadableStream", - "grpc.web.GrpcWebStreamParser", - "grpc.web.Status", - "grpc.web.StatusCode", -]; - const closureArgs = [].concat( jsPaths.map(jsPath => `--js=${jsPath}`), - grpcWebExports.map(grpcWebExport => `--entry_point=${grpcWebExport}`), [ + `--entry_point=grpc.web.Exports`, + `--externs=externs.js`, `--dependency_mode=STRICT`, + `--compilation_level=ADVANCED_OPTIMIZATIONS`, + `--generate_exports`, + `--export_local_property_definitions`, `--js_output_file=${indexPath}`, - `--output_wrapper="%output%module.exports=grpc.web;"`, ] ); diff --git a/packages/grpc-web/test/export_test.js b/packages/grpc-web/test/export_test.js new file mode 100644 index 000000000..70b2b1d39 --- /dev/null +++ b/packages/grpc-web/test/export_test.js @@ -0,0 +1,39 @@ +const assert = require('assert'); +const grpc = {}; +grpc.web = require('grpc-web'); + +describe('grpc-web export test', function() { + it('should have AbstractClientBase.MethodInfo exported', function() { + assert.equal(typeof grpc.web.AbstractClientBase.MethodInfo, 'function'); + }); + + it('should have GrpcWebClientBase#rpcCall() exported', function() { + assert.equal(typeof grpc.web.GrpcWebClientBase.prototype.rpcCall, 'function'); + }); + + it('should have GrpcWebClientBase#serverStreaming() exported', function() { + assert.equal(typeof grpc.web.GrpcWebClientBase.prototype.serverStreaming, 'function'); + }); + + it('should have grpc StatusCode exported', function() { + assert.deepEqual(grpc.web.StatusCode, { + ABORTED: 10, + ALREADY_EXISTS: 6, + CANCELLED: 1, + DATA_LOSS: 15, + DEADLINE_EXCEEDED: 4, + FAILED_PRECONDITION: 9, + INTERNAL: 13, + INVALID_ARGUMENT: 3, + NOT_FOUND: 5, + OK: 0, + OUT_OF_RANGE: 11, + PERMISSION_DENIED: 7, + RESOURCE_EXHAUSTED: 8, + UNAUTHENTICATED: 16, + UNAVAILABLE: 14, + UNIMPLEMENTED: 12, + UNKNOWN: 2 + }); + }); +});