athena-browser-mcp 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -3
- package/dist/src/browser/ensure-browser.d.ts +39 -0
- package/dist/src/browser/ensure-browser.d.ts.map +1 -0
- package/dist/src/browser/ensure-browser.js +65 -0
- package/dist/src/browser/ensure-browser.js.map +1 -0
- package/dist/src/browser/page-network-tracker.d.ts +10 -2
- package/dist/src/browser/page-network-tracker.d.ts.map +1 -1
- package/dist/src/browser/page-network-tracker.js +52 -88
- package/dist/src/browser/page-network-tracker.js.map +1 -1
- package/dist/src/browser/page-registry.d.ts +6 -6
- package/dist/src/browser/page-registry.d.ts.map +1 -1
- package/dist/src/browser/page-registry.js +6 -14
- package/dist/src/browser/page-registry.js.map +1 -1
- package/dist/src/browser/page-stabilization.d.ts +4 -4
- package/dist/src/browser/page-stabilization.d.ts.map +1 -1
- package/dist/src/browser/page-stabilization.js +3 -3
- package/dist/src/browser/session-manager.d.ts +71 -27
- package/dist/src/browser/session-manager.d.ts.map +1 -1
- package/dist/src/browser/session-manager.js +311 -169
- package/dist/src/browser/session-manager.js.map +1 -1
- package/dist/src/cdp/index.d.ts +1 -1
- package/dist/src/cdp/index.d.ts.map +1 -1
- package/dist/src/cdp/index.js +1 -1
- package/dist/src/cdp/index.js.map +1 -1
- package/dist/src/cdp/{playwright-cdp-client.d.ts → puppeteer-cdp-client.d.ts} +12 -13
- package/dist/src/cdp/puppeteer-cdp-client.d.ts.map +1 -0
- package/dist/src/cdp/{playwright-cdp-client.js → puppeteer-cdp-client.js} +21 -18
- package/dist/src/cdp/puppeteer-cdp-client.js.map +1 -0
- package/dist/src/cli/args.d.ts +35 -0
- package/dist/src/cli/args.d.ts.map +1 -0
- package/dist/src/cli/args.js +76 -0
- package/dist/src/cli/args.js.map +1 -0
- package/dist/src/delta/dom-stabilizer.d.ts +2 -2
- package/dist/src/delta/dom-stabilizer.d.ts.map +1 -1
- package/dist/src/delta/dom-stabilizer.js +1 -1
- package/dist/src/index.d.ts +2 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +59 -42
- package/dist/src/index.js.map +1 -1
- package/dist/src/observation/eid-linker.d.ts +21 -1
- package/dist/src/observation/eid-linker.d.ts.map +1 -1
- package/dist/src/observation/eid-linker.js +135 -0
- package/dist/src/observation/eid-linker.js.map +1 -1
- package/dist/src/observation/observation-accumulator.d.ts +1 -1
- package/dist/src/observation/observation-accumulator.d.ts.map +1 -1
- package/dist/src/observation/observation.types.d.ts +16 -0
- package/dist/src/observation/observation.types.d.ts.map +1 -1
- package/dist/src/server/server-config.d.ts +41 -0
- package/dist/src/server/server-config.d.ts.map +1 -0
- package/dist/src/server/server-config.js +80 -0
- package/dist/src/server/server-config.js.map +1 -0
- package/dist/src/snapshot/snapshot-compiler.d.ts +2 -2
- package/dist/src/snapshot/snapshot-compiler.d.ts.map +1 -1
- package/dist/src/snapshot/snapshot-compiler.js +2 -2
- package/dist/src/snapshot/snapshot-compiler.js.map +1 -1
- package/dist/src/snapshot/snapshot-health.d.ts +2 -2
- package/dist/src/snapshot/snapshot-health.d.ts.map +1 -1
- package/dist/src/snapshot/snapshot-health.js +1 -1
- package/dist/src/state/health.types.d.ts +1 -1
- package/dist/src/state/state-renderer.d.ts +24 -7
- package/dist/src/state/state-renderer.d.ts.map +1 -1
- package/dist/src/state/state-renderer.js +78 -112
- package/dist/src/state/state-renderer.js.map +1 -1
- package/dist/src/tools/browser-tools.d.ts +0 -14
- package/dist/src/tools/browser-tools.d.ts.map +1 -1
- package/dist/src/tools/browser-tools.js +2 -64
- package/dist/src/tools/browser-tools.js.map +1 -1
- package/dist/src/tools/execute-action.d.ts +2 -2
- package/dist/src/tools/execute-action.d.ts.map +1 -1
- package/dist/src/tools/execute-action.js +8 -10
- package/dist/src/tools/execute-action.js.map +1 -1
- package/dist/src/tools/index.d.ts +3 -2
- package/dist/src/tools/index.d.ts.map +1 -1
- package/dist/src/tools/index.js +3 -5
- package/dist/src/tools/index.js.map +1 -1
- package/dist/src/tools/tool-schemas.d.ts +0 -24
- package/dist/src/tools/tool-schemas.d.ts.map +1 -1
- package/dist/src/tools/tool-schemas.js +0 -18
- package/dist/src/tools/tool-schemas.js.map +1 -1
- package/package.json +2 -2
- package/dist/src/cdp/playwright-cdp-client.d.ts.map +0 -1
- package/dist/src/cdp/playwright-cdp-client.js.map +0 -1
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ The goal is not to mirror the browser, but to present the page in a form that al
|
|
|
40
40
|
|
|
41
41
|
At a high level:
|
|
42
42
|
|
|
43
|
-
1. The browser is controlled via
|
|
43
|
+
1. The browser is controlled via Puppeteer and CDP
|
|
44
44
|
2. The page is reduced into semantic regions and actionable elements
|
|
45
45
|
3. A structured snapshot is generated and sent to the LLM
|
|
46
46
|
4. Actions are resolved against stable semantic identifiers rather than fragile selectors
|
|
@@ -78,9 +78,9 @@ Results are task-dependent and should be treated as directional rather than abso
|
|
|
78
78
|
|
|
79
79
|
- A general-purpose browser
|
|
80
80
|
- A visual testing or screenshot framework
|
|
81
|
-
- A replacement for
|
|
81
|
+
- A replacement for Puppeteer
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
Puppeteer remains the execution layer; Athena focuses on representation and reasoning.
|
|
84
84
|
|
|
85
85
|
---
|
|
86
86
|
|
|
@@ -104,6 +104,79 @@ See the `examples/` directory for concrete agent workflows.
|
|
|
104
104
|
|
|
105
105
|
---
|
|
106
106
|
|
|
107
|
+
## Claude Code
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Basic (auto-launches browser)
|
|
111
|
+
claude mcp add athena-browser-mcp -- npx athena-browser-mcp@latest
|
|
112
|
+
|
|
113
|
+
# With auto-connect to your Chrome profile
|
|
114
|
+
claude mcp add athena-browser-mcp -- npx athena-browser-mcp@latest --autoConnect
|
|
115
|
+
|
|
116
|
+
# Headless mode
|
|
117
|
+
claude mcp add athena-browser-mcp -- npx athena-browser-mcp@latest --headless
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## CLI Arguments
|
|
123
|
+
|
|
124
|
+
The server accepts the following arguments to configure browser initialization:
|
|
125
|
+
|
|
126
|
+
| Argument | Description | Default |
|
|
127
|
+
| ------------------------ | --------------------------------------------------------------- | ---------------- |
|
|
128
|
+
| `--headless=true\|false` | Run browser in headless mode | `false` |
|
|
129
|
+
| `--browserUrl` | HTTP endpoint to connect to existing browser | - |
|
|
130
|
+
| `--wsEndpoint` | WebSocket endpoint to connect to existing browser | - |
|
|
131
|
+
| `--autoConnect` | Auto-connect to Chrome 144+ via DevToolsActivePort | `false` |
|
|
132
|
+
| `--isolated` | Use isolated temp profile instead of persistent | `false` |
|
|
133
|
+
| `--userDataDir` | Chrome user data directory | Platform default |
|
|
134
|
+
| `--channel` | Chrome channel (chrome, chrome-canary, chrome-beta, chrome-dev) | `chrome` |
|
|
135
|
+
| `--executablePath` | Path to Chrome executable | - |
|
|
136
|
+
|
|
137
|
+
### Automatic Browser Initialization
|
|
138
|
+
|
|
139
|
+
The browser is automatically launched or connected on the first tool call. No explicit initialization is needed.
|
|
140
|
+
|
|
141
|
+
Examples:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Auto-launch visible browser (default)
|
|
145
|
+
npx athena-browser-mcp
|
|
146
|
+
|
|
147
|
+
# Launch headless browser
|
|
148
|
+
npx athena-browser-mcp --headless
|
|
149
|
+
|
|
150
|
+
# Auto-connect to Chrome with remote debugging enabled
|
|
151
|
+
npx athena-browser-mcp --autoConnect
|
|
152
|
+
|
|
153
|
+
# Connect to specific endpoint
|
|
154
|
+
npx athena-browser-mcp --browserUrl http://localhost:9222
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Using Your Existing Chrome Profile (Chrome 144+)
|
|
160
|
+
|
|
161
|
+
To connect with your bookmarks, extensions, and logged-in sessions:
|
|
162
|
+
|
|
163
|
+
1. Navigate to `chrome://inspect/#remote-debugging` in Chrome
|
|
164
|
+
2. Enable remote debugging and allow the connection
|
|
165
|
+
3. Use `--autoConnect` CLI argument
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"mcpServers": {
|
|
170
|
+
"athena-browser-mcp": {
|
|
171
|
+
"command": "npx",
|
|
172
|
+
"args": ["athena-browser-mcp@latest", "--autoConnect"]
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
107
180
|
## Installation
|
|
108
181
|
|
|
109
182
|
```bash
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy Browser Initialization
|
|
3
|
+
*
|
|
4
|
+
* Ensures a browser is ready before tool execution.
|
|
5
|
+
* If no browser is running, launches or connects based on CLI configuration.
|
|
6
|
+
*/
|
|
7
|
+
import type { SessionManager } from './session-manager.js';
|
|
8
|
+
/**
|
|
9
|
+
* Options for lazy browser initialization.
|
|
10
|
+
*/
|
|
11
|
+
export interface EnsureBrowserOptions {
|
|
12
|
+
/** Run browser in headless mode (default: false) */
|
|
13
|
+
headless?: boolean;
|
|
14
|
+
/** Use isolated temp profile (default: false) */
|
|
15
|
+
isolated?: boolean;
|
|
16
|
+
/** HTTP endpoint URL for connecting to existing browser */
|
|
17
|
+
browserUrl?: string;
|
|
18
|
+
/** WebSocket endpoint URL for connecting to existing browser */
|
|
19
|
+
wsEndpoint?: string;
|
|
20
|
+
/** Auto-connect to Chrome 144+ via DevToolsActivePort */
|
|
21
|
+
autoConnect?: boolean;
|
|
22
|
+
/** Chrome user data directory */
|
|
23
|
+
userDataDir?: string;
|
|
24
|
+
/** Chrome channel */
|
|
25
|
+
channel?: 'chrome' | 'chrome-canary' | 'chrome-beta' | 'chrome-dev';
|
|
26
|
+
/** Path to Chrome executable */
|
|
27
|
+
executablePath?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Ensure browser is ready for tool execution.
|
|
31
|
+
*
|
|
32
|
+
* If browser is already running, returns immediately.
|
|
33
|
+
* Otherwise, launches or connects based on provided options.
|
|
34
|
+
*
|
|
35
|
+
* @param session - SessionManager instance
|
|
36
|
+
* @param options - Configuration options from CLI
|
|
37
|
+
*/
|
|
38
|
+
export declare function ensureBrowserReady(session: SessionManager, options: EnsureBrowserOptions): Promise<void>;
|
|
39
|
+
//# sourceMappingURL=ensure-browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-browser.d.ts","sourceRoot":"","sources":["../../../src/browser/ensure-browser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAK3D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,oDAAoD;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,yDAAyD;IACzD,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,iCAAiC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,qBAAqB;IACrB,OAAO,CAAC,EAAE,QAAQ,GAAG,eAAe,GAAG,aAAa,GAAG,YAAY,CAAC;IAEpE,gCAAgC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AASD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAwCf"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy Browser Initialization
|
|
3
|
+
*
|
|
4
|
+
* Ensures a browser is ready before tool execution.
|
|
5
|
+
* If no browser is running, launches or connects based on CLI configuration.
|
|
6
|
+
*/
|
|
7
|
+
import { getLogger } from '../shared/services/logging.service.js';
|
|
8
|
+
const logger = getLogger();
|
|
9
|
+
/**
|
|
10
|
+
* Determine if we should connect to an existing browser vs launch new one.
|
|
11
|
+
*/
|
|
12
|
+
function shouldConnect(options) {
|
|
13
|
+
return !!(options.browserUrl ?? options.wsEndpoint ?? options.autoConnect);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Ensure browser is ready for tool execution.
|
|
17
|
+
*
|
|
18
|
+
* If browser is already running, returns immediately.
|
|
19
|
+
* Otherwise, launches or connects based on provided options.
|
|
20
|
+
*
|
|
21
|
+
* @param session - SessionManager instance
|
|
22
|
+
* @param options - Configuration options from CLI
|
|
23
|
+
*/
|
|
24
|
+
export async function ensureBrowserReady(session, options) {
|
|
25
|
+
// Fast path: browser already running
|
|
26
|
+
if (session.isRunning()) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const mode = shouldConnect(options) ? 'connect' : 'launch';
|
|
30
|
+
logger.info('Lazy browser initialization triggered', { mode });
|
|
31
|
+
try {
|
|
32
|
+
if (shouldConnect(options)) {
|
|
33
|
+
// Connect to existing browser
|
|
34
|
+
await session.connect({
|
|
35
|
+
browserURL: options.browserUrl,
|
|
36
|
+
browserWSEndpoint: options.wsEndpoint,
|
|
37
|
+
autoConnect: options.autoConnect,
|
|
38
|
+
userDataDir: options.userDataDir,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// Launch new browser
|
|
43
|
+
await session.launch({
|
|
44
|
+
headless: options.headless ?? false,
|
|
45
|
+
isolated: options.isolated ?? false,
|
|
46
|
+
userDataDir: options.userDataDir,
|
|
47
|
+
channel: options.channel,
|
|
48
|
+
executablePath: options.executablePath,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
logger.info('Browser initialized successfully', { mode });
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
logger.error('Browser initialization failed', error instanceof Error ? error : undefined, {
|
|
55
|
+
mode,
|
|
56
|
+
browserUrl: options.browserUrl,
|
|
57
|
+
wsEndpoint: options.wsEndpoint,
|
|
58
|
+
autoConnect: options.autoConnect,
|
|
59
|
+
headless: options.headless,
|
|
60
|
+
userDataDir: options.userDataDir,
|
|
61
|
+
});
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=ensure-browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-browser.js","sourceRoot":"","sources":["../../../src/browser/ensure-browser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAElE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;AA+B3B;;GAEG;AACH,SAAS,aAAa,CAAC,OAA6B;IAClD,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAuB,EACvB,OAA6B;IAE7B,qCAAqC;IACrC,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QACxB,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC3D,MAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,IAAI,CAAC;QACH,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,8BAA8B;YAC9B,MAAM,OAAO,CAAC,OAAO,CAAC;gBACpB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,iBAAiB,EAAE,OAAO,CAAC,UAAU;gBACrC,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,WAAW,EAAE,OAAO,CAAC,WAAW;aACjC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,qBAAqB;YACrB,MAAM,OAAO,CAAC,MAAM,CAAC;gBACnB,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;gBACnC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;gBACnC,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,cAAc,EAAE,OAAO,CAAC,cAAc;aACvC,CAAC,CAAC;QACL,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE;YACxF,IAAI;YACJ,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC,CAAC,CAAC;QACH,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
* Page Network Tracker
|
|
3
3
|
*
|
|
4
4
|
* Tracks in-flight network requests for a page and provides a reliable
|
|
5
|
-
* "network quiet" wait mechanism. Unlike
|
|
5
|
+
* "network quiet" wait mechanism. Unlike Puppeteer's waitForNetworkIdle(),
|
|
6
6
|
* this tracks requests triggered after page load (e.g., by user actions).
|
|
7
7
|
*
|
|
8
8
|
* Uses a generation counter to safely handle navigation - late events from
|
|
9
9
|
* previous documents are ignored.
|
|
10
10
|
*/
|
|
11
|
-
import type { Page } from '
|
|
11
|
+
import type { Page } from 'puppeteer-core';
|
|
12
12
|
/**
|
|
13
13
|
* Tracks network requests for a single page.
|
|
14
14
|
*
|
|
@@ -67,6 +67,14 @@ export declare class PageNetworkTracker {
|
|
|
67
67
|
private cancelQuietTimer;
|
|
68
68
|
private checkQuiet;
|
|
69
69
|
private startQuietTimer;
|
|
70
|
+
/**
|
|
71
|
+
* Create and attach event handlers for the current generation.
|
|
72
|
+
*/
|
|
73
|
+
private createAndAttachHandlers;
|
|
74
|
+
/**
|
|
75
|
+
* Remove event handlers from a page.
|
|
76
|
+
*/
|
|
77
|
+
private removeHandlers;
|
|
70
78
|
}
|
|
71
79
|
/**
|
|
72
80
|
* Get or create a network tracker for a page.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-network-tracker.d.ts","sourceRoot":"","sources":["../../../src/browser/page-network-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"page-network-tracker.d.ts","sourceRoot":"","sources":["../../../src/browser/page-network-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,gBAAgB,CAAC;AAKxD;;;;;;GAMG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,iBAAiB,CAAK;IAG9B,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,cAAc,CAAyE;IAG/F,OAAO,CAAC,SAAS,CAA6C;IAC9D,OAAO,CAAC,iBAAiB,CAA6C;IACtE,OAAO,CAAC,eAAe,CAA6C;IAEpE;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAaxB;;;;OAIG;IACH,MAAM,IAAI,IAAI;IAmBd;;;;;;OAMG;IACH,cAAc,IAAI,IAAI;IAYtB;;;;;;OAMG;IACG,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,aAAa,GAAE,MAAgC,GAC9C,OAAO,CAAC,OAAO,CAAC;IAuBnB;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACH,UAAU,IAAI,OAAO;IAMrB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,eAAe;IAavB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA6B/B;;OAEG;IACH,OAAO,CAAC,cAAc;CAWvB;AAYD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,kBAAkB,CAOjE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAM9C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAE9C"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Page Network Tracker
|
|
3
3
|
*
|
|
4
4
|
* Tracks in-flight network requests for a page and provides a reliable
|
|
5
|
-
* "network quiet" wait mechanism. Unlike
|
|
5
|
+
* "network quiet" wait mechanism. Unlike Puppeteer's waitForNetworkIdle(),
|
|
6
6
|
* this tracks requests triggered after page load (e.g., by user actions).
|
|
7
7
|
*
|
|
8
8
|
* Uses a generation counter to safely handle navigation - late events from
|
|
@@ -37,7 +37,6 @@ export class PageNetworkTracker {
|
|
|
37
37
|
* Safe to call multiple times - will detach previous listeners first.
|
|
38
38
|
*/
|
|
39
39
|
attach(page) {
|
|
40
|
-
// Detach from previous page if any
|
|
41
40
|
if (this.page) {
|
|
42
41
|
this.detach();
|
|
43
42
|
}
|
|
@@ -45,37 +44,7 @@ export class PageNetworkTracker {
|
|
|
45
44
|
this.generation++;
|
|
46
45
|
this.currentGeneration = this.generation;
|
|
47
46
|
this.inflightCount = 0;
|
|
48
|
-
|
|
49
|
-
this.onRequest = (req) => {
|
|
50
|
-
// Ignore stale events from previous document
|
|
51
|
-
if (this.currentGeneration !== gen)
|
|
52
|
-
return;
|
|
53
|
-
// Ignore websockets (persistent connections)
|
|
54
|
-
if (req.resourceType() === 'websocket')
|
|
55
|
-
return;
|
|
56
|
-
this.inflightCount++;
|
|
57
|
-
this.cancelQuietTimer();
|
|
58
|
-
};
|
|
59
|
-
this.onRequestFinished = (req) => {
|
|
60
|
-
if (this.currentGeneration !== gen)
|
|
61
|
-
return;
|
|
62
|
-
if (req.resourceType() === 'websocket')
|
|
63
|
-
return;
|
|
64
|
-
// Never go below 0 (handles edge cases)
|
|
65
|
-
this.inflightCount = Math.max(0, this.inflightCount - 1);
|
|
66
|
-
this.checkQuiet();
|
|
67
|
-
};
|
|
68
|
-
this.onRequestFailed = (req) => {
|
|
69
|
-
if (this.currentGeneration !== gen)
|
|
70
|
-
return;
|
|
71
|
-
if (req.resourceType() === 'websocket')
|
|
72
|
-
return;
|
|
73
|
-
this.inflightCount = Math.max(0, this.inflightCount - 1);
|
|
74
|
-
this.checkQuiet();
|
|
75
|
-
};
|
|
76
|
-
page.on('request', this.onRequest);
|
|
77
|
-
page.on('requestfinished', this.onRequestFinished);
|
|
78
|
-
page.on('requestfailed', this.onRequestFailed);
|
|
47
|
+
this.createAndAttachHandlers(page);
|
|
79
48
|
}
|
|
80
49
|
/**
|
|
81
50
|
* Detach all event listeners and cleanup timers.
|
|
@@ -84,23 +53,13 @@ export class PageNetworkTracker {
|
|
|
84
53
|
*/
|
|
85
54
|
detach() {
|
|
86
55
|
if (this.page) {
|
|
87
|
-
|
|
88
|
-
this.page.off('request', this.onRequest);
|
|
89
|
-
}
|
|
90
|
-
if (this.onRequestFinished) {
|
|
91
|
-
this.page.off('requestfinished', this.onRequestFinished);
|
|
92
|
-
}
|
|
93
|
-
if (this.onRequestFailed) {
|
|
94
|
-
this.page.off('requestfailed', this.onRequestFailed);
|
|
95
|
-
}
|
|
56
|
+
this.removeHandlers(this.page);
|
|
96
57
|
}
|
|
97
58
|
this.onRequest = null;
|
|
98
59
|
this.onRequestFinished = null;
|
|
99
60
|
this.onRequestFailed = null;
|
|
100
61
|
this.page = null;
|
|
101
|
-
// Cancel any pending quiet timers
|
|
102
62
|
this.cancelQuietTimer();
|
|
103
|
-
// Reject all pending waiters with false (not idle)
|
|
104
63
|
for (const { resolve, timeoutId } of this.quietResolvers) {
|
|
105
64
|
clearTimeout(timeoutId);
|
|
106
65
|
resolve(false);
|
|
@@ -119,48 +78,9 @@ export class PageNetworkTracker {
|
|
|
119
78
|
this.currentGeneration = this.generation;
|
|
120
79
|
this.inflightCount = 0;
|
|
121
80
|
this.cancelQuietTimer();
|
|
122
|
-
// Re-attach handlers with new generation if we have a page
|
|
123
81
|
if (this.page) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (this.onRequest) {
|
|
127
|
-
page.off('request', this.onRequest);
|
|
128
|
-
}
|
|
129
|
-
if (this.onRequestFinished) {
|
|
130
|
-
page.off('requestfinished', this.onRequestFinished);
|
|
131
|
-
}
|
|
132
|
-
if (this.onRequestFailed) {
|
|
133
|
-
page.off('requestfailed', this.onRequestFailed);
|
|
134
|
-
}
|
|
135
|
-
// Create new handlers with updated generation
|
|
136
|
-
const gen = this.currentGeneration;
|
|
137
|
-
this.onRequest = (req) => {
|
|
138
|
-
if (this.currentGeneration !== gen)
|
|
139
|
-
return;
|
|
140
|
-
if (req.resourceType() === 'websocket')
|
|
141
|
-
return;
|
|
142
|
-
this.inflightCount++;
|
|
143
|
-
this.cancelQuietTimer();
|
|
144
|
-
};
|
|
145
|
-
this.onRequestFinished = (req) => {
|
|
146
|
-
if (this.currentGeneration !== gen)
|
|
147
|
-
return;
|
|
148
|
-
if (req.resourceType() === 'websocket')
|
|
149
|
-
return;
|
|
150
|
-
this.inflightCount = Math.max(0, this.inflightCount - 1);
|
|
151
|
-
this.checkQuiet();
|
|
152
|
-
};
|
|
153
|
-
this.onRequestFailed = (req) => {
|
|
154
|
-
if (this.currentGeneration !== gen)
|
|
155
|
-
return;
|
|
156
|
-
if (req.resourceType() === 'websocket')
|
|
157
|
-
return;
|
|
158
|
-
this.inflightCount = Math.max(0, this.inflightCount - 1);
|
|
159
|
-
this.checkQuiet();
|
|
160
|
-
};
|
|
161
|
-
page.on('request', this.onRequest);
|
|
162
|
-
page.on('requestfinished', this.onRequestFinished);
|
|
163
|
-
page.on('requestfailed', this.onRequestFailed);
|
|
82
|
+
this.removeHandlers(this.page);
|
|
83
|
+
this.createAndAttachHandlers(this.page);
|
|
164
84
|
}
|
|
165
85
|
}
|
|
166
86
|
/**
|
|
@@ -214,12 +134,9 @@ export class PageNetworkTracker {
|
|
|
214
134
|
}
|
|
215
135
|
}
|
|
216
136
|
startQuietTimer() {
|
|
217
|
-
// Cancel any existing timer first
|
|
218
137
|
this.cancelQuietTimer();
|
|
219
|
-
// Start quiet window timer
|
|
220
138
|
this.quietTimer = setTimeout(() => {
|
|
221
139
|
this.quietTimer = null;
|
|
222
|
-
// Resolve all pending waiters
|
|
223
140
|
for (const { resolve, timeoutId } of this.quietResolvers) {
|
|
224
141
|
clearTimeout(timeoutId);
|
|
225
142
|
resolve(true);
|
|
@@ -227,6 +144,53 @@ export class PageNetworkTracker {
|
|
|
227
144
|
this.quietResolvers = [];
|
|
228
145
|
}, this.quietWindowMs);
|
|
229
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Create and attach event handlers for the current generation.
|
|
149
|
+
*/
|
|
150
|
+
createAndAttachHandlers(page) {
|
|
151
|
+
const gen = this.currentGeneration;
|
|
152
|
+
this.onRequest = (req) => {
|
|
153
|
+
if (this.currentGeneration !== gen)
|
|
154
|
+
return;
|
|
155
|
+
if (req.resourceType() === 'websocket')
|
|
156
|
+
return;
|
|
157
|
+
this.inflightCount++;
|
|
158
|
+
this.cancelQuietTimer();
|
|
159
|
+
};
|
|
160
|
+
this.onRequestFinished = (req) => {
|
|
161
|
+
if (this.currentGeneration !== gen)
|
|
162
|
+
return;
|
|
163
|
+
if (req.resourceType() === 'websocket')
|
|
164
|
+
return;
|
|
165
|
+
this.inflightCount = Math.max(0, this.inflightCount - 1);
|
|
166
|
+
this.checkQuiet();
|
|
167
|
+
};
|
|
168
|
+
this.onRequestFailed = (req) => {
|
|
169
|
+
if (this.currentGeneration !== gen)
|
|
170
|
+
return;
|
|
171
|
+
if (req.resourceType() === 'websocket')
|
|
172
|
+
return;
|
|
173
|
+
this.inflightCount = Math.max(0, this.inflightCount - 1);
|
|
174
|
+
this.checkQuiet();
|
|
175
|
+
};
|
|
176
|
+
page.on('request', this.onRequest);
|
|
177
|
+
page.on('requestfinished', this.onRequestFinished);
|
|
178
|
+
page.on('requestfailed', this.onRequestFailed);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Remove event handlers from a page.
|
|
182
|
+
*/
|
|
183
|
+
removeHandlers(page) {
|
|
184
|
+
if (this.onRequest) {
|
|
185
|
+
page.off('request', this.onRequest);
|
|
186
|
+
}
|
|
187
|
+
if (this.onRequestFinished) {
|
|
188
|
+
page.off('requestfinished', this.onRequestFinished);
|
|
189
|
+
}
|
|
190
|
+
if (this.onRequestFailed) {
|
|
191
|
+
page.off('requestfailed', this.onRequestFailed);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
230
194
|
}
|
|
231
195
|
// --- Global Registry ---
|
|
232
196
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-network-tracker.js","sourceRoot":"","sources":["../../../src/browser/page-network-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,8EAA8E;AAC9E,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAEpC;;;;;;GAMG;AACH,MAAM,OAAO,kBAAkB;IACrB,IAAI,GAAgB,IAAI,CAAC;IACzB,aAAa,GAAG,CAAC,CAAC;IAClB,UAAU,GAAG,CAAC,CAAC;IACf,iBAAiB,GAAG,CAAC,CAAC;IAE9B,qBAAqB;IACb,UAAU,GAA0B,IAAI,CAAC;IACzC,aAAa,GAAW,uBAAuB,CAAC;IAChD,cAAc,GAAsE,EAAE,CAAC;IAE/F,qDAAqD;IAC7C,SAAS,
|
|
1
|
+
{"version":3,"file":"page-network-tracker.js","sourceRoot":"","sources":["../../../src/browser/page-network-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Page Registry
|
|
3
3
|
*
|
|
4
|
-
* Tracks active
|
|
4
|
+
* Tracks active Puppeteer pages and their CDP sessions.
|
|
5
5
|
* Provides a central registry for page lifecycle management.
|
|
6
6
|
*/
|
|
7
|
-
import type { Page } from '
|
|
7
|
+
import type { Page } from 'puppeteer-core';
|
|
8
8
|
import type { CdpClient } from '../cdp/cdp-client.interface.js';
|
|
9
9
|
/**
|
|
10
10
|
* Handle to a registered page with its CDP session
|
|
@@ -12,7 +12,7 @@ import type { CdpClient } from '../cdp/cdp-client.interface.js';
|
|
|
12
12
|
export interface PageHandle {
|
|
13
13
|
/** Unique identifier for this page */
|
|
14
14
|
page_id: string;
|
|
15
|
-
/**
|
|
15
|
+
/** Puppeteer Page instance */
|
|
16
16
|
page: Page;
|
|
17
17
|
/** CDP client for this page */
|
|
18
18
|
cdp: CdpClient;
|
|
@@ -33,7 +33,7 @@ export declare class PageRegistry {
|
|
|
33
33
|
/**
|
|
34
34
|
* Register a new page with its CDP session
|
|
35
35
|
*
|
|
36
|
-
* @param page -
|
|
36
|
+
* @param page - Puppeteer Page instance
|
|
37
37
|
* @param cdp - CDP client for the page
|
|
38
38
|
* @returns PageHandle with unique page_id
|
|
39
39
|
* @throws Error if page is already closed
|
|
@@ -96,9 +96,9 @@ export declare class PageRegistry {
|
|
|
96
96
|
*/
|
|
97
97
|
updateMetadata(page_id: string, metadata: Partial<Pick<PageHandle, 'url' | 'title'>>): boolean;
|
|
98
98
|
/**
|
|
99
|
-
* Find a handle by its
|
|
99
|
+
* Find a handle by its Puppeteer Page instance
|
|
100
100
|
*
|
|
101
|
-
* @param page -
|
|
101
|
+
* @param page - Puppeteer Page instance to find
|
|
102
102
|
* @returns PageHandle if found, undefined otherwise
|
|
103
103
|
*/
|
|
104
104
|
findByPage(page: Page): PageHandle | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-registry.d.ts","sourceRoot":"","sources":["../../../src/browser/page-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"page-registry.d.ts","sourceRoot":"","sources":["../../../src/browser/page-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAGhE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAEhB,8BAA8B;IAC9B,IAAI,EAAE,IAAI,CAAC;IAEX,+BAA+B;IAC/B,GAAG,EAAE,SAAS,CAAC;IAEf,mCAAmC;IACnC,UAAU,EAAE,IAAI,CAAC;IAEjB,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,wDAAwD;IACxD,OAAO,CAAC,SAAS,CAAuB;IAExC;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,GAAG,UAAU;IAsBhD;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI5C;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAUhC;;;;OAIG;IACH,IAAI,IAAI,UAAU,EAAE;IAIpB;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;;;OAIG;IACH,IAAI,IAAI,MAAM;IAId;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI7B;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO;IAQrD;;;;;;OAMG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,OAAO;IAgB9F;;;;;OAKG;IACH,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,GAAG,SAAS;IAI9C;;;;;OAKG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE;IAIpC;;;;;;;OAOG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IASjC;;;;;OAKG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAQ/B;;;;;;OAMG;IACH,aAAa,IAAI,UAAU,GAAG,SAAS;CAOxC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Page Registry
|
|
3
3
|
*
|
|
4
|
-
* Tracks active
|
|
4
|
+
* Tracks active Puppeteer pages and their CDP sessions.
|
|
5
5
|
* Provides a central registry for page lifecycle management.
|
|
6
6
|
*/
|
|
7
7
|
import { randomUUID } from 'crypto';
|
|
@@ -15,13 +15,13 @@ export class PageRegistry {
|
|
|
15
15
|
/**
|
|
16
16
|
* Register a new page with its CDP session
|
|
17
17
|
*
|
|
18
|
-
* @param page -
|
|
18
|
+
* @param page - Puppeteer Page instance
|
|
19
19
|
* @param cdp - CDP client for the page
|
|
20
20
|
* @returns PageHandle with unique page_id
|
|
21
21
|
* @throws Error if page is already closed
|
|
22
22
|
*/
|
|
23
23
|
register(page, cdp) {
|
|
24
|
-
// Validate page is not closed
|
|
24
|
+
// Validate page is not closed (Puppeteer uses isClosed())
|
|
25
25
|
if (page.isClosed()) {
|
|
26
26
|
throw new Error('Cannot register a closed page');
|
|
27
27
|
}
|
|
@@ -131,9 +131,9 @@ export class PageRegistry {
|
|
|
131
131
|
return true;
|
|
132
132
|
}
|
|
133
133
|
/**
|
|
134
|
-
* Find a handle by its
|
|
134
|
+
* Find a handle by its Puppeteer Page instance
|
|
135
135
|
*
|
|
136
|
-
* @param page -
|
|
136
|
+
* @param page - Puppeteer Page instance to find
|
|
137
137
|
* @returns PageHandle if found, undefined otherwise
|
|
138
138
|
*/
|
|
139
139
|
findByPage(page) {
|
|
@@ -161,15 +161,7 @@ export class PageRegistry {
|
|
|
161
161
|
if (!handle) {
|
|
162
162
|
return false;
|
|
163
163
|
}
|
|
164
|
-
|
|
165
|
-
if (handle.page.isClosed()) {
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
// Check if CDP session is still active
|
|
169
|
-
if (!handle.cdp.isActive()) {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
return true;
|
|
164
|
+
return !handle.page.isClosed() && handle.cdp.isActive();
|
|
173
165
|
}
|
|
174
166
|
/**
|
|
175
167
|
* Touch a page to mark it as most recently used.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-registry.js","sourceRoot":"","sources":["../../../src/browser/page-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAyBpC;;GAEG;AACH,MAAM,OAAO,YAAY;IACN,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IACvD,wDAAwD;IAChD,SAAS,GAAkB,IAAI,CAAC;IAExC;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAU,EAAE,GAAc;QACjC,
|
|
1
|
+
{"version":3,"file":"page-registry.js","sourceRoot":"","sources":["../../../src/browser/page-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* Used by session-manager and execute-action.
|
|
6
6
|
*
|
|
7
7
|
* IMPORTANT: This module uses PageNetworkTracker for reliable network idle
|
|
8
|
-
* detection. Unlike
|
|
8
|
+
* detection. Unlike Puppeteer's waitForNetworkIdle(), the tracker
|
|
9
9
|
* monitors actual request/response events and works for in-page actions
|
|
10
10
|
* (not just navigation load states).
|
|
11
11
|
*/
|
|
12
|
-
import type { Page } from '
|
|
12
|
+
import type { Page } from 'puppeteer-core';
|
|
13
13
|
/** Default timeout for network idle waiting after actions (ms) */
|
|
14
14
|
export declare const ACTION_NETWORK_IDLE_TIMEOUT_MS = 3000;
|
|
15
15
|
/** Default timeout for network idle waiting after navigation (ms) */
|
|
@@ -23,10 +23,10 @@ export declare const DEFAULT_QUIET_WINDOW_MS = 500;
|
|
|
23
23
|
* which monitors request/response events directly, providing reliable detection
|
|
24
24
|
* of network activity for both navigation and in-page actions.
|
|
25
25
|
*
|
|
26
|
-
* Unlike
|
|
26
|
+
* Unlike Puppeteer's waitForNetworkIdle(), this works correctly
|
|
27
27
|
* for fetch/XHR requests triggered by user actions after page load.
|
|
28
28
|
*
|
|
29
|
-
* @param page -
|
|
29
|
+
* @param page - Puppeteer Page instance
|
|
30
30
|
* @param timeoutMs - Maximum time to wait for network idle
|
|
31
31
|
* @param quietWindowMs - Time with 0 inflight requests to consider "idle" (default: 500ms)
|
|
32
32
|
* @returns Whether network became idle (false = timed out, but that's OK - never throws)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-stabilization.d.ts","sourceRoot":"","sources":["../../../src/browser/page-stabilization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"page-stabilization.d.ts","sourceRoot":"","sources":["../../../src/browser/page-stabilization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAG3C,kEAAkE;AAClE,eAAO,MAAM,8BAA8B,OAAO,CAAC;AAEnD,qEAAqE;AACrE,eAAO,MAAM,kCAAkC,OAAO,CAAC;AAEvD,mFAAmF;AACnF,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,EACjB,aAAa,GAAE,MAAgC,GAC9C,OAAO,CAAC,OAAO,CAAC,CASlB"}
|