nxkit
Version:
This is a collection of tools, independent of any other libraries
253 lines (252 loc) • 9.17 kB
JavaScript
"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;