Add AutoSessionRouter which takes care of all CDP command routing + Mod.getTopology to expose unified Session+Target+Frame+DomRoot+ExecutionContext tree that it uses to route#8
Open
pirate wants to merge 1 commit into
Conversation
Mod.getTopology to get unified Session+Target+Frame+DomRoot+ExecutionContext tree
Mod.getTopology to get unified Session+Target+Frame+DomRoot+ExecutionContext treeAutoSessionRouter which takes care of all CDP command routing + Mod.getTopology to expose unified Session+Target+Frame+DomRoot+ExecutionContext tree that it uses
AutoSessionRouter which takes care of all CDP command routing + Mod.getTopology to expose unified Session+Target+Frame+DomRoot+ExecutionContext tree that it usesAutoSessionRouter which takes care of all CDP command routing + Mod.getTopology to expose unified Session+Target+Frame+DomRoot+ExecutionContext tree that it uses to route
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CDP clients repeatedly have to keep several browser-owned identifiers in sync before they can send a command to the right place:
targetId: the browser target for a page, iframe/OOPIF, worker, or extension context.sessionId: the flattened CDP session id used by loopback CDP afterTarget.attachToTarget. Inchrome.debuggermode the parent page route is sessionless, while child sessions fromTarget.attachedToTargetare still observed and mapped when Chrome emits them.frameId: the Page domain frame id. Same-process frames share their target; OOPIFs appear as iframe targets and have to be stitched back into the frame tree throughparentFrameId.executionContextId: the Runtime context id used for evaluation. It is only meaningful inside its target/session route and changes on navigation or context teardown. The router records the native id, optionaluniqueId, owningtargetId, optionalsessionId,frameId, and semantic world (main,piercer, or isolated-world name).backendNodeId: the DOM boundary ids needed to cross document, iframe, and shadow-root boundaries. The topology exposes only the boundary ids that matter: frame owner<iframe>ids, document<html>ids, shadow host ids, and shadow-root ids.objectId: live Runtime remote-object handles for document and shadow roots. These are returned as the keys oftopology.rootsand are scoped to the returnedobjectGroup, so callers can use them immediately with Runtime/DOM commands and release the group when done.This PR adds an
AutoSessionRouterlayer that owns the generic routing state and uses it consistently for server-side CDP dispatch. The router subscribes to typed upstream CDP events (Target.*,Runtime.*, andPage.*) from the selectedServerUpstreamTransport, records target/session/context mappings as they change, invalidates context records on navigation, frame detach, context clear/destroy, target detach, and target destroy, and routes standard CDP commands through the active upstream without leaking loopback-vs-chrome.debuggerlogic into callers.The PR also adds
Mod.getTopology, which exposes the router's current view plus a fresh topology build in one command. It starts from the selected root page target, enables Page/DOM/Runtime/flattened auto-attach for each relevant target, walks same-process frame trees and OOPIF iframe targets, resolves frame owner backend node ids, creates or reuses a dedicated__modcdp_piercer__isolated world for each frame, resolves each document root, and walksDOM.getDocument({ depth: -1, pierce: true })to include open and closed shadow roots. Topology work runs through a small breadth-style queue with up to 8 concurrent frame/target tasks so pages with many frames do not require serial per-frame traversal.Mod.getTopologyreturns flat id-keyed maps:rootFrameId: the root Page frame id for the chosen target.frames:frameId -> { targetId, url, parentFrameId, outerBackendNodeId }.targets:targetId -> TargetInfo + optional sessionId.contexts: router context key -> Runtime execution context metadata, including route and world.roots: RuntimeobjectId -> { kind: "document" | "shadow", frameId, outerBackendNodeId, innerBackendNodeId, mode, executionContextId, uniqueContextId }.objectGroup: the Runtime object group used for the returned root handles.This keeps ModCDP generic. It does not add locator, XPath, DOM-summary, Stagehand, or Understudy logic to ModCDP. Higher layers can consume the topology to build cross-OOPIF DOM summaries, deep selectors that pierce closed shadow roots and frame boundaries, or other browser-graph-aware features without reimplementing target/session/context/frame traversal themselves.
Validation
pnpm exec tsc -p tsconfig.json --noEmitpnpm run buildpnpm exec vitest run js/test/test.ServerUpstreamTransport.ts js/test/test.ModCDPClientRoutedDefaultOverrides.ts --fileParallelism=false --maxWorkers=1pnpm exec prek run --all-files