UNPKG

@hippy/debug-server-next

Version:
184 lines (183 loc) 7.94 kB
"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.onVanillaJSClientConnection = void 0; const tslib_1 = require("tslib"); const safe_1 = tslib_1.__importDefault(require("colors/safe")); const enum_1 = require("@debug-server-next/@types/enum"); const log_1 = require("@debug-server-next/utils/log"); const pub_sub_channel_1 = require("@debug-server-next/utils/pub-sub-channel"); const db_1 = require("@debug-server-next/db"); const report_1 = require("@debug-server-next/utils/report"); const debug_targets_1 = require("@debug-server-next/controller/debug-targets"); const global_id_1 = require("@debug-server-next/utils/global-id"); const timer_1 = require("@debug-server-next/utils/timer"); const history_event_protocol_1 = require("@debug-server-next/utils/history-event-protocol"); const constants_1 = require("@debug-server-next/@types/constants"); const label = safe_1.default.yellow('vanilla-js-devtools'); const downwardLog = new log_1.Logger(`↓↓↓ ${label}`, enum_1.WinstonColor.BrightRed); const upwardLog = new log_1.Logger(`↑↑↑ ${label}`, enum_1.WinstonColor.BrightGreen); const log = new log_1.Logger(label); const ENABLE_LOG_PROTOCOL = 'Runtime.enable'; const ENABLE_PROTOCOLS = ['Network.enable', 'DOMStorage.enable']; // const LOG_EVENT = 'Runtime.consoleAPICalled'; /** * Pub/Sub vanilla js devtools msg */ const onVanillaJSClientConnection = async (ws, wsUrlParams) => { const protocolId = new global_id_1.GlobalId(-20000, -1); const { contextName, clientRole, clientId, platform } = wsUrlParams; log.info('%s connected', clientRole); const { Subscriber, Publisher } = (0, db_1.getDBOperator)(); const internalChannelId = (0, pub_sub_channel_1.createInternalChannel)(clientId, ''); const internalSubscriber = new Subscriber(internalChannelId); internalSubscriber.subscribe((msg) => { if (msg === enum_1.InternalChannelEvent.DevtoolsConnected) { // pub enable after devtools connected triggerEnableLogForIOS(ws, protocolId, clientId); broadcastHistoryLog(clientId, downPublisher, platform); } }); // pub enable immediately, support for reload scene triggerEnableLogForIOS(ws, protocolId, clientId); triggerEnableNetworkAndStorage(ws, protocolId); const upwardChannelId = (0, pub_sub_channel_1.createUpwardChannel)(clientId, '*'); const downwardChannelId = (0, pub_sub_channel_1.createDownwardChannel)(clientId); const downPublisher = new Publisher(downwardChannelId); const upSubscriber = new Subscriber(upwardChannelId); upSubscriber.pSubscribe((msg) => { try { const msgStr = msg.toString(); const msgObj = JSON.parse(msgStr); if (constants_1.LOG_PROTOCOLS.includes(msgObj.method)) { if (!ws.enableLogForIOS) return; upwardLog.verbose('sendToApp %j', msgObj); report_1.report.event({ name: enum_1.ReportEvent.VanillaIOSJSRuntime, ext1: contextName, ext2: msgObj.method, }); return ws.send(msgStr); } if (constants_1.VANILLA_JS_METHODS.includes(msgObj.method)) { upwardLog.verbose('sendToApp %j', msgObj); ws.send(msgStr); report_1.report.event({ name: enum_1.ReportEvent.VanillaJSRuntime, ext1: contextName, ext2: msgObj.method, }); } } catch (e) { } }); let debugTarget; ws.on('message', async (msg) => { const msgStr = msg.toString(); if (!msgStr) return; try { const cmd = JSON.parse(msgStr); // network event dispatch from history cache // if (!cmd.method?.startsWith('Network.')) { downPublisher.publish(msgStr); downwardLog.verbose('sendToDevtools %s %s %s', cmd.id || '', cmd.method, 'error' in cmd ? 'not support' : ''); // } if (!debugTarget) { await (0, timer_1.sleep)(800); debugTarget = await debug_targets_1.DebugTargetManager.findDebugTarget(clientId, undefined, true); } if (cmd.method && debugTarget && (0, history_event_protocol_1.isHistoryProtocol)(cmd.method, debugTarget.platform)) { (0, history_event_protocol_1.saveHistoryProtocol)(clientId, msgStr); } } catch (e) { log.error('parse json error: %s', (e === null || e === void 0 ? void 0 : e.stack) || e); } }); ws.on('close', async (code, reason) => { log.info('%s closed. code: %s, reason: %s', clientRole, code, reason); (0, history_event_protocol_1.clearHistoryProtocol)(clientId); await upSubscriber.disconnect(); await downPublisher.disconnect(); await internalSubscriber.disconnect(); }); ws.on('error', (e) => log.error('vanilla js ws error: %s', e.stack || e)); }; exports.onVanillaJSClientConnection = onVanillaJSClientConnection; async function enableLogForIOS(clientId) { /** * app ws maybe late connect than vanilla js, so maybe could not find debugTarget */ await (0, timer_1.sleep)(800); const debugTarget = await debug_targets_1.DebugTargetManager.findDebugTarget(clientId, undefined, true); if (!debugTarget) return true; return debugTarget.platform === enum_1.DevicePlatform.IOS && !debugTarget.appClientTypeList.includes("IWDPAppClient" /* AppClientType.IWDP */); } /** * if iOS device not use IWDP, enable log protocol by vanilla js */ async function triggerEnableLogForIOS(ws, protocolId, clientId) { const enabled = await enableLogForIOS(clientId); ws.enableLogForIOS = enabled; if (enabled) { const event = { id: protocolId.create(), method: ENABLE_LOG_PROTOCOL, params: {}, }; ws.send(JSON.stringify(event)); upwardLog.verbose('sendToApp %j', event); } } async function triggerEnableNetworkAndStorage(ws, protocolId) { // enable sample data when connected ENABLE_PROTOCOLS.forEach((protocol) => { const event = { id: protocolId.create(), method: protocol, params: {}, }; ws.send(JSON.stringify(event)); upwardLog.verbose('sendToApp %j', event); }); } const broadcastHistoryLog = async (clientId, downPublisher, platform) => { const list = await (0, history_event_protocol_1.getHistoryProtocol)(clientId); if (!list.length) return; /** * delay to send history log after ConsoleModel of devtools is ready */ setTimeout(async () => { /** * mock a clear protocol to clear existed history logs in console panel */ if (platform === enum_1.DevicePlatform.IOS) await downPublisher.publish({ method: 'Log.cleared', params: {}, }); await list.map(downPublisher.publish.bind(downPublisher)); }, 1500); };