@hippy/debug-server-next
Version:
Debug server for hippy.
190 lines (189 loc) • 7.76 kB
JavaScript
"use strict";
/*
* Tencent is pleased to support the open source community by making
* Hippy available.
*
* Copyright (C) 2017-2019 THL A29 Limited, a Tencent company.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppClient = void 0;
const events_1 = require("events");
const types_1 = require("@hippy/devtools-protocol/dist/types");
const enum_1 = require("@debug-server-next/@types/enum");
const middlewares_1 = require("@debug-server-next/middlewares");
const cdp_1 = require("@debug-server-next/utils/cdp");
const log_1 = require("@debug-server-next/utils/log");
const middleware_1 = require("@debug-server-next/utils/middleware");
const report_1 = require("@debug-server-next/utils/report");
const config_1 = require("@debug-server-next/config");
// ignore log the following method, because of high frequency
const ignoreMethods = [types_1.ChromeCommand.PageScreencastFrame, types_1.ChromeCommand.PageScreencastFrameAck];
const downwardLog = new log_1.Logger('↓↓↓', enum_1.WinstonColor.BrightRed);
const upwardLog = new log_1.Logger('↑↑↑', enum_1.WinstonColor.BrightGreen);
/**
* app client message tunnel
**/
class AppClient extends events_1.EventEmitter {
get middleWareManager() {
return {
[enum_1.DevicePlatform.Android]: middlewares_1.androidMiddleWareManager,
[enum_1.DevicePlatform.IOS]: middlewares_1.iOSMiddleWareManager,
}[this.platform];
}
constructor(id, { useAllDomain = true, acceptDomains, ignoreDomains = [], urlParsedContext, platform }) {
super();
this.cacheContext = {};
this.acceptDomains = cdp_1.CDP_DOMAIN_LIST;
this.ignoreDomains = [];
this.useAllDomain = true;
this.msgIdMap = new Map();
this.id = id;
this.useAllDomain = useAllDomain;
this.acceptDomains = acceptDomains || [];
this.ignoreDomains = ignoreDomains || [];
this.urlParsedContext = urlParsedContext;
this.platform = platform;
}
/**
* send debug protocol to app side
*/
sendToApp(msg) {
if (!this.filter(msg))
return Promise.reject(1 /* ErrorCode.DomainFiltered */);
const { id, method } = msg;
this.msgIdMap.set(id, {
method,
performance: (0, report_1.createCDPPerformance)({
...(msg.performance || {}),
debugServerReceiveFromDevtools: Date.now(),
}),
});
const middlewareList = this.getMiddlewareList(enum_1.MiddlewareType.Upward, method);
return this.middlewareMessageHandler(middlewareList, msg);
}
destroy() { }
/**
* receive debug protocol from app side
*/
downwardMessageHandler(msg) {
try {
if ('id' in msg) {
const cache = this.msgIdMap.get(msg.id);
if (cache === null || cache === void 0 ? void 0 : cache.method)
msg.method = cache.method;
}
const { method } = msg;
const middlewareList = this.getMiddlewareList(enum_1.MiddlewareType.Downward, method);
return this.middlewareMessageHandler(middlewareList, msg);
}
catch (e) {
downwardLog.error(`app client on message error: %s`, e === null || e === void 0 ? void 0 : e.stack);
return Promise.reject(e);
}
}
/**
* use middleware process debug protocol
*/
middlewareMessageHandler(middlewareList, msgBeforeAdapter) {
const middlewareContext = {
...this.urlParsedContext,
...this.cacheContext,
msg: msgBeforeAdapter,
sendToApp: (msg) => {
if (!msg.id) {
msg.id = middlewares_1.requestId.create();
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { performance, ...msgWithoutPerf } = msg;
if (!ignoreMethods.includes(msg.method))
upwardLog.verbose('%s sendToApp %j', this.constructor.name, msgWithoutPerf);
return this.sendHandler(msgWithoutPerf);
},
sendToDevtools: (msg) => {
if (!ignoreMethods.includes(msg.method))
downwardLog.verbose('%s sendToDevtools %s %s %s', this.constructor.name, msg.id || '', msg.method, 'error' in msg ? 'not support' : '');
let performance;
if ('id' in msg) {
const cache = this.msgIdMap.get(msg.id);
performance = cache === null || cache === void 0 ? void 0 : cache.performance;
if (performance)
performance.debugServerToDevtools = Date.now();
}
if (config_1.config.showPerformance)
msg.performance = performance;
return this.emitMessageToDevtools(msg);
},
setContext: (key, value) => {
this.cacheContext[key] = value;
},
};
return (0, middleware_1.composeMiddlewares)(middlewareList)(middlewareContext);
}
/**
* emit debug protocol to devtools frontend
*/
emitMessageToDevtools(msg) {
if (!msg)
return Promise.reject(3 /* ErrorCode.EmptyCommand */);
this.emit("message" /* AppClientEvent.Message */, msg);
if ('id' in msg) {
this.msgIdMap.delete(msg.id);
}
return Promise.resolve(msg);
}
/**
* filter upward msg by protocol domain
* whiteList - blackList = acceptDomain - ignoreDomain
*/
filter(msg) {
if (this.useAllDomain)
return true;
const { method } = msg;
const domain = (0, cdp_1.getDomain)(method);
let isIgnoreDomain;
let isAcceptDomain;
if (this.ignoreDomains.length) {
isIgnoreDomain = this.ignoreDomains.indexOf(domain) !== -1 || this.ignoreDomains.indexOf(method) !== -1;
}
if (this.acceptDomains.length) {
isAcceptDomain = this.acceptDomains.indexOf(domain) !== -1 || this.acceptDomains.indexOf(method) !== -1;
}
else {
isAcceptDomain = true;
}
if (isAcceptDomain)
return !isIgnoreDomain;
return false;
}
/**
* get registered protocol middlewares by protocol method
*/
getMiddlewareList(type, method) {
let middlewareList = {
[enum_1.MiddlewareType.Upward]: this.middleWareManager.upwardMiddleWareListMap,
[enum_1.MiddlewareType.Downward]: this.middleWareManager.downwardMiddleWareListMap,
}[type][method];
if (!middlewareList)
middlewareList = [];
if (!Array.isArray(middlewareList))
middlewareList = [middlewareList];
if (type === enum_1.MiddlewareType.Upward) {
return [...middlewareList, middlewares_1.defaultUpwardMiddleware];
}
return [middlewares_1.errorDownwardMiddleware, ...middlewareList, middlewares_1.defaultDownwardMiddleware];
}
}
exports.AppClient = AppClient;