BidiServer.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. "use strict";
  2. /**
  3. * Copyright 2021 Google LLC.
  4. * Copyright (c) Microsoft Corporation.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. Object.defineProperty(exports, "__esModule", { value: true });
  19. exports.BidiServer = void 0;
  20. const EventEmitter_js_1 = require("../utils/EventEmitter.js");
  21. const log_js_1 = require("../utils/log.js");
  22. const ProcessingQueue_js_1 = require("../utils/ProcessingQueue.js");
  23. const CommandProcessor_js_1 = require("./CommandProcessor.js");
  24. const CdpTargetManager_js_1 = require("./modules/cdp/CdpTargetManager.js");
  25. const BrowsingContextStorage_js_1 = require("./modules/context/BrowsingContextStorage.js");
  26. const NetworkStorage_js_1 = require("./modules/network/NetworkStorage.js");
  27. const PreloadScriptStorage_js_1 = require("./modules/script/PreloadScriptStorage.js");
  28. const RealmStorage_js_1 = require("./modules/script/RealmStorage.js");
  29. const EventManager_js_1 = require("./modules/session/EventManager.js");
  30. class BidiServer extends EventEmitter_js_1.EventEmitter {
  31. #messageQueue;
  32. #transport;
  33. #commandProcessor;
  34. #eventManager;
  35. #browsingContextStorage = new BrowsingContextStorage_js_1.BrowsingContextStorage();
  36. #realmStorage = new RealmStorage_js_1.RealmStorage();
  37. #preloadScriptStorage = new PreloadScriptStorage_js_1.PreloadScriptStorage();
  38. #logger;
  39. #handleIncomingMessage = (message) => {
  40. void this.#commandProcessor.processCommand(message).catch((error) => {
  41. this.#logger?.(log_js_1.LogType.debugError, error);
  42. });
  43. };
  44. #processOutgoingMessage = async (messageEntry) => {
  45. const message = messageEntry.message;
  46. if (messageEntry.channel !== null) {
  47. message['channel'] = messageEntry.channel;
  48. }
  49. await this.#transport.sendMessage(message);
  50. };
  51. constructor(bidiTransport, cdpConnection, browserCdpClient, selfTargetId, defaultUserContextId, options, parser, logger) {
  52. super();
  53. this.#logger = logger;
  54. this.#messageQueue = new ProcessingQueue_js_1.ProcessingQueue(this.#processOutgoingMessage, this.#logger);
  55. this.#transport = bidiTransport;
  56. this.#transport.setOnMessage(this.#handleIncomingMessage);
  57. this.#eventManager = new EventManager_js_1.EventManager(this.#browsingContextStorage);
  58. const networkStorage = new NetworkStorage_js_1.NetworkStorage(this.#eventManager, browserCdpClient, logger);
  59. new CdpTargetManager_js_1.CdpTargetManager(cdpConnection, browserCdpClient, selfTargetId, this.#eventManager, this.#browsingContextStorage, this.#realmStorage, networkStorage, this.#preloadScriptStorage, options?.acceptInsecureCerts ?? false, defaultUserContextId, logger);
  60. this.#commandProcessor = new CommandProcessor_js_1.CommandProcessor(cdpConnection, browserCdpClient, this.#eventManager, this.#browsingContextStorage, this.#realmStorage, this.#preloadScriptStorage, networkStorage, parser, this.#logger);
  61. this.#eventManager.on("event" /* EventManagerEvents.Event */, ({ message, event }) => {
  62. this.emitOutgoingMessage(message, event);
  63. });
  64. this.#commandProcessor.on("response" /* CommandProcessorEvents.Response */, ({ message, event }) => {
  65. this.emitOutgoingMessage(message, event);
  66. });
  67. }
  68. /**
  69. * Creates and starts BiDi Mapper instance.
  70. */
  71. static async createAndStart(bidiTransport, cdpConnection, browserCdpClient, selfTargetId, options, parser, logger) {
  72. // The default context is not exposed in Target.getBrowserContexts but can
  73. // be observed via Target.getTargets. To determine the default browser
  74. // context, we check which one is mentioned in Target.getTargets and not in
  75. // Target.getBrowserContexts.
  76. const [{ browserContextIds }, { targetInfos }] = await Promise.all([
  77. browserCdpClient.sendCommand('Target.getBrowserContexts'),
  78. browserCdpClient.sendCommand('Target.getTargets'),
  79. ]);
  80. let defaultUserContextId = 'default';
  81. for (const info of targetInfos) {
  82. if (info.browserContextId &&
  83. !browserContextIds.includes(info.browserContextId)) {
  84. defaultUserContextId = info.browserContextId;
  85. break;
  86. }
  87. }
  88. const server = new BidiServer(bidiTransport, cdpConnection, browserCdpClient, selfTargetId, defaultUserContextId, options, parser, logger);
  89. // Needed to get events about new targets.
  90. await browserCdpClient.sendCommand('Target.setDiscoverTargets', {
  91. discover: true,
  92. });
  93. // Needed to automatically attach to new targets.
  94. await browserCdpClient.sendCommand('Target.setAutoAttach', {
  95. autoAttach: true,
  96. waitForDebuggerOnStart: true,
  97. flatten: true,
  98. });
  99. await server.#topLevelContextsLoaded();
  100. return server;
  101. }
  102. /**
  103. * Sends BiDi message.
  104. */
  105. emitOutgoingMessage(messageEntry, event) {
  106. this.#messageQueue.add(messageEntry, event);
  107. }
  108. close() {
  109. this.#transport.close();
  110. }
  111. async #topLevelContextsLoaded() {
  112. await Promise.all(this.#browsingContextStorage
  113. .getTopLevelContexts()
  114. .map((c) => c.lifecycleLoaded()));
  115. }
  116. }
  117. exports.BidiServer = BidiServer;
  118. //# sourceMappingURL=BidiServer.js.map