UNPKG

nxkit

Version:

This is a collection of tools, independent of any other libraries

253 lines (252 loc) 9.17 kB
"use strict"; /* ***** BEGIN LICENSE BLOCK ***** * Distributed under the BSD license: * * Copyright (c) 2015, xuewen.chu * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, self list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, self list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of xuewen.chu nor the * names of its contributors may be used to endorse or promote products * derived from self software without specific prior written permission. * * self SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL xuewen.chu BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF self * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ Object.defineProperty(exports, "__esModule", { value: true }); const util_1 = require("./util"); const path_1 = require("./path"); const event_1 = require("./event"); const request_1 = require("./request"); const cli_1 = require("./ws/cli"); const log = require("./log"); var serviceAPI = new path_1.default.URL(util_1.default.config.serviceAPI || 'http://127.0.0.1:8091/service-api'); if (util_1.default.haveWeb) { var default_host = path_1.default.getParam('D_SDK_HOST') || serviceAPI.hostname; var default_port = path_1.default.getParam('D_SDK_PORT') || serviceAPI.port; var default_ssl = !!Number(path_1.default.getParam('D_SDK_SSL')) || /^(http|ws)s/.test(serviceAPI.protocol); var default_directory = path_1.default.getParam('D_SDK_VIRTUAL') || serviceAPI.filename; } else { var default_host = serviceAPI.hostname; var default_port = serviceAPI.port; var default_ssl = /^(http|ws)s/.test(serviceAPI.protocol); var default_directory = serviceAPI.filename; } class WrapClient extends event_1.Notification { constructor(host, name, cli, desc) { super(); this.m_name = ''; this.m_methods = {}; this.m_host = host; this.m_name = name; this.m_cli = cli; this.m_desc = desc; if (this.m_desc) { this.m_desc.methods.forEach(e => { this.m_methods[e] = (...args) => { return this.call(e, ...args); }; }); } } get methods() { return this.m_methods; } getNoticer(name) { if (this.m_cli instanceof cli_1.WSClient) { if (this.hasNoticer(name)) { return super.getNoticer(name); } else { var notice = super.getNoticer(name); this.m_cli.addEventForward(name, notice); // forward event return notice; } } else { return super.getNoticer(name); } } async _call(name, full_name, ...args) { var fail; var is_report_call = name.indexOf('report') != -1; try { // TODO Printing log will lead to `electron` client crash // if (!is_report_call) // log.log('call', full_name, __j++, '...'); return await this.m_cli.call(name, ...args); } catch (err) { fail = err; this.m_host.trigger('Error', err); throw err; } finally { // if (!is_report_call) // log.log('call', full_name, --__j, fail ? 'fail' : 'ok'); } } call(name, data, opts) { var _a, _b; var timeout = ((_a = opts) === null || _a === void 0 ? void 0 : _a.timeout) || cli_1.METHOD_CALL_TIMEOUT; return this._call(name, this.m_name + '/' + name, data, timeout, (_b = opts) === null || _b === void 0 ? void 0 : _b.sender); } trigger(name, data) { // log.log(`${this.m_name}/${name}`, data); return super.trigger(name, data); } } exports.WrapClient = WrapClient; class WrapRequest extends WrapClient { async call(name, ...args) { name = this.m_name + '/' + name; return (await this._call(name, name, ...args)).data; } } class Request2 extends request_1.Request { constructor(host, url) { super(url); this.m_host = host; } parseResponseData(buf) { var res = request_1.parseJSON(buf.toString('utf8')); if (res.errno === 0) { return res.data; } else { throw Error.new(res); } } getRequestHeaders() { return this.m_host.requestHeaders; } } class WSConversation2 extends cli_1.WSConversation { constructor(host, url) { super(url); this.m_host = host; } getRequestHeaders() { return this.m_host.requestHeaders; } } /** * @class APIStore */ class APIStore extends event_1.Notification { constructor(name = 'dphoto-cli') { super(); this.m_desc = {}; this.m_timeoutid = 0; this.m_signer = null; this.m_request_headers = {}; this.m_port = ''; this.m_ssl = ''; this.m_host = ''; this.m_directory = ''; this.m_core = {}; this.m_isloaded = false; this.m_name = name; } get name() { return this.m_name; } get descriptors() { return this.m_desc; } get core() { return this.m_core; } _get_wssocket_conv() { var self = this; if (!self.m_conv) { var port = self.m_port != (self.m_ssl ? '443' : '80') ? ':' + self.m_port : ''; var pathname = path_1.default.resolve(`ws${self.m_ssl}://${self.m_host}${port}`, self.m_directory); var conv = self.m_conv = new WSConversation2(self, pathname); if (self.m_signer) conv.signer = self.m_signer; conv.onClose.on(e => console.error('Connection accidental disconnection')); conv.keepAliveTime = 5e3; // 5s; // disconnect auto connect conv.onClose.on(e => { util_1.default.sleep(50).then(e => conv.connect()); }); conv.onError.on(e => { util_1.default.sleep(50).then(e => conv.connect()); }); } return self.m_conv; } destroy() { if (this.m_conv) this.m_conv.close(); this.m_conv = null; this.m_core = {}; this.m_isloaded = false; this.m_desc = {}; clearInterval(this.m_timeoutid); } get isLoaded() { return this.m_isloaded; } get requestHeaders() { return this.m_request_headers; } setRequestHeaders(headers) { this.m_request_headers = headers; } setSigner(signer) { this.m_signer = signer; if (this.m_req) this.m_req.signer = signer; if (this.m_conv) this.m_conv.signer = signer; } async initialize(host = default_host, port = default_port, ssl = default_ssl, directory = default_directory) { this.m_host = host; this.m_port = port || (ssl ? '443' : '80'); this.m_ssl = ssl ? 's' : ''; this.m_directory = directory; port = this.m_port != (ssl ? '443' : '80') ? ':' + this.m_port : ''; var service_api = path_1.default.resolve(`http${this.m_ssl}://${host}${port}`, this.m_directory); this.m_req = new Request2(this, service_api); this.m_req.urlencoded = false; if (this.m_signer) this.m_req.signer = this.m_signer; var { data: desc } = await this.m_req.get('descriptors/descriptors', undefined, { timeout: 2e4 }); delete this.m_desc.descriptors; for (var name in desc) { var item = desc[name]; if (item.type == 'event') { var ws = this._get_wssocket_conv(); this.m_core[name] = new WrapClient(this, name, new cli_1.WSClient(name, ws), desc[name]); } else { this.m_core[name] = new WrapRequest(this, name, this.m_req, desc[name]); } } // log.log('nxkit/store', 'startup complete'); this.m_isloaded = true; } trigger(name, data) { log.log(`${this.m_name}/${name}`, data); return super.trigger(name, data); } } exports.default = APIStore;