No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

service.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. "use strict";
  2. module.exports = Service;
  3. // extends Namespace
  4. var Namespace = require("./namespace");
  5. ((Service.prototype = Object.create(Namespace.prototype)).constructor = Service).className = "Service";
  6. var Method = require("./method"),
  7. util = require("./util"),
  8. rpc = require("./rpc");
  9. /**
  10. * Constructs a new service instance.
  11. * @classdesc Reflected service.
  12. * @extends NamespaceBase
  13. * @constructor
  14. * @param {string} name Service name
  15. * @param {Object.<string,*>} [options] Service options
  16. * @throws {TypeError} If arguments are invalid
  17. */
  18. function Service(name, options) {
  19. Namespace.call(this, name, options);
  20. /**
  21. * Service methods.
  22. * @type {Object.<string,Method>}
  23. */
  24. this.methods = {}; // toJSON, marker
  25. /**
  26. * Cached methods as an array.
  27. * @type {Method[]|null}
  28. * @private
  29. */
  30. this._methodsArray = null;
  31. }
  32. /**
  33. * Service descriptor.
  34. * @interface IService
  35. * @extends INamespace
  36. * @property {Object.<string,IMethod>} methods Method descriptors
  37. */
  38. /**
  39. * Constructs a service from a service descriptor.
  40. * @param {string} name Service name
  41. * @param {IService} json Service descriptor
  42. * @returns {Service} Created service
  43. * @throws {TypeError} If arguments are invalid
  44. */
  45. Service.fromJSON = function fromJSON(name, json) {
  46. var service = new Service(name, json.options);
  47. /* istanbul ignore else */
  48. if (json.methods)
  49. for (var names = Object.keys(json.methods), i = 0; i < names.length; ++i)
  50. service.add(Method.fromJSON(names[i], json.methods[names[i]]));
  51. if (json.nested)
  52. service.addJSON(json.nested);
  53. service.comment = json.comment;
  54. return service;
  55. };
  56. /**
  57. * Converts this service to a service descriptor.
  58. * @param {IToJSONOptions} [toJSONOptions] JSON conversion options
  59. * @returns {IService} Service descriptor
  60. */
  61. Service.prototype.toJSON = function toJSON(toJSONOptions) {
  62. var inherited = Namespace.prototype.toJSON.call(this, toJSONOptions);
  63. var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
  64. return util.toObject([
  65. "options" , inherited && inherited.options || undefined,
  66. "methods" , Namespace.arrayToJSON(this.methodsArray, toJSONOptions) || /* istanbul ignore next */ {},
  67. "nested" , inherited && inherited.nested || undefined,
  68. "comment" , keepComments ? this.comment : undefined
  69. ]);
  70. };
  71. /**
  72. * Methods of this service as an array for iteration.
  73. * @name Service#methodsArray
  74. * @type {Method[]}
  75. * @readonly
  76. */
  77. Object.defineProperty(Service.prototype, "methodsArray", {
  78. get: function() {
  79. return this._methodsArray || (this._methodsArray = util.toArray(this.methods));
  80. }
  81. });
  82. function clearCache(service) {
  83. service._methodsArray = null;
  84. return service;
  85. }
  86. /**
  87. * @override
  88. */
  89. Service.prototype.get = function get(name) {
  90. return this.methods[name]
  91. || Namespace.prototype.get.call(this, name);
  92. };
  93. /**
  94. * @override
  95. */
  96. Service.prototype.resolveAll = function resolveAll() {
  97. var methods = this.methodsArray;
  98. for (var i = 0; i < methods.length; ++i)
  99. methods[i].resolve();
  100. return Namespace.prototype.resolve.call(this);
  101. };
  102. /**
  103. * @override
  104. */
  105. Service.prototype.add = function add(object) {
  106. /* istanbul ignore if */
  107. if (this.get(object.name))
  108. throw Error("duplicate name '" + object.name + "' in " + this);
  109. if (object instanceof Method) {
  110. this.methods[object.name] = object;
  111. object.parent = this;
  112. return clearCache(this);
  113. }
  114. return Namespace.prototype.add.call(this, object);
  115. };
  116. /**
  117. * @override
  118. */
  119. Service.prototype.remove = function remove(object) {
  120. if (object instanceof Method) {
  121. /* istanbul ignore if */
  122. if (this.methods[object.name] !== object)
  123. throw Error(object + " is not a member of " + this);
  124. delete this.methods[object.name];
  125. object.parent = null;
  126. return clearCache(this);
  127. }
  128. return Namespace.prototype.remove.call(this, object);
  129. };
  130. /**
  131. * Creates a runtime service using the specified rpc implementation.
  132. * @param {RPCImpl} rpcImpl RPC implementation
  133. * @param {boolean} [requestDelimited=false] Whether requests are length-delimited
  134. * @param {boolean} [responseDelimited=false] Whether responses are length-delimited
  135. * @returns {rpc.Service} RPC service. Useful where requests and/or responses are streamed.
  136. */
  137. Service.prototype.create = function create(rpcImpl, requestDelimited, responseDelimited) {
  138. var rpcService = new rpc.Service(rpcImpl, requestDelimited, responseDelimited);
  139. for (var i = 0, method; i < /* initializes */ this.methodsArray.length; ++i) {
  140. var methodName = util.lcFirst((method = this._methodsArray[i]).resolve().name).replace(/[^$\w_]/g, "");
  141. rpcService[methodName] = util.codegen(["r","c"], util.isReserved(methodName) ? methodName + "_" : methodName)("return this.rpcCall(m,q,s,r,c)")({
  142. m: method,
  143. q: method.resolvedRequestType.ctor,
  144. s: method.resolvedResponseType.ctor
  145. });
  146. }
  147. return rpcService;
  148. };