@tontoko/fast-playwright-mcp 0.0.4

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 (107) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +1047 -0
  3. package/cli.js +18 -0
  4. package/config.d.ts +124 -0
  5. package/index.d.ts +25 -0
  6. package/index.js +18 -0
  7. package/lib/actions.d.js +0 -0
  8. package/lib/batch/batch-executor.js +137 -0
  9. package/lib/browser-context-factory.js +252 -0
  10. package/lib/browser-server-backend.js +139 -0
  11. package/lib/config/constants.js +80 -0
  12. package/lib/config.js +405 -0
  13. package/lib/context.js +274 -0
  14. package/lib/diagnostics/common/diagnostic-base.js +63 -0
  15. package/lib/diagnostics/common/error-enrichment-utils.js +212 -0
  16. package/lib/diagnostics/common/index.js +56 -0
  17. package/lib/diagnostics/common/initialization-manager.js +210 -0
  18. package/lib/diagnostics/common/performance-tracker.js +132 -0
  19. package/lib/diagnostics/diagnostic-error.js +140 -0
  20. package/lib/diagnostics/diagnostic-level.js +123 -0
  21. package/lib/diagnostics/diagnostic-thresholds.js +347 -0
  22. package/lib/diagnostics/element-discovery.js +441 -0
  23. package/lib/diagnostics/enhanced-error-handler.js +376 -0
  24. package/lib/diagnostics/error-enrichment.js +157 -0
  25. package/lib/diagnostics/frame-reference-manager.js +179 -0
  26. package/lib/diagnostics/page-analyzer.js +639 -0
  27. package/lib/diagnostics/parallel-page-analyzer.js +129 -0
  28. package/lib/diagnostics/resource-manager.js +134 -0
  29. package/lib/diagnostics/smart-config.js +482 -0
  30. package/lib/diagnostics/smart-handle.js +118 -0
  31. package/lib/diagnostics/unified-system.js +717 -0
  32. package/lib/extension/cdp-relay.js +486 -0
  33. package/lib/extension/extension-context-factory.js +74 -0
  34. package/lib/extension/main.js +41 -0
  35. package/lib/file-utils.js +42 -0
  36. package/lib/generate-keys.js +75 -0
  37. package/lib/http-server.js +50 -0
  38. package/lib/in-process-client.js +64 -0
  39. package/lib/index.js +48 -0
  40. package/lib/javascript.js +90 -0
  41. package/lib/log.js +33 -0
  42. package/lib/loop/loop-claude.js +247 -0
  43. package/lib/loop/loop-open-ai.js +222 -0
  44. package/lib/loop/loop.js +174 -0
  45. package/lib/loop/main.js +46 -0
  46. package/lib/loopTools/context.js +76 -0
  47. package/lib/loopTools/main.js +65 -0
  48. package/lib/loopTools/perform.js +40 -0
  49. package/lib/loopTools/snapshot.js +37 -0
  50. package/lib/loopTools/tool.js +26 -0
  51. package/lib/manual-promise.js +125 -0
  52. package/lib/mcp/in-process-transport.js +91 -0
  53. package/lib/mcp/proxy-backend.js +127 -0
  54. package/lib/mcp/server.js +123 -0
  55. package/lib/mcp/transport.js +159 -0
  56. package/lib/package.js +28 -0
  57. package/lib/program.js +82 -0
  58. package/lib/response.js +493 -0
  59. package/lib/schemas/expectation.js +152 -0
  60. package/lib/session-log.js +210 -0
  61. package/lib/tab.js +417 -0
  62. package/lib/tools/base-tool-handler.js +141 -0
  63. package/lib/tools/batch-execute.js +150 -0
  64. package/lib/tools/common.js +65 -0
  65. package/lib/tools/console.js +60 -0
  66. package/lib/tools/diagnose/diagnose-analysis-runner.js +101 -0
  67. package/lib/tools/diagnose/diagnose-config-handler.js +130 -0
  68. package/lib/tools/diagnose/diagnose-report-builder.js +394 -0
  69. package/lib/tools/diagnose.js +147 -0
  70. package/lib/tools/dialogs.js +57 -0
  71. package/lib/tools/evaluate.js +67 -0
  72. package/lib/tools/files.js +53 -0
  73. package/lib/tools/find-elements.js +307 -0
  74. package/lib/tools/install.js +60 -0
  75. package/lib/tools/keyboard.js +93 -0
  76. package/lib/tools/mouse.js +110 -0
  77. package/lib/tools/navigate.js +82 -0
  78. package/lib/tools/network.js +50 -0
  79. package/lib/tools/pdf.js +46 -0
  80. package/lib/tools/screenshot.js +113 -0
  81. package/lib/tools/snapshot.js +158 -0
  82. package/lib/tools/tabs.js +97 -0
  83. package/lib/tools/tool.js +47 -0
  84. package/lib/tools/utils.js +131 -0
  85. package/lib/tools/wait.js +64 -0
  86. package/lib/tools.js +65 -0
  87. package/lib/types/batch.js +47 -0
  88. package/lib/types/diff.js +0 -0
  89. package/lib/types/performance.js +0 -0
  90. package/lib/types/threshold-base.js +0 -0
  91. package/lib/utils/array-utils.js +44 -0
  92. package/lib/utils/code-deduplication-utils.js +141 -0
  93. package/lib/utils/common-formatters.js +252 -0
  94. package/lib/utils/console-filter.js +64 -0
  95. package/lib/utils/diagnostic-report-utils.js +178 -0
  96. package/lib/utils/diff-formatter.js +126 -0
  97. package/lib/utils/disposable-manager.js +135 -0
  98. package/lib/utils/error-handler-middleware.js +77 -0
  99. package/lib/utils/image-processor.js +137 -0
  100. package/lib/utils/index.js +92 -0
  101. package/lib/utils/report-builder.js +189 -0
  102. package/lib/utils/request-logger.js +82 -0
  103. package/lib/utils/response-diff-detector.js +150 -0
  104. package/lib/utils/section-builder.js +62 -0
  105. package/lib/utils/tool-patterns.js +153 -0
  106. package/lib/utils.js +46 -0
  107. package/package.json +77 -0
@@ -0,0 +1,441 @@
1
+ import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
+
20
+ // src/diagnostics/element-discovery.ts
21
+ import debug from "debug";
22
+ import { DiagnosticBase } from "./common/diagnostic-base.js";
23
+ import { safeDispose } from "./common/error-enrichment-utils.js";
24
+ import { SmartHandleBatch } from "./smart-handle.js";
25
+ var elementDiscoveryDebug = debug("pw:mcp:element-discovery");
26
+
27
+ class ElementDiscovery extends DiagnosticBase {
28
+ smartHandleBatch;
29
+ maxBatchSize = 100;
30
+ constructor(page) {
31
+ super(page, "ElementDiscovery");
32
+ this.smartHandleBatch = new SmartHandleBatch;
33
+ }
34
+ async performDispose() {
35
+ await safeDispose(this.smartHandleBatch, "SmartHandleBatch", "dispose");
36
+ }
37
+ async safeDispose(element, operation) {
38
+ await safeDispose(element, "ElementHandle", operation);
39
+ }
40
+ async safeDisposePublic(element, operation) {
41
+ if ("dispose" in element) {
42
+ await safeDispose(element, "Element", operation);
43
+ } else {
44
+ await safeDispose(element, "ElementHandle", operation);
45
+ }
46
+ }
47
+ async findAlternativeElements(options) {
48
+ this.getPage();
49
+ const { searchCriteria, maxResults = 10 } = options;
50
+ const alternatives = [];
51
+ const effectiveMaxResults = Math.min(maxResults, this.maxBatchSize);
52
+ try {
53
+ if (searchCriteria.text) {
54
+ const textMatches = await this.findByText(searchCriteria.text, effectiveMaxResults);
55
+ alternatives.push(...textMatches);
56
+ }
57
+ if (searchCriteria.role) {
58
+ const roleMatches = await this.findByRole(searchCriteria.role, effectiveMaxResults);
59
+ alternatives.push(...roleMatches);
60
+ }
61
+ if (searchCriteria.tagName) {
62
+ const tagMatches = await this.findByTagName(searchCriteria.tagName, effectiveMaxResults);
63
+ alternatives.push(...tagMatches);
64
+ }
65
+ if (searchCriteria.attributes) {
66
+ const attributeMatches = await this.findByAttributes(searchCriteria.attributes, effectiveMaxResults);
67
+ alternatives.push(...attributeMatches);
68
+ }
69
+ const uniqueAlternatives = this.deduplicateAndSort(alternatives);
70
+ return uniqueAlternatives.slice(0, effectiveMaxResults);
71
+ } catch (error) {
72
+ await safeDispose(this.smartHandleBatch, "SmartHandleBatch", "findAlternativeElements");
73
+ throw error;
74
+ }
75
+ }
76
+ async findByText(text, maxResults) {
77
+ const page = this.getPage();
78
+ const strategies = this.getTextSearchStrategies(text);
79
+ const alternatives = [];
80
+ await this.processTextSearchStrategies(page, strategies, text, alternatives, maxResults);
81
+ return alternatives;
82
+ }
83
+ async processTextSearchStrategies(page, strategies, text, alternatives, maxResults) {
84
+ let totalFound = 0;
85
+ const processStrategiesSequentially = async (index) => {
86
+ if (index >= strategies.length || totalFound >= maxResults) {
87
+ return;
88
+ }
89
+ const selector = strategies[index];
90
+ totalFound = await this.processTextStrategy(page, selector, text, alternatives, totalFound, maxResults);
91
+ await processStrategiesSequentially(index + 1);
92
+ };
93
+ await processStrategiesSequentially(0);
94
+ }
95
+ getTextSearchStrategies(text) {
96
+ return [
97
+ `text=${text}`,
98
+ `text*=${text}`,
99
+ `[value="${text}"]`,
100
+ `[placeholder="${text}"]`,
101
+ `[aria-label="${text}"]`
102
+ ];
103
+ }
104
+ async processTextStrategy(page, selector, text, alternatives, totalFound, maxResults) {
105
+ try {
106
+ const elements = await page.$$(selector);
107
+ return await this.processTextElements(elements, text, alternatives, totalFound, maxResults);
108
+ } catch {
109
+ return totalFound;
110
+ }
111
+ }
112
+ async processTextElements(elements, text, alternatives, totalFound, maxResults) {
113
+ const result = await elements.reduce(async (previousPromise, element) => {
114
+ const currentFound = await previousPromise;
115
+ if (currentFound >= maxResults) {
116
+ await this.safeDispose(element, `findByText-excess-${currentFound}`);
117
+ return currentFound;
118
+ }
119
+ const elementProcessed = await this.processTextElement(element, text, alternatives, currentFound);
120
+ return elementProcessed ? currentFound + 1 : currentFound;
121
+ }, Promise.resolve(totalFound));
122
+ return result;
123
+ }
124
+ async processTextElement(element, text, alternatives, totalFound) {
125
+ try {
126
+ const elementText = await this.extractElementText(element);
127
+ const confidence = this.calculateTextSimilarity(text, elementText);
128
+ return await this.handleTextMatchResult(element, elementText, confidence, alternatives, totalFound);
129
+ } catch (elementError) {
130
+ elementDiscoveryDebug("Element processing failed:", elementError);
131
+ await this.safeDispose(element, `findByText-element-${totalFound}`);
132
+ return false;
133
+ }
134
+ }
135
+ async extractElementText(element) {
136
+ const [textContent, value, placeholder, ariaLabel] = await Promise.all([
137
+ element.textContent().then((content) => content ?? ""),
138
+ element.getAttribute("value").then((attr) => attr ?? ""),
139
+ element.getAttribute("placeholder").then((attr) => attr ?? ""),
140
+ element.getAttribute("aria-label").then((attr) => attr ?? "")
141
+ ]);
142
+ return [textContent, value, placeholder, ariaLabel].join(" ").trim();
143
+ }
144
+ async handleTextMatchResult(element, elementText, confidence, alternatives, totalFound) {
145
+ if (confidence > 0.3) {
146
+ const smartElement = this.smartHandleBatch.add(element);
147
+ alternatives.push({
148
+ selector: await this.generateSelector(element),
149
+ confidence,
150
+ reason: `text match: "${elementText.substring(0, 50).trim()}"`,
151
+ element: smartElement,
152
+ elementId: `text_${totalFound}`
153
+ });
154
+ return true;
155
+ }
156
+ await this.safeDispose(element, `findByText-threshold-${totalFound}`);
157
+ return false;
158
+ }
159
+ async findByRole(role, maxResults) {
160
+ const page = this.getPage();
161
+ const alternatives = [];
162
+ try {
163
+ const elements = await page.$$(`[role="${role}"]`);
164
+ const totalFound = await elements.reduce(async (previousPromise, element) => {
165
+ const currentFound = await previousPromise;
166
+ if (currentFound >= maxResults) {
167
+ await this.safeDispose(element, `findByRole-excess-${currentFound}`);
168
+ return currentFound;
169
+ }
170
+ try {
171
+ const confidence = 0.7;
172
+ const smartElement = this.smartHandleBatch.add(element);
173
+ alternatives.push({
174
+ selector: await this.generateSelector(element),
175
+ confidence,
176
+ reason: `role match: "${role}"`,
177
+ element: smartElement,
178
+ elementId: `role_${currentFound}`
179
+ });
180
+ return currentFound + 1;
181
+ } catch (elementError) {
182
+ elementDiscoveryDebug("Element role processing failed:", elementError);
183
+ await this.safeDispose(element, `findByRole-element-${currentFound}`);
184
+ return currentFound;
185
+ }
186
+ }, Promise.resolve(0));
187
+ if (totalFound < maxResults) {
188
+ const implicitRoleElements = await this.findImplicitRoleElements(role, maxResults - totalFound);
189
+ alternatives.push(...implicitRoleElements);
190
+ }
191
+ } catch {}
192
+ return alternatives;
193
+ }
194
+ async findByTagName(tagName, maxResults) {
195
+ const page = this.getPage();
196
+ const alternatives = [];
197
+ try {
198
+ const elements = await page.$$(tagName);
199
+ await elements.reduce(async (previousPromise, element) => {
200
+ const currentFound = await previousPromise;
201
+ if (currentFound >= maxResults) {
202
+ await this.safeDispose(element, `findByTagName-excess-${currentFound}`);
203
+ return currentFound;
204
+ }
205
+ try {
206
+ const confidence = 0.5;
207
+ const smartElement = this.smartHandleBatch.add(element);
208
+ alternatives.push({
209
+ selector: await this.generateSelector(element),
210
+ confidence,
211
+ reason: `tag name match: "${tagName}"`,
212
+ element: smartElement,
213
+ elementId: `tag_${currentFound}`
214
+ });
215
+ return currentFound + 1;
216
+ } catch (elementError) {
217
+ elementDiscoveryDebug("Element tag processing failed:", elementError);
218
+ await this.safeDispose(element, `findByTagName-element-${currentFound}`);
219
+ return currentFound;
220
+ }
221
+ }, Promise.resolve(0));
222
+ } catch {}
223
+ return alternatives;
224
+ }
225
+ async findByAttributes(attributes, maxResults) {
226
+ const alternatives = [];
227
+ await this.processAttributeEntries(Object.entries(attributes), alternatives, maxResults);
228
+ return alternatives;
229
+ }
230
+ async processAttributeEntries(attributeEntries, alternatives, maxResults) {
231
+ let totalFound = 0;
232
+ const processEntriesSequentially = async (index) => {
233
+ if (index >= attributeEntries.length || totalFound >= maxResults) {
234
+ return;
235
+ }
236
+ const [attrName, attrValue] = attributeEntries[index];
237
+ totalFound = await this.processAttributeEntry(attrName, attrValue, alternatives, totalFound, maxResults);
238
+ await processEntriesSequentially(index + 1);
239
+ };
240
+ await processEntriesSequentially(0);
241
+ }
242
+ async processAttributeEntry(attrName, attrValue, alternatives, totalFound, maxResults) {
243
+ const page = this.getPage();
244
+ try {
245
+ const elements = await page.$$(`[${attrName}="${attrValue}"]`);
246
+ return await this.processAttributeElements(elements, attrName, attrValue, alternatives, totalFound, maxResults);
247
+ } catch {
248
+ return totalFound;
249
+ }
250
+ }
251
+ async processAttributeElements(elements, attrName, attrValue, alternatives, totalFound, maxResults) {
252
+ let currentFound = totalFound;
253
+ const processElementsSequentially = async (index) => {
254
+ if (index >= elements.length) {
255
+ return;
256
+ }
257
+ const element = elements[index];
258
+ if (currentFound >= maxResults) {
259
+ await this.safeDispose(element, `findByAttributes-excess-${currentFound}`);
260
+ return processElementsSequentially(index + 1);
261
+ }
262
+ const processResult = await this.processAttributeElement(element, attrName, attrValue, alternatives, currentFound);
263
+ if (processResult) {
264
+ currentFound++;
265
+ }
266
+ await processElementsSequentially(index + 1);
267
+ };
268
+ await processElementsSequentially(0);
269
+ return currentFound;
270
+ }
271
+ async processAttributeElement(element, attrName, attrValue, alternatives, currentFound) {
272
+ try {
273
+ const smartElement = this.smartHandleBatch.add(element);
274
+ alternatives.push({
275
+ selector: await this.generateSelector(element),
276
+ confidence: 0.9,
277
+ reason: `attribute match: ${attrName}="${attrValue}"`,
278
+ element: smartElement,
279
+ elementId: `attr_${currentFound}`
280
+ });
281
+ return true;
282
+ } catch (elementError) {
283
+ elementDiscoveryDebug("Element attribute processing failed:", elementError);
284
+ await this.safeDispose(element, `findByAttributes-element-${currentFound}`);
285
+ return false;
286
+ }
287
+ }
288
+ async findImplicitRoleElements(role, maxResults) {
289
+ const roleTagMapping = {
290
+ button: ["button", 'input[type="button"]', 'input[type="submit"]'],
291
+ textbox: ['input[type="text"]', 'input[type="email"]', "textarea"],
292
+ link: ["a[href]"],
293
+ checkbox: ['input[type="checkbox"]'],
294
+ radio: ['input[type="radio"]']
295
+ };
296
+ const tags = roleTagMapping[role] ?? [];
297
+ const alternatives = [];
298
+ await this.processImplicitRoleTags(tags, role, alternatives, maxResults);
299
+ return alternatives;
300
+ }
301
+ async processImplicitRoleTags(tags, role, alternatives, maxResults) {
302
+ let totalFound = 0;
303
+ const processTagsSequentially = async (index) => {
304
+ if (index >= tags.length || totalFound >= maxResults) {
305
+ return;
306
+ }
307
+ const tagSelector = tags[index];
308
+ totalFound = await this.processImplicitRoleTag(tagSelector, role, alternatives, totalFound, maxResults);
309
+ await processTagsSequentially(index + 1);
310
+ };
311
+ await processTagsSequentially(0);
312
+ }
313
+ async processImplicitRoleTag(tagSelector, role, alternatives, totalFound, maxResults) {
314
+ const page = this.getPage();
315
+ try {
316
+ const elements = await page.$$(tagSelector);
317
+ return await this.processImplicitRoleElements(elements, tagSelector, role, alternatives, totalFound, maxResults);
318
+ } catch {
319
+ return totalFound;
320
+ }
321
+ }
322
+ async processImplicitRoleElements(elements, tagSelector, role, alternatives, totalFound, maxResults) {
323
+ let currentFound = totalFound;
324
+ const processElementsSequentially = async (index) => {
325
+ if (index >= elements.length) {
326
+ return;
327
+ }
328
+ const element = elements[index];
329
+ if (currentFound >= maxResults) {
330
+ await this.safeDispose(element, `findImplicitRole-excess-${currentFound}`);
331
+ return processElementsSequentially(index + 1);
332
+ }
333
+ const processResult = await this.processImplicitRoleElement(element, tagSelector, role, alternatives, currentFound);
334
+ if (processResult) {
335
+ currentFound++;
336
+ }
337
+ await processElementsSequentially(index + 1);
338
+ };
339
+ await processElementsSequentially(0);
340
+ return currentFound;
341
+ }
342
+ async processImplicitRoleElement(element, tagSelector, role, alternatives, currentFound) {
343
+ try {
344
+ const smartElement = this.smartHandleBatch.add(element);
345
+ alternatives.push({
346
+ selector: await this.generateSelector(element),
347
+ confidence: 0.6,
348
+ reason: `implicit role match: "${role}" via ${tagSelector}`,
349
+ element: smartElement,
350
+ elementId: `implicit_${currentFound}`
351
+ });
352
+ return true;
353
+ } catch (elementError) {
354
+ elementDiscoveryDebug("Implicit role element processing failed:", elementError);
355
+ await this.safeDispose(element, `findImplicitRole-element-${currentFound}`);
356
+ return false;
357
+ }
358
+ }
359
+ async generateSelector(element) {
360
+ return await element.evaluate((el) => {
361
+ if (!(el instanceof Element)) {
362
+ return "unknown";
363
+ }
364
+ const tag = el.tagName.toLowerCase();
365
+ const id = el.id ? `#${el.id}` : "";
366
+ const classes = el.className ? `.${el.className.split(" ").join(".")}` : "";
367
+ if (id) {
368
+ return `${tag}${id}`;
369
+ }
370
+ if (classes) {
371
+ return `${tag}${classes}`;
372
+ }
373
+ const parent = el.parentElement;
374
+ if (parent) {
375
+ const siblings = Array.from(parent.children);
376
+ const index = siblings.indexOf(el) + 1;
377
+ return `${parent.tagName.toLowerCase()} > ${tag}:nth-child(${index})`;
378
+ }
379
+ return tag;
380
+ });
381
+ }
382
+ calculateTextSimilarity(target, candidate) {
383
+ const targetLower = target.toLowerCase().trim();
384
+ const candidateLower = candidate.toLowerCase().trim();
385
+ if (targetLower === candidateLower) {
386
+ return 1;
387
+ }
388
+ if (candidateLower.includes(targetLower)) {
389
+ return 0.8;
390
+ }
391
+ if (targetLower.includes(candidateLower)) {
392
+ return 0.6;
393
+ }
394
+ const distance = this.levenshteinDistance(targetLower, candidateLower);
395
+ const maxLen = Math.max(targetLower.length, candidateLower.length);
396
+ return 1 - distance / maxLen;
397
+ }
398
+ levenshteinDistance(a, b) {
399
+ if (a.length === 0) {
400
+ return b.length;
401
+ }
402
+ if (b.length === 0) {
403
+ return a.length;
404
+ }
405
+ const matrix = new Array(b.length + 1).fill(null).map(() => new Array(a.length + 1).fill(null));
406
+ for (let i = 0;i <= a.length; i++) {
407
+ matrix[0][i] = i;
408
+ }
409
+ for (let j = 0;j <= b.length; j++) {
410
+ matrix[j][0] = j;
411
+ }
412
+ for (let j = 1;j <= b.length; j++) {
413
+ for (let i = 1;i <= a.length; i++) {
414
+ const indicator = a[i - 1] === b[j - 1] ? 0 : 1;
415
+ matrix[j][i] = Math.min(matrix[j][i - 1] + 1, matrix[j - 1][i] + 1, matrix[j - 1][i - 1] + indicator);
416
+ }
417
+ }
418
+ return matrix[b.length][a.length];
419
+ }
420
+ deduplicateAndSort(alternatives) {
421
+ const seen = new Set;
422
+ const unique = [];
423
+ for (const alt of alternatives) {
424
+ if (!seen.has(alt.selector)) {
425
+ seen.add(alt.selector);
426
+ unique.push(alt);
427
+ }
428
+ }
429
+ return unique.sort((a, b) => b.confidence - a.confidence);
430
+ }
431
+ getMemoryStats() {
432
+ return {
433
+ activeHandles: this.smartHandleBatch.getActiveCount(),
434
+ isDisposed: this.disposed,
435
+ maxBatchSize: this.maxBatchSize
436
+ };
437
+ }
438
+ }
439
+ export {
440
+ ElementDiscovery
441
+ };