{"version":3,"file":"browser/base.mjs","sources":["webpack://@agent-infra/browser/./src/browser/base.ts"],"sourcesContent":["/*\n * Copyright (c) 2025 Bytedance, Inc. and its affiliates.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Browser as pptrBrowser, Viewport } from 'puppeteer-core';\n\nimport type { Tabs } from '../tabs/tabs';\nimport type { EnvInfo, UserAgentInfo } from '../types';\n\nconst MAX_RETRIES = 5;\nconst INITIAL_BACKOFF = 2000;\n\n/**\n * Abstract base class for browser implementations\n * Contains common functionality shared between Browser and UIBrowser\n */\nexport abstract class BaseBrowser<TTabs extends Tabs> {\n  public pptrBrowser?: pptrBrowser;\n  public _tabs?: TTabs;\n  public _envInfo?: EnvInfo;\n  public wsEndpoint = '';\n  public defaultViewport: Viewport = {\n    width: 1280,\n    height: 1024,\n    deviceScaleFactor: 0,\n    isMobile: false,\n    isLandscape: false,\n    hasTouch: false,\n  };\n  public isIntentionalDisconnect: boolean = false;\n  public reconnectAttempts: number = 0;\n  public userAgentInfo?: UserAgentInfo;\n\n  constructor() {}\n\n  // #region tabs\n\n  private get tabs(): TTabs {\n    if (!this._tabs) {\n      throw new Error('Tabs not initialized');\n    }\n    return this._tabs;\n  }\n\n  getTabsSnapshot() {\n    return this.tabs.getSnapshot();\n  }\n\n  subscribeTabChange(callback: () => void) {\n    return this.tabs.subscribe(callback);\n  }\n\n  getActiveTab() {\n    return this.tabs.getActiveTab();\n  }\n\n  async createTab() {\n    return this.tabs.createTab();\n  }\n\n  async activeTab(tabId: string) {\n    return this.tabs.activeTab(tabId);\n  }\n\n  async closeTab(tabId: string) {\n    return this.tabs.closeTab(tabId);\n  }\n\n  async destroyAllTabs() {\n    return this.tabs.destroy();\n  }\n\n  // #endregion\n\n  // #region userAgent\n\n  /**\n   * Set the user agent for the browser and future tabs\n   */\n  setUserAgent(options: UserAgentInfo): void {\n    this.userAgentInfo = options;\n  }\n\n  /**\n   * Get the current user agent\n   */\n  async getUserAgent() {\n    if (this.userAgentInfo) {\n      return this.userAgentInfo;\n    }\n\n    const uaString = await this.pptrBrowser?.userAgent();\n    return { userAgent: uaString };\n  }\n\n  // #endregion\n\n  // #region other methods\n\n  get envInfo(): any {\n    return this._envInfo!;\n  }\n\n  async getBrowserMetaInfo() {\n    if (!this.pptrBrowser) {\n      throw new Error('Browser not initialized');\n    }\n\n    const userAgent = await this.pptrBrowser.userAgent();\n\n    return {\n      envInfo: this._envInfo!,\n      userAgent,\n      viewport: this.defaultViewport,\n      wsEndpoint: this.wsEndpoint,\n    };\n  }\n\n  async disconnect(): Promise<void> {\n    this.isIntentionalDisconnect = true;\n    if (this._tabs && typeof (this._tabs as any).destroy === 'function') {\n      await (this._tabs as any).destroy();\n    }\n    await this.pptrBrowser?.disconnect();\n  }\n\n  public setDefaultViewport(viewport?: Viewport | null): Viewport {\n    if (!viewport) {\n      return this.defaultViewport;\n    }\n\n    if (typeof viewport === 'object') {\n      this.defaultViewport = {\n        ...this.defaultViewport,\n        ...viewport,\n      };\n    }\n\n    return this.defaultViewport;\n  }\n\n  // #endregion\n\n  // #region reconnect logic\n\n  public setupAutoReconnect(): void {\n    if (!this.pptrBrowser) return;\n\n    this.pptrBrowser.on('disconnected', () => {\n      if (this.isIntentionalDisconnect) {\n        return;\n      }\n      this.attemptReconnect();\n    });\n  }\n\n  protected abstract performReconnect(): Promise<void>;\n\n  protected async attemptReconnect(): Promise<void> {\n    if (this.reconnectAttempts >= MAX_RETRIES) {\n      console.error('Max reconnect attempts reached. Giving up reconnecting');\n      return;\n    }\n    if (!this.wsEndpoint) {\n      console.error('No wsEndpoint found. Cannot reconnect');\n      return;\n    }\n\n    const delay = INITIAL_BACKOFF * this.reconnectAttempts;\n    await new Promise((resolve) => setTimeout(resolve, delay));\n    this.reconnectAttempts++;\n\n    try {\n      await this.performReconnect();\n      this.reconnectAttempts = 0;\n    } catch (error) {\n      if (this.reconnectAttempts < MAX_RETRIES) {\n        this.attemptReconnect();\n      } else {\n        console.error('Failed to reconnect after max retries:', error);\n      }\n    }\n  }\n\n  // #endregion\n}\n"],"names":["MAX_RETRIES","INITIAL_BACKOFF","BaseBrowser","Error","callback","tabId","options","_this_pptrBrowser","uaString","userAgent","viewport","console","delay","Promise","resolve","setTimeout","error"],"mappings":"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"}