agent-web-interface 4.2.0 → 4.4.0

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.
Files changed (265) hide show
  1. package/dist/src/browser/connection-utils.d.ts +48 -0
  2. package/dist/src/browser/connection-utils.d.ts.map +1 -0
  3. package/dist/src/browser/connection-utils.js +129 -0
  4. package/dist/src/browser/connection-utils.js.map +1 -0
  5. package/dist/src/browser/index.d.ts +3 -1
  6. package/dist/src/browser/index.d.ts.map +1 -1
  7. package/dist/src/browser/index.js +2 -1
  8. package/dist/src/browser/index.js.map +1 -1
  9. package/dist/src/browser/session-manager.d.ts +1 -89
  10. package/dist/src/browser/session-manager.d.ts.map +1 -1
  11. package/dist/src/browser/session-manager.js +1 -116
  12. package/dist/src/browser/session-manager.js.map +1 -1
  13. package/dist/src/browser/session-manager.types.d.ts +90 -0
  14. package/dist/src/browser/session-manager.types.d.ts.map +1 -0
  15. package/dist/src/browser/session-manager.types.js +7 -0
  16. package/dist/src/browser/session-manager.types.js.map +1 -0
  17. package/dist/src/form/constraint-extraction.d.ts +31 -0
  18. package/dist/src/form/constraint-extraction.d.ts.map +1 -0
  19. package/dist/src/form/constraint-extraction.js +110 -0
  20. package/dist/src/form/constraint-extraction.js.map +1 -0
  21. package/dist/src/form/field-extractor.d.ts.map +1 -1
  22. package/dist/src/form/field-extractor.js +3 -444
  23. package/dist/src/form/field-extractor.js.map +1 -1
  24. package/dist/src/form/field-state-extractor.d.ts +22 -0
  25. package/dist/src/form/field-state-extractor.d.ts.map +1 -0
  26. package/dist/src/form/field-state-extractor.js +55 -0
  27. package/dist/src/form/field-state-extractor.js.map +1 -0
  28. package/dist/src/form/form-actions.d.ts +45 -0
  29. package/dist/src/form/form-actions.d.ts.map +1 -0
  30. package/dist/src/form/form-actions.js +108 -0
  31. package/dist/src/form/form-actions.js.map +1 -0
  32. package/dist/src/form/form-detector.d.ts +0 -36
  33. package/dist/src/form/form-detector.d.ts.map +1 -1
  34. package/dist/src/form/form-detector.js +11 -376
  35. package/dist/src/form/form-detector.js.map +1 -1
  36. package/dist/src/form/input-clustering.d.ts +15 -0
  37. package/dist/src/form/input-clustering.d.ts.map +1 -0
  38. package/dist/src/form/input-clustering.js +61 -0
  39. package/dist/src/form/input-clustering.js.map +1 -0
  40. package/dist/src/form/intent-inference.d.ts +28 -0
  41. package/dist/src/form/intent-inference.d.ts.map +1 -0
  42. package/dist/src/form/intent-inference.js +137 -0
  43. package/dist/src/form/intent-inference.js.map +1 -0
  44. package/dist/src/form/purpose-inference.d.ts +50 -0
  45. package/dist/src/form/purpose-inference.d.ts.map +1 -0
  46. package/dist/src/form/purpose-inference.js +313 -0
  47. package/dist/src/form/purpose-inference.js.map +1 -0
  48. package/dist/src/form/submit-detection.d.ts +36 -0
  49. package/dist/src/form/submit-detection.d.ts.map +1 -0
  50. package/dist/src/form/submit-detection.js +101 -0
  51. package/dist/src/form/submit-detection.js.map +1 -0
  52. package/dist/src/form/types.d.ts +2 -2
  53. package/dist/src/index.js +65 -48
  54. package/dist/src/index.js.map +1 -1
  55. package/dist/src/observation/observation-accumulator.d.ts +1 -1
  56. package/dist/src/observation/observation-accumulator.js +1 -1
  57. package/dist/src/observation/observer-script.d.ts +1 -1
  58. package/dist/src/observation/observer-script.d.ts.map +1 -1
  59. package/dist/src/observation/observer-script.js +129 -7
  60. package/dist/src/observation/observer-script.js.map +1 -1
  61. package/dist/src/query/disambiguation.d.ts +18 -0
  62. package/dist/src/query/disambiguation.d.ts.map +1 -0
  63. package/dist/src/query/disambiguation.js +123 -0
  64. package/dist/src/query/disambiguation.js.map +1 -0
  65. package/dist/src/query/fuzzy-match.d.ts +17 -0
  66. package/dist/src/query/fuzzy-match.d.ts.map +1 -0
  67. package/dist/src/query/fuzzy-match.js +34 -0
  68. package/dist/src/query/fuzzy-match.js.map +1 -0
  69. package/dist/src/query/index.d.ts +3 -0
  70. package/dist/src/query/index.d.ts.map +1 -1
  71. package/dist/src/query/index.js +6 -0
  72. package/dist/src/query/index.js.map +1 -1
  73. package/dist/src/query/query-engine.d.ts +0 -35
  74. package/dist/src/query/query-engine.d.ts.map +1 -1
  75. package/dist/src/query/query-engine.js +9 -309
  76. package/dist/src/query/query-engine.js.map +1 -1
  77. package/dist/src/query/scoring.d.ts +52 -0
  78. package/dist/src/query/scoring.d.ts.map +1 -0
  79. package/dist/src/query/scoring.js +162 -0
  80. package/dist/src/query/scoring.js.map +1 -0
  81. package/dist/src/server/mcp-server.d.ts.map +1 -1
  82. package/dist/src/server/mcp-server.js +29 -1
  83. package/dist/src/server/mcp-server.js.map +1 -1
  84. package/dist/src/snapshot/element-resolver.d.ts +50 -18
  85. package/dist/src/snapshot/element-resolver.d.ts.map +1 -1
  86. package/dist/src/snapshot/element-resolver.js +180 -101
  87. package/dist/src/snapshot/element-resolver.js.map +1 -1
  88. package/dist/src/snapshot/extractors/ax-extractor.d.ts +1 -1
  89. package/dist/src/snapshot/extractors/ax-extractor.d.ts.map +1 -1
  90. package/dist/src/snapshot/extractors/ax-extractor.js +4 -1
  91. package/dist/src/snapshot/extractors/ax-extractor.js.map +1 -1
  92. package/dist/src/snapshot/extractors/index.d.ts +1 -1
  93. package/dist/src/snapshot/extractors/index.d.ts.map +1 -1
  94. package/dist/src/snapshot/extractors/index.js +1 -1
  95. package/dist/src/snapshot/extractors/index.js.map +1 -1
  96. package/dist/src/snapshot/extractors/region-resolver.d.ts.map +1 -1
  97. package/dist/src/snapshot/extractors/region-resolver.js +8 -0
  98. package/dist/src/snapshot/extractors/region-resolver.js.map +1 -1
  99. package/dist/src/snapshot/extractors/types.d.ts +8 -0
  100. package/dist/src/snapshot/extractors/types.d.ts.map +1 -1
  101. package/dist/src/snapshot/extractors/types.js +16 -0
  102. package/dist/src/snapshot/extractors/types.js.map +1 -1
  103. package/dist/src/snapshot/frame-context.d.ts +68 -0
  104. package/dist/src/snapshot/frame-context.d.ts.map +1 -0
  105. package/dist/src/snapshot/frame-context.js +131 -0
  106. package/dist/src/snapshot/frame-context.js.map +1 -0
  107. package/dist/src/snapshot/heading-index.d.ts +28 -0
  108. package/dist/src/snapshot/heading-index.d.ts.map +1 -0
  109. package/dist/src/snapshot/heading-index.js +108 -0
  110. package/dist/src/snapshot/heading-index.js.map +1 -0
  111. package/dist/src/snapshot/index.d.ts +5 -3
  112. package/dist/src/snapshot/index.d.ts.map +1 -1
  113. package/dist/src/snapshot/index.js +3 -2
  114. package/dist/src/snapshot/index.js.map +1 -1
  115. package/dist/src/snapshot/kind-mapping.d.ts +30 -0
  116. package/dist/src/snapshot/kind-mapping.d.ts.map +1 -0
  117. package/dist/src/snapshot/kind-mapping.js +114 -0
  118. package/dist/src/snapshot/kind-mapping.js.map +1 -0
  119. package/dist/src/snapshot/node-filter.d.ts +31 -0
  120. package/dist/src/snapshot/node-filter.d.ts.map +1 -0
  121. package/dist/src/snapshot/node-filter.js +137 -0
  122. package/dist/src/snapshot/node-filter.js.map +1 -0
  123. package/dist/src/snapshot/node-synthesizer.d.ts +62 -0
  124. package/dist/src/snapshot/node-synthesizer.d.ts.map +1 -0
  125. package/dist/src/snapshot/node-synthesizer.js +185 -0
  126. package/dist/src/snapshot/node-synthesizer.js.map +1 -0
  127. package/dist/src/snapshot/snapshot-compiler.d.ts +2 -36
  128. package/dist/src/snapshot/snapshot-compiler.d.ts.map +1 -1
  129. package/dist/src/snapshot/snapshot-compiler.js +28 -520
  130. package/dist/src/snapshot/snapshot-compiler.js.map +1 -1
  131. package/dist/src/snapshot/snapshot.types.d.ts +7 -2
  132. package/dist/src/snapshot/snapshot.types.d.ts.map +1 -1
  133. package/dist/src/snapshot/snapshot.types.js +9 -0
  134. package/dist/src/snapshot/snapshot.types.js.map +1 -1
  135. package/dist/src/state/actionables-filter.d.ts +5 -0
  136. package/dist/src/state/actionables-filter.d.ts.map +1 -1
  137. package/dist/src/state/actionables-filter.js +22 -3
  138. package/dist/src/state/actionables-filter.js.map +1 -1
  139. package/dist/src/state/diff-engine.js +3 -3
  140. package/dist/src/state/diff-engine.js.map +1 -1
  141. package/dist/src/state/element-registry.d.ts.map +1 -1
  142. package/dist/src/state/element-registry.js +6 -4
  143. package/dist/src/state/element-registry.js.map +1 -1
  144. package/dist/src/state/hash-utils.d.ts +24 -0
  145. package/dist/src/state/hash-utils.d.ts.map +1 -0
  146. package/dist/src/state/hash-utils.js +41 -0
  147. package/dist/src/state/hash-utils.js.map +1 -0
  148. package/dist/src/state/layer-detector.d.ts.map +1 -1
  149. package/dist/src/state/layer-detector.js +15 -286
  150. package/dist/src/state/layer-detector.js.map +1 -1
  151. package/dist/src/state/layer-detectors/drawer-detector.d.ts +32 -0
  152. package/dist/src/state/layer-detectors/drawer-detector.d.ts.map +1 -0
  153. package/dist/src/state/layer-detectors/drawer-detector.js +96 -0
  154. package/dist/src/state/layer-detectors/drawer-detector.js.map +1 -0
  155. package/dist/src/state/layer-detectors/index.d.ts +10 -0
  156. package/dist/src/state/layer-detectors/index.d.ts.map +1 -0
  157. package/dist/src/state/layer-detectors/index.js +10 -0
  158. package/dist/src/state/layer-detectors/index.js.map +1 -0
  159. package/dist/src/state/layer-detectors/modal-detector.d.ts +30 -0
  160. package/dist/src/state/layer-detectors/modal-detector.d.ts.map +1 -0
  161. package/dist/src/state/layer-detectors/modal-detector.js +127 -0
  162. package/dist/src/state/layer-detectors/modal-detector.js.map +1 -0
  163. package/dist/src/state/layer-detectors/popover-detector.d.ts +20 -0
  164. package/dist/src/state/layer-detectors/popover-detector.d.ts.map +1 -0
  165. package/dist/src/state/layer-detectors/popover-detector.js +76 -0
  166. package/dist/src/state/layer-detectors/popover-detector.js.map +1 -0
  167. package/dist/src/state/layer-detectors/toast-detector.d.ts +24 -0
  168. package/dist/src/state/layer-detectors/toast-detector.d.ts.map +1 -0
  169. package/dist/src/state/layer-detectors/toast-detector.js +48 -0
  170. package/dist/src/state/layer-detectors/toast-detector.js.map +1 -0
  171. package/dist/src/state/region-mapping.d.ts +13 -0
  172. package/dist/src/state/region-mapping.d.ts.map +1 -0
  173. package/dist/src/state/region-mapping.js +25 -0
  174. package/dist/src/state/region-mapping.js.map +1 -0
  175. package/dist/src/state/state-manager.d.ts.map +1 -1
  176. package/dist/src/state/state-manager.js +8 -192
  177. package/dist/src/state/state-manager.js.map +1 -1
  178. package/dist/src/state/state-renderer.d.ts.map +1 -1
  179. package/dist/src/state/state-renderer.js +16 -2
  180. package/dist/src/state/state-renderer.js.map +1 -1
  181. package/dist/src/state/types.d.ts +8 -4
  182. package/dist/src/state/types.d.ts.map +1 -1
  183. package/dist/src/state/url-sanitization.d.ts +22 -0
  184. package/dist/src/state/url-sanitization.d.ts.map +1 -0
  185. package/dist/src/state/url-sanitization.js +60 -0
  186. package/dist/src/state/url-sanitization.js.map +1 -0
  187. package/dist/src/state/value-masking.d.ts +36 -0
  188. package/dist/src/state/value-masking.d.ts.map +1 -0
  189. package/dist/src/state/value-masking.js +86 -0
  190. package/dist/src/state/value-masking.js.map +1 -0
  191. package/dist/src/tools/action-context.d.ts +60 -0
  192. package/dist/src/tools/action-context.d.ts.map +1 -0
  193. package/dist/src/tools/action-context.js +78 -0
  194. package/dist/src/tools/action-context.js.map +1 -0
  195. package/dist/src/tools/action-stabilization.d.ts +48 -0
  196. package/dist/src/tools/action-stabilization.d.ts.map +1 -0
  197. package/dist/src/tools/action-stabilization.js +87 -0
  198. package/dist/src/tools/action-stabilization.js.map +1 -0
  199. package/dist/src/tools/browser-tools.d.ts +8 -146
  200. package/dist/src/tools/browser-tools.d.ts.map +1 -1
  201. package/dist/src/tools/browser-tools.js +13 -689
  202. package/dist/src/tools/browser-tools.js.map +1 -1
  203. package/dist/src/tools/canvas-tools.d.ts +32 -0
  204. package/dist/src/tools/canvas-tools.d.ts.map +1 -0
  205. package/dist/src/tools/canvas-tools.js +370 -0
  206. package/dist/src/tools/canvas-tools.js.map +1 -0
  207. package/dist/src/tools/effect-tracker.d.ts +25 -0
  208. package/dist/src/tools/effect-tracker.d.ts.map +1 -0
  209. package/dist/src/tools/effect-tracker.js +69 -0
  210. package/dist/src/tools/effect-tracker.js.map +1 -0
  211. package/dist/src/tools/execute-action.d.ts +1 -31
  212. package/dist/src/tools/execute-action.d.ts.map +1 -1
  213. package/dist/src/tools/execute-action.js +7 -276
  214. package/dist/src/tools/execute-action.js.map +1 -1
  215. package/dist/src/tools/form-tools.d.ts +4 -6
  216. package/dist/src/tools/form-tools.d.ts.map +1 -1
  217. package/dist/src/tools/form-tools.js +10 -42
  218. package/dist/src/tools/form-tools.js.map +1 -1
  219. package/dist/src/tools/index.d.ts +6 -4
  220. package/dist/src/tools/index.d.ts.map +1 -1
  221. package/dist/src/tools/index.js +21 -10
  222. package/dist/src/tools/index.js.map +1 -1
  223. package/dist/src/tools/interaction-tools.d.ts +46 -0
  224. package/dist/src/tools/interaction-tools.d.ts.map +1 -0
  225. package/dist/src/tools/interaction-tools.js +138 -0
  226. package/dist/src/tools/interaction-tools.js.map +1 -0
  227. package/dist/src/tools/navigation-detection.d.ts +31 -0
  228. package/dist/src/tools/navigation-detection.d.ts.map +1 -0
  229. package/dist/src/tools/navigation-detection.js +46 -0
  230. package/dist/src/tools/navigation-detection.js.map +1 -0
  231. package/dist/src/tools/navigation-tools.d.ts +57 -0
  232. package/dist/src/tools/navigation-tools.d.ts.map +1 -0
  233. package/dist/src/tools/navigation-tools.js +178 -0
  234. package/dist/src/tools/navigation-tools.js.map +1 -0
  235. package/dist/src/tools/observation-tools.d.ts +53 -0
  236. package/dist/src/tools/observation-tools.d.ts.map +1 -0
  237. package/dist/src/tools/observation-tools.js +247 -0
  238. package/dist/src/tools/observation-tools.js.map +1 -0
  239. package/dist/src/tools/response-builder.js +2 -2
  240. package/dist/src/tools/response-builder.js.map +1 -1
  241. package/dist/src/tools/stale-element-retry.d.ts +37 -0
  242. package/dist/src/tools/stale-element-retry.d.ts.map +1 -0
  243. package/dist/src/tools/stale-element-retry.js +68 -0
  244. package/dist/src/tools/stale-element-retry.js.map +1 -0
  245. package/dist/src/tools/state-manager-registry.d.ts +26 -0
  246. package/dist/src/tools/state-manager-registry.d.ts.map +1 -0
  247. package/dist/src/tools/state-manager-registry.js +39 -0
  248. package/dist/src/tools/state-manager-registry.js.map +1 -0
  249. package/dist/src/tools/tool-context.d.ts +53 -0
  250. package/dist/src/tools/tool-context.d.ts.map +1 -0
  251. package/dist/src/tools/tool-context.js +119 -0
  252. package/dist/src/tools/tool-context.js.map +1 -0
  253. package/dist/src/tools/tool-result.types.d.ts +16 -1
  254. package/dist/src/tools/tool-result.types.d.ts.map +1 -1
  255. package/dist/src/tools/tool-result.types.js +11 -0
  256. package/dist/src/tools/tool-result.types.js.map +1 -1
  257. package/dist/src/tools/tool-schemas.d.ts +358 -146
  258. package/dist/src/tools/tool-schemas.d.ts.map +1 -1
  259. package/dist/src/tools/tool-schemas.js +142 -19
  260. package/dist/src/tools/tool-schemas.js.map +1 -1
  261. package/dist/src/tools/viewport-tools.d.ts +36 -0
  262. package/dist/src/tools/viewport-tools.d.ts.map +1 -0
  263. package/dist/src/tools/viewport-tools.js +105 -0
  264. package/dist/src/tools/viewport-tools.js.map +1 -0
  265. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-context.d.ts","sourceRoot":"","sources":["../../../src/snapshot/frame-context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACzC,4EAA4E;IAC5E,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC3C;AAED,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AAKnE;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAIxD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,mBAAmB,GAAG,eAAe,CAiBpF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,eAAe,EAAE,eAAe,GAC/B,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,SAAS,CAGrC;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,mBAAmB,GAAG,aAAa,CAqBhF;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,mBAAmB,EAC9B,aAAa,EAAE,aAAa,GAC3B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAqCrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE;IACT,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;CACzB,EACD,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EAC5C,YAAY,UAAO,GAClB,IAAI,CAaN"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Frame and Shadow DOM Context Utilities
3
+ *
4
+ * Provides context-scoped ID maps, adjacency maps for shadow roots and
5
+ * iframe content documents, and DOM order indexing.
6
+ *
7
+ * @module snapshot/frame-context
8
+ */
9
+ const ROOT_CONTEXT = 'root';
10
+ const LIGHT_DOM_CONTEXT = 'light';
11
+ /**
12
+ * Build a context key based on iframe and shadow ancestry.
13
+ */
14
+ export function buildContextKey(node) {
15
+ const frameKey = node.framePath?.length ? node.framePath.join('/') : ROOT_CONTEXT;
16
+ const shadowKey = node.shadowPath?.length ? node.shadowPath.join('/') : LIGHT_DOM_CONTEXT;
17
+ return `${frameKey}|${shadowKey}`;
18
+ }
19
+ /**
20
+ * Build context-scoped ID maps to avoid cross-frame/shadow collisions.
21
+ */
22
+ export function buildIdMapsByContext(domResult) {
23
+ const idMaps = new Map();
24
+ for (const node of domResult.nodes.values()) {
25
+ const id = node.attributes?.id;
26
+ if (!id)
27
+ continue;
28
+ const contextKey = buildContextKey(node);
29
+ let map = idMaps.get(contextKey);
30
+ if (!map) {
31
+ map = new Map();
32
+ idMaps.set(contextKey, map);
33
+ }
34
+ map.set(id, node);
35
+ }
36
+ return idMaps;
37
+ }
38
+ /**
39
+ * Get the ID map scoped to a node's frame/shadow context.
40
+ */
41
+ export function getIdMapForNode(node, idMapsByContext) {
42
+ if (!node)
43
+ return undefined;
44
+ return idMapsByContext.get(buildContextKey(node));
45
+ }
46
+ /**
47
+ * Build adjacency maps for shadow roots and iframe content documents.
48
+ * Single O(n) pass through all nodes.
49
+ *
50
+ * @param domResult - DOM extraction result
51
+ * @returns Adjacency maps for shadow roots and content documents
52
+ */
53
+ export function buildAdjacencyMaps(domResult) {
54
+ const shadowRootsByHost = new Map();
55
+ const contentDocsByFrame = new Map();
56
+ for (const [nodeId, node] of domResult.nodes) {
57
+ if (node.parentId === undefined)
58
+ continue;
59
+ if (node.nodeName === '#document-fragment') {
60
+ // This is a shadow root - add to shadow host's children
61
+ const existing = shadowRootsByHost.get(node.parentId) ?? [];
62
+ existing.push(nodeId);
63
+ shadowRootsByHost.set(node.parentId, existing);
64
+ }
65
+ else if (node.nodeName === '#document') {
66
+ // This is a content document - add to iframe's children
67
+ const existing = contentDocsByFrame.get(node.parentId) ?? [];
68
+ existing.push(nodeId);
69
+ contentDocsByFrame.set(node.parentId, existing);
70
+ }
71
+ }
72
+ return { shadowRootsByHost, contentDocsByFrame };
73
+ }
74
+ /**
75
+ * Build DOM pre-order index by traversing the DOM tree.
76
+ * Also traverses into shadow roots and iframe content documents.
77
+ *
78
+ * @param domResult - DOM extraction result with nodes and rootId
79
+ * @param adjacencyMaps - Precomputed maps for shadow roots and content documents
80
+ * @returns Map of backendNodeId -> DOM order index
81
+ */
82
+ export function buildDomOrderIndex(domResult, adjacencyMaps) {
83
+ const orderIndex = new Map();
84
+ const shadowHostSet = new Set(domResult.shadowRoots);
85
+ let index = 0;
86
+ function traverse(nodeId) {
87
+ const node = domResult.nodes.get(nodeId);
88
+ if (!node)
89
+ return;
90
+ orderIndex.set(nodeId, index++);
91
+ // 1. Process light DOM children first (pre-order DFS)
92
+ if (node.childNodeIds) {
93
+ for (const childId of node.childNodeIds) {
94
+ traverse(childId);
95
+ }
96
+ }
97
+ // 2. If this node hosts a shadow root, traverse shadow content (O(1) lookup)
98
+ if (shadowHostSet.has(nodeId)) {
99
+ const shadowRoots = adjacencyMaps.shadowRootsByHost.get(nodeId) ?? [];
100
+ for (const shadowRootId of shadowRoots) {
101
+ traverse(shadowRootId);
102
+ }
103
+ }
104
+ // 3. If this node is an iframe, traverse content document (O(1) lookup)
105
+ if (node.frameId || node.nodeName.toUpperCase() === 'IFRAME') {
106
+ const contentDocs = adjacencyMaps.contentDocsByFrame.get(nodeId) ?? [];
107
+ for (const contentDocId of contentDocs) {
108
+ traverse(contentDocId);
109
+ }
110
+ }
111
+ }
112
+ traverse(domResult.rootId);
113
+ return orderIndex;
114
+ }
115
+ /**
116
+ * Recursively collect frame loaderIds from frame tree.
117
+ */
118
+ export function collectFrameLoaderIds(frameTree, frameLoaderIds, _isMainFrame = true) {
119
+ const frame = frameTree.frame;
120
+ frameLoaderIds.set(frame.id, {
121
+ frameId: frame.id,
122
+ loaderId: frame.loaderId,
123
+ isMainFrame: !frame.parentId,
124
+ });
125
+ if (frameTree.childFrames) {
126
+ for (const child of frameTree.childFrames) {
127
+ collectFrameLoaderIds(child, frameLoaderIds, false);
128
+ }
129
+ }
130
+ }
131
+ //# sourceMappingURL=frame-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-context.js","sourceRoot":"","sources":["../../../src/snapshot/frame-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Heading Index Builder
3
+ *
4
+ * Builds a heading context index mapping each backendNodeId to its
5
+ * heading context based on DOM order traversal.
6
+ *
7
+ * @module snapshot/heading-index
8
+ */
9
+ import type { DomExtractionResult, AxExtractionResult } from './extractors/index.js';
10
+ import type { AdjacencyMaps, IdMapsByContext } from './frame-context.js';
11
+ /**
12
+ * Build heading index mapping each backendNodeId to its heading context.
13
+ * Uses DOM order to determine the most recent preceding heading.
14
+ * Also traverses into shadow roots and iframe content documents.
15
+ *
16
+ * Heading context is isolated at iframe boundaries:
17
+ * - Heading from parent document does NOT propagate into iframe
18
+ * - Heading from iframe does NOT propagate back to parent document
19
+ * - Shadow DOM shares heading context with its host document
20
+ *
21
+ * @param domResult - DOM extraction result
22
+ * @param axResult - AX extraction result for heading names
23
+ * @param idMapsByContext - Context-scoped ID maps for aria-labelledby resolution
24
+ * @param adjacencyMaps - Precomputed maps for shadow roots and content documents
25
+ * @returns Map of backendNodeId -> heading context string
26
+ */
27
+ export declare function buildHeadingIndex(domResult: DomExtractionResult, axResult: AxExtractionResult | undefined, idMapsByContext: IdMapsByContext, adjacencyMaps: AdjacencyMaps): Map<number, string>;
28
+ //# sourceMappingURL=heading-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heading-index.d.ts","sourceRoot":"","sources":["../../../src/snapshot/heading-index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGrF,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGzE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,mBAAmB,EAC9B,QAAQ,EAAE,kBAAkB,GAAG,SAAS,EACxC,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE,aAAa,GAC3B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA2FrB"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Heading Index Builder
3
+ *
4
+ * Builds a heading context index mapping each backendNodeId to its
5
+ * heading context based on DOM order traversal.
6
+ *
7
+ * @module snapshot/heading-index
8
+ */
9
+ import { resolveLabel } from './extractors/index.js';
10
+ import { getTextContent } from '../lib/text-utils.js';
11
+ import { getIdMapForNode } from './frame-context.js';
12
+ /**
13
+ * Build heading index mapping each backendNodeId to its heading context.
14
+ * Uses DOM order to determine the most recent preceding heading.
15
+ * Also traverses into shadow roots and iframe content documents.
16
+ *
17
+ * Heading context is isolated at iframe boundaries:
18
+ * - Heading from parent document does NOT propagate into iframe
19
+ * - Heading from iframe does NOT propagate back to parent document
20
+ * - Shadow DOM shares heading context with its host document
21
+ *
22
+ * @param domResult - DOM extraction result
23
+ * @param axResult - AX extraction result for heading names
24
+ * @param idMapsByContext - Context-scoped ID maps for aria-labelledby resolution
25
+ * @param adjacencyMaps - Precomputed maps for shadow roots and content documents
26
+ * @returns Map of backendNodeId -> heading context string
27
+ */
28
+ export function buildHeadingIndex(domResult, axResult, idMapsByContext, adjacencyMaps) {
29
+ const headingIndex = new Map();
30
+ const shadowHostSet = new Set(domResult.shadowRoots);
31
+ // Helper to check if a node is a heading and resolve its name
32
+ function isHeading(backendNodeId) {
33
+ const domNode = domResult.nodes.get(backendNodeId);
34
+ const axNode = axResult?.nodes.get(backendNodeId);
35
+ // Check AX role first
36
+ const scopedIdMap = domNode ? getIdMapForNode(domNode, idMapsByContext) : undefined;
37
+ if (axNode?.role === 'heading') {
38
+ // Priority: AX name -> resolveLabel -> DOM text content
39
+ let name = axNode.name;
40
+ if (!name && domNode) {
41
+ const labelResult = resolveLabel(domNode, axNode, scopedIdMap);
42
+ if (labelResult.source !== 'none') {
43
+ name = labelResult.label;
44
+ }
45
+ }
46
+ name ??= getTextContent(backendNodeId, domResult.nodes);
47
+ return { isHeading: true, name };
48
+ }
49
+ // Check DOM tag (H1-H6)
50
+ if (domNode?.nodeName?.match(/^H[1-6]$/i)) {
51
+ // Priority: AX name -> resolveLabel -> DOM text content
52
+ let name = axNode?.name;
53
+ if (!name) {
54
+ const labelResult = resolveLabel(domNode, axNode, scopedIdMap);
55
+ if (labelResult.source !== 'none') {
56
+ name = labelResult.label;
57
+ }
58
+ }
59
+ name ??= getTextContent(backendNodeId, domResult.nodes);
60
+ return { isHeading: true, name };
61
+ }
62
+ return { isHeading: false };
63
+ }
64
+ // Traverse DOM in pre-order, passing and returning heading context
65
+ function traverse(nodeId, currentHeading) {
66
+ const node = domResult.nodes.get(nodeId);
67
+ if (!node)
68
+ return currentHeading;
69
+ // Check if this node is a heading
70
+ const headingInfo = isHeading(nodeId);
71
+ if (headingInfo.isHeading && headingInfo.name) {
72
+ currentHeading = headingInfo.name;
73
+ }
74
+ // Record the current heading context for this node
75
+ if (currentHeading) {
76
+ headingIndex.set(nodeId, currentHeading);
77
+ }
78
+ // 1. Process light DOM children first (pre-order DFS)
79
+ // Heading context propagates and updates through light DOM
80
+ if (node.childNodeIds) {
81
+ for (const childId of node.childNodeIds) {
82
+ currentHeading = traverse(childId, currentHeading) ?? currentHeading;
83
+ }
84
+ }
85
+ // 2. If this node hosts a shadow root, traverse shadow content (O(1) lookup)
86
+ // Shadow DOM shares heading context with host document (same logical document)
87
+ if (shadowHostSet.has(nodeId)) {
88
+ const shadowRoots = adjacencyMaps.shadowRootsByHost.get(nodeId) ?? [];
89
+ for (const shadowRootId of shadowRoots) {
90
+ currentHeading = traverse(shadowRootId, currentHeading) ?? currentHeading;
91
+ }
92
+ }
93
+ // 3. If this node is an iframe, traverse content document (O(1) lookup)
94
+ // IMPORTANT: Heading context resets at iframe boundary (separate document)
95
+ // - Pass undefined to reset context inside iframe
96
+ // - Discard returned heading (iframe headings don't affect parent)
97
+ if (node.frameId || node.nodeName.toUpperCase() === 'IFRAME') {
98
+ const contentDocs = adjacencyMaps.contentDocsByFrame.get(nodeId) ?? [];
99
+ for (const contentDocId of contentDocs) {
100
+ traverse(contentDocId, undefined);
101
+ }
102
+ }
103
+ return currentHeading;
104
+ }
105
+ traverse(domResult.rootId, undefined);
106
+ return headingIndex;
107
+ }
108
+ //# sourceMappingURL=heading-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heading-index.js","sourceRoot":"","sources":["../../../src/snapshot/heading-index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAA8B,EAC9B,QAAwC,EACxC,eAAgC,EAChC,aAA4B;IAE5B,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC/C,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAErD,8DAA8D;IAC9D,SAAS,SAAS,CAAC,aAAqB;QACtC,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAElD,sBAAsB;QACtB,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEpF,IAAI,MAAM,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,wDAAwD;YACxD,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACvB,IAAI,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC;gBACrB,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;gBAC/D,IAAI,WAAW,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;oBAClC,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC;gBAC3B,CAAC;YACH,CAAC;YACD,IAAI,KAAK,cAAc,CAAC,aAAa,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;YACxD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACnC,CAAC;QAED,wBAAwB;QACxB,IAAI,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;YAC1C,wDAAwD;YACxD,IAAI,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC;YACxB,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;gBAC/D,IAAI,WAAW,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;oBAClC,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC;gBAC3B,CAAC;YACH,CAAC;YACD,IAAI,KAAK,cAAc,CAAC,aAAa,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;YACxD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACnC,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED,mEAAmE;IACnE,SAAS,QAAQ,CAAC,MAAc,EAAE,cAAkC;QAClE,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI;YAAE,OAAO,cAAc,CAAC;QAEjC,kCAAkC;QAClC,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,WAAW,CAAC,SAAS,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC;YAC9C,cAAc,GAAG,WAAW,CAAC,IAAI,CAAC;QACpC,CAAC;QAED,mDAAmD;QACnD,IAAI,cAAc,EAAE,CAAC;YACnB,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC3C,CAAC;QAED,sDAAsD;QACtD,2DAA2D;QAC3D,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACxC,cAAc,GAAG,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,cAAc,CAAC;YACvE,CAAC;QACH,CAAC;QAED,6EAA6E;QAC7E,+EAA+E;QAC/E,IAAI,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,WAAW,GAAG,aAAa,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACtE,KAAK,MAAM,YAAY,IAAI,WAAW,EAAE,CAAC;gBACvC,cAAc,GAAG,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,cAAc,CAAC;YAC5E,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,2EAA2E;QAC3E,kDAAkD;QAClD,mEAAmE;QACnE,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC7D,MAAM,WAAW,GAAG,aAAa,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACvE,KAAK,MAAM,YAAY,IAAI,WAAW,EAAE,CAAC;gBACvC,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,OAAO,YAAY,CAAC;AACtB,CAAC"}
@@ -6,9 +6,11 @@
6
6
  * @module snapshot
7
7
  */
8
8
  export type { BaseSnapshot, Viewport, SnapshotMeta, ReadableNode, NodeKind, SemanticRegion, NodeLocation, NodeLayout, BBox, BoundingBox, ScreenZone, NodeState, NodeLocators, NodeAttributes, SnapshotOptions, SnapshotResult, } from './snapshot.types.js';
9
- export { isInteractiveNode, isReadableNode, isStructuralNode } from './snapshot.types.js';
9
+ export { isInteractiveNode, isReadableNode, isStructuralNode, isLiveRegionNode, } from './snapshot.types.js';
10
10
  export { SnapshotStore, type SnapshotEntry, type SnapshotStoreOptions, type SnapshotStoreStats, } from './snapshot-store.js';
11
- export { clickByBackendNodeId, typeByBackendNodeId, pressKey, selectOption, hoverByBackendNodeId, scrollIntoView, scrollPage, clearFocusedText, MODIFIER_ALT, MODIFIER_CTRL, MODIFIER_META, MODIFIER_SHIFT, } from './element-resolver.js';
12
- export { SnapshotCompiler, compileSnapshot, type CompileOptions } from './snapshot-compiler.js';
11
+ export { clickByBackendNodeId, clickAtCoordinates, clickAtElementOffset, getElementTopLeft, dragBetweenCoordinates, dispatchWheelEvent, typeByBackendNodeId, pressKey, selectOption, hoverByBackendNodeId, scrollIntoView, scrollPage, clearFocusedText, MODIFIER_ALT, MODIFIER_CTRL, MODIFIER_META, MODIFIER_SHIFT, } from './element-resolver.js';
12
+ export { SnapshotCompiler, compileSnapshot } from './snapshot-compiler.js';
13
+ export type { CompileOptions } from './kind-mapping.js';
14
+ export { sliceWithOverlayPriority } from './node-filter.js';
13
15
  export * from './extractors/index.js';
14
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/snapshot/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EACV,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,UAAU,EACV,IAAI,EACJ,WAAW,EACX,UAAU,EACV,SAAS,EACT,YAAY,EACZ,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG1F,OAAO,EACL,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGhG,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/snapshot/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EACV,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,UAAU,EACV,IAAI,EACJ,WAAW,EACX,UAAU,EACV,SAAS,EACT,YAAY,EACZ,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC3E,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAG5D,cAAc,uBAAuB,CAAC"}
@@ -6,13 +6,14 @@
6
6
  * @module snapshot
7
7
  */
8
8
  // Type guards
9
- export { isInteractiveNode, isReadableNode, isStructuralNode } from './snapshot.types.js';
9
+ export { isInteractiveNode, isReadableNode, isStructuralNode, isLiveRegionNode, } from './snapshot.types.js';
10
10
  // Store
11
11
  export { SnapshotStore, } from './snapshot-store.js';
12
12
  // Element resolver - CDP input functions
13
- export { clickByBackendNodeId, typeByBackendNodeId, pressKey, selectOption, hoverByBackendNodeId, scrollIntoView, scrollPage, clearFocusedText, MODIFIER_ALT, MODIFIER_CTRL, MODIFIER_META, MODIFIER_SHIFT, } from './element-resolver.js';
13
+ export { clickByBackendNodeId, clickAtCoordinates, clickAtElementOffset, getElementTopLeft, dragBetweenCoordinates, dispatchWheelEvent, typeByBackendNodeId, pressKey, selectOption, hoverByBackendNodeId, scrollIntoView, scrollPage, clearFocusedText, MODIFIER_ALT, MODIFIER_CTRL, MODIFIER_META, MODIFIER_SHIFT, } from './element-resolver.js';
14
14
  // Snapshot compiler
15
15
  export { SnapshotCompiler, compileSnapshot } from './snapshot-compiler.js';
16
+ export { sliceWithOverlayPriority } from './node-filter.js';
16
17
  // Extractors (advanced usage)
17
18
  export * from './extractors/index.js';
18
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/snapshot/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,cAAc;AACd,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE1F,QAAQ;AACR,OAAO,EACL,aAAa,GAId,MAAM,qBAAqB,CAAC;AAE7B,yCAAyC;AACzC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,oBAAoB;AACpB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAuB,MAAM,wBAAwB,CAAC;AAEhG,8BAA8B;AAC9B,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/snapshot/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,cAAc;AACd,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,QAAQ;AACR,OAAO,EACL,aAAa,GAId,MAAM,qBAAqB,CAAC;AAE7B,yCAAyC;AACzC,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,oBAAoB;AACpB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,8BAA8B;AAC9B,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Kind Mapping
3
+ *
4
+ * Maps AX roles and HTML tags to NodeKind values.
5
+ *
6
+ * @module snapshot/kind-mapping
7
+ */
8
+ import type { NodeKind, SnapshotOptions } from './snapshot.types.js';
9
+ /**
10
+ * Snapshot compiler options
11
+ */
12
+ export interface CompileOptions extends Partial<SnapshotOptions> {
13
+ /** Include readable content nodes (headings, paragraphs). Default: true */
14
+ includeReadable?: boolean;
15
+ /** Extract bounding boxes and layout info. Default: true */
16
+ includeLayout?: boolean;
17
+ }
18
+ /**
19
+ * Default compile options
20
+ */
21
+ export declare const DEFAULT_OPTIONS: Required<CompileOptions>;
22
+ /**
23
+ * Map AX role to NodeKind.
24
+ */
25
+ export declare function mapRoleToKind(role: string | undefined): NodeKind | undefined;
26
+ /**
27
+ * Get NodeKind from HTML tag name.
28
+ */
29
+ export declare function getKindFromTag(tagName: string): NodeKind | undefined;
30
+ //# sourceMappingURL=kind-mapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kind-mapping.d.ts","sourceRoot":"","sources":["../../../src/snapshot/kind-mapping.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,OAAO,CAAC,eAAe,CAAC;IAC9D,2EAA2E;IAC3E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4DAA4D;IAC5D,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,cAAc,CAQpD,CAAC;AAoFF;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAG5E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAEpE"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Kind Mapping
3
+ *
4
+ * Maps AX roles and HTML tags to NodeKind values.
5
+ *
6
+ * @module snapshot/kind-mapping
7
+ */
8
+ /**
9
+ * Default compile options
10
+ */
11
+ export const DEFAULT_OPTIONS = {
12
+ include_hidden: false,
13
+ max_nodes: 2000,
14
+ timeout: 30000,
15
+ redact_sensitive: true,
16
+ include_values: true, // Enable value extraction with password redaction
17
+ includeReadable: true,
18
+ includeLayout: true,
19
+ };
20
+ /** AX role → NodeKind lookup (hoisted to avoid per-call allocation) */
21
+ const ROLE_TO_KIND = {
22
+ // Interactive
23
+ button: 'button',
24
+ link: 'link',
25
+ textbox: 'input',
26
+ searchbox: 'input',
27
+ combobox: 'combobox',
28
+ listbox: 'select',
29
+ checkbox: 'checkbox',
30
+ radio: 'radio',
31
+ switch: 'switch',
32
+ slider: 'slider',
33
+ spinbutton: 'slider',
34
+ tab: 'tab',
35
+ menuitem: 'menuitem',
36
+ menuitemcheckbox: 'menuitem',
37
+ menuitemradio: 'menuitem',
38
+ option: 'menuitem',
39
+ // Readable
40
+ heading: 'heading',
41
+ paragraph: 'paragraph',
42
+ text: 'text',
43
+ statictext: 'text',
44
+ list: 'list',
45
+ listitem: 'listitem',
46
+ tree: 'list',
47
+ treeitem: 'listitem',
48
+ image: 'image',
49
+ img: 'image',
50
+ figure: 'image',
51
+ canvas: 'canvas',
52
+ table: 'table',
53
+ grid: 'table',
54
+ treegrid: 'table',
55
+ // Structural
56
+ form: 'form',
57
+ dialog: 'dialog',
58
+ alertdialog: 'dialog',
59
+ navigation: 'navigation',
60
+ region: 'section',
61
+ article: 'section',
62
+ main: 'section',
63
+ banner: 'section',
64
+ complementary: 'section',
65
+ contentinfo: 'section',
66
+ // Live region / ephemeral feedback
67
+ alert: 'alert',
68
+ status: 'status',
69
+ log: 'log',
70
+ marquee: 'log',
71
+ timer: 'timer',
72
+ tooltip: 'tooltip',
73
+ progressbar: 'progressbar',
74
+ };
75
+ /** HTML tag → NodeKind lookup (hoisted to avoid per-call allocation) */
76
+ const TAG_TO_KIND = {
77
+ BUTTON: 'button',
78
+ A: 'link',
79
+ INPUT: 'input',
80
+ TEXTAREA: 'textarea',
81
+ SELECT: 'select',
82
+ H1: 'heading',
83
+ H2: 'heading',
84
+ H3: 'heading',
85
+ H4: 'heading',
86
+ H5: 'heading',
87
+ H6: 'heading',
88
+ P: 'paragraph',
89
+ IMG: 'image',
90
+ TABLE: 'table',
91
+ UL: 'list',
92
+ OL: 'list',
93
+ LI: 'listitem',
94
+ FORM: 'form',
95
+ DIALOG: 'dialog',
96
+ NAV: 'navigation',
97
+ OPTION: 'menuitem',
98
+ CANVAS: 'canvas',
99
+ };
100
+ /**
101
+ * Map AX role to NodeKind.
102
+ */
103
+ export function mapRoleToKind(role) {
104
+ if (!role)
105
+ return undefined;
106
+ return ROLE_TO_KIND[role.toLowerCase()];
107
+ }
108
+ /**
109
+ * Get NodeKind from HTML tag name.
110
+ */
111
+ export function getKindFromTag(tagName) {
112
+ return TAG_TO_KIND[tagName.toUpperCase()];
113
+ }
114
+ //# sourceMappingURL=kind-mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kind-mapping.js","sourceRoot":"","sources":["../../../src/snapshot/kind-mapping.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Node Filtering
3
+ *
4
+ * Filters noise nodes and slices to budget while preserving overlay content.
5
+ *
6
+ * @module snapshot/node-filter
7
+ */
8
+ import type { ReadableNode } from './snapshot.types.js';
9
+ import type { RawNodeData, RawDomNode, RawAxNode } from './extractors/index.js';
10
+ /**
11
+ * Filter out noise nodes to reduce snapshot size.
12
+ *
13
+ * Filters:
14
+ * 1. Empty list/listitem containers with no semantic name AND no interactive descendants
15
+ * 2. StaticText/text nodes that mirror their parent's label exactly
16
+ */
17
+ export declare function filterNoiseNodes(nodes: ReadableNode[], domTree: Map<number, RawDomNode>, axTree: Map<number, RawAxNode>): ReadableNode[];
18
+ /**
19
+ * Slice nodes to max_nodes budget while preserving high z-index overlay content.
20
+ *
21
+ * Portal-rendered content (dropdowns, popovers, modals) appears at the end of
22
+ * DOM order. On heavy pages, a naive slice truncates it.
23
+ *
24
+ * Strategy:
25
+ * 1. Partition nodes into overlay (z-index > threshold) and main
26
+ * 2. Take all overlay nodes (up to 30% of budget)
27
+ * 3. Fill remaining budget with main nodes (DOM order)
28
+ * 4. Re-sort by original DOM order
29
+ */
30
+ export declare function sliceWithOverlayPriority(nodes: RawNodeData[], maxNodes: number): RawNodeData[];
31
+ //# sourceMappingURL=node-filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-filter.d.ts","sourceRoot":"","sources":["../../../src/snapshot/node-filter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGhF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAChC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,GAC7B,YAAY,EAAE,CAkFhB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CA2C9F"}