@whenessel/seql-js 1.0.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.
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/dist/seql-js.d.ts +1215 -0
- package/dist/seql-js.js +2 -0
- package/dist/seql-js.js.map +1 -0
- package/dist/seql-js.umd.cjs +2 -0
- package/dist/seql-js.umd.cjs.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,1215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds semantic anchor for element identification
|
|
3
|
+
* Traverses up from target to find semantic root
|
|
4
|
+
* Following SPECIFICATION.md §7
|
|
5
|
+
*/
|
|
6
|
+
export declare class AnchorFinder {
|
|
7
|
+
private maxDepth;
|
|
8
|
+
private cache?;
|
|
9
|
+
constructor(options: GeneratorOptions, cache?: EIDCache);
|
|
10
|
+
/**
|
|
11
|
+
* Finds the best anchor element for the target
|
|
12
|
+
* @param target - Target element to find anchor for
|
|
13
|
+
* @returns Anchor result or null if not found
|
|
14
|
+
*/
|
|
15
|
+
findAnchor(target: Element): AnchorResult | null;
|
|
16
|
+
/**
|
|
17
|
+
* Scores an element as anchor candidate (without depth penalty)
|
|
18
|
+
* @param element - Element to score
|
|
19
|
+
* @returns Raw score from 0 to 1
|
|
20
|
+
*/
|
|
21
|
+
scoreAnchor(element: Element): number;
|
|
22
|
+
/**
|
|
23
|
+
* Applies depth penalty to score
|
|
24
|
+
* Following SPECIFICATION.md §7: depthPenalty = (depth - threshold) * factor
|
|
25
|
+
*/
|
|
26
|
+
private applyDepthPenalty;
|
|
27
|
+
/**
|
|
28
|
+
* Determines the tier of an anchor element
|
|
29
|
+
*/
|
|
30
|
+
private getTier;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Anchor node - the semantic root of the EID path
|
|
35
|
+
* Following SPECIFICATION.md §7
|
|
36
|
+
*/
|
|
37
|
+
export declare interface AnchorNode {
|
|
38
|
+
/** HTML tag name (lowercase) */
|
|
39
|
+
tag: string;
|
|
40
|
+
/** Semantic features */
|
|
41
|
+
semantics: ElementSemantics;
|
|
42
|
+
/** Quality score 0-1 */
|
|
43
|
+
score: number;
|
|
44
|
+
/** Whether this is a degraded/fallback anchor */
|
|
45
|
+
degraded: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Result of anchor finding
|
|
50
|
+
*/
|
|
51
|
+
export declare interface AnchorResult {
|
|
52
|
+
element: Element;
|
|
53
|
+
score: number;
|
|
54
|
+
tier: 'A' | 'B' | 'C';
|
|
55
|
+
depth: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Options for batch EID generation
|
|
60
|
+
*/
|
|
61
|
+
export declare interface BatchGeneratorOptions {
|
|
62
|
+
/** Root element to search from (default: document.body) */
|
|
63
|
+
root?: Element | Document;
|
|
64
|
+
/** CSS selector to filter elements (default: '*') */
|
|
65
|
+
filter?: string;
|
|
66
|
+
/** Maximum number of elements to process (default: Infinity) */
|
|
67
|
+
limit?: number;
|
|
68
|
+
/** Progress callback: (current, total) => void */
|
|
69
|
+
onProgress?: (current: number, total: number) => void;
|
|
70
|
+
/** Interval for calling onProgress (default: 100) */
|
|
71
|
+
progressInterval?: number;
|
|
72
|
+
/** Skip elements without semantic features (default: true) */
|
|
73
|
+
skipNonSemantic?: boolean;
|
|
74
|
+
/** Generator options */
|
|
75
|
+
generatorOptions?: GeneratorOptions;
|
|
76
|
+
/** Optional cache instance */
|
|
77
|
+
cache?: EIDCache;
|
|
78
|
+
/** AbortController for cancellation */
|
|
79
|
+
signal?: AbortSignal;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Result of batch generation
|
|
84
|
+
*/
|
|
85
|
+
export declare interface BatchResult {
|
|
86
|
+
/** Successfully generated Element Identities */
|
|
87
|
+
results: Array<{
|
|
88
|
+
element: Element;
|
|
89
|
+
eid: ElementIdentity;
|
|
90
|
+
generationTimeMs: number;
|
|
91
|
+
}>;
|
|
92
|
+
/** Elements that failed to generate EID */
|
|
93
|
+
failed: Array<{
|
|
94
|
+
element: Element;
|
|
95
|
+
error: string;
|
|
96
|
+
}>;
|
|
97
|
+
/** Statistics */
|
|
98
|
+
stats: {
|
|
99
|
+
totalElements: number;
|
|
100
|
+
successful: number;
|
|
101
|
+
failed: number;
|
|
102
|
+
skipped: number;
|
|
103
|
+
totalTimeMs: number;
|
|
104
|
+
avgTimePerElementMs: number;
|
|
105
|
+
cacheHitRate: number;
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Options for selector building with uniqueness control
|
|
111
|
+
*/
|
|
112
|
+
declare interface BuildSelectorOptions {
|
|
113
|
+
/**
|
|
114
|
+
* Enable uniqueness disambiguation for target element.
|
|
115
|
+
* When true and base selector is not unique, adds:
|
|
116
|
+
* 1. Extra stable classes (up to maxClasses)
|
|
117
|
+
* 2. :nth-of-type(N) as last resort
|
|
118
|
+
*/
|
|
119
|
+
ensureUnique?: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Maximum number of additional classes to add for disambiguation
|
|
122
|
+
* @default 4
|
|
123
|
+
*/
|
|
124
|
+
maxClasses?: number;
|
|
125
|
+
/**
|
|
126
|
+
* Root element for uniqueness check (defaults to document)
|
|
127
|
+
*/
|
|
128
|
+
root?: Document | Element;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Result of selector building with uniqueness info
|
|
133
|
+
*/
|
|
134
|
+
declare interface BuildSelectorResult {
|
|
135
|
+
/** Generated CSS selector */
|
|
136
|
+
selector: string;
|
|
137
|
+
/** Whether selector is unique in the given root */
|
|
138
|
+
isUnique: boolean;
|
|
139
|
+
/** Whether nth-of-type was added for disambiguation */
|
|
140
|
+
usedNthOfType: boolean;
|
|
141
|
+
/** Number of extra classes added for disambiguation */
|
|
142
|
+
extraClassesAdded: number;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Cache statistics
|
|
147
|
+
*/
|
|
148
|
+
export declare interface CacheStats {
|
|
149
|
+
/** Total number of EID cache hits */
|
|
150
|
+
eidHits: number;
|
|
151
|
+
/** Total number of EID cache misses */
|
|
152
|
+
eidMisses: number;
|
|
153
|
+
/** Total number of selector cache hits */
|
|
154
|
+
selectorHits: number;
|
|
155
|
+
/** Total number of selector cache misses */
|
|
156
|
+
selectorMisses: number;
|
|
157
|
+
/** Total number of anchor cache hits */
|
|
158
|
+
anchorHits: number;
|
|
159
|
+
/** Total number of anchor cache misses */
|
|
160
|
+
anchorMisses: number;
|
|
161
|
+
/** Total number of semantics cache hits */
|
|
162
|
+
semanticsHits: number;
|
|
163
|
+
/** Total number of semantics cache misses */
|
|
164
|
+
semanticsMisses: number;
|
|
165
|
+
/** Current selector cache size */
|
|
166
|
+
selectorCacheSize: number;
|
|
167
|
+
/** Maximum selector cache size */
|
|
168
|
+
maxSelectorCacheSize: number;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Calculates overall confidence score for Element Identity
|
|
173
|
+
* Following SPECIFICATION.md §13 confidence formula
|
|
174
|
+
*
|
|
175
|
+
* @param eid - The Element Identity to score
|
|
176
|
+
* @param uniquenessBonus - Bonus for unique resolution (0-1), determined during resolution
|
|
177
|
+
* @returns Confidence score from 0 to 1
|
|
178
|
+
*/
|
|
179
|
+
export declare function calculateConfidence(eid: ElementIdentity, uniquenessBonus?: number): number;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Calculates score for a single element based on its semantic features
|
|
183
|
+
* @param semanticsCount - Number of semantic features present
|
|
184
|
+
* @param hasId - Whether element has stable ID
|
|
185
|
+
* @param hasRole - Whether element has ARIA role
|
|
186
|
+
* @returns Score from 0 to 1
|
|
187
|
+
*/
|
|
188
|
+
export declare function calculateElementScore(semanticsCount: number, hasId: boolean, hasRole: boolean): number;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Base constraint structure
|
|
192
|
+
*/
|
|
193
|
+
export declare interface Constraint {
|
|
194
|
+
/** Constraint type */
|
|
195
|
+
type: ConstraintType;
|
|
196
|
+
/** Constraint-specific parameters */
|
|
197
|
+
params: Record<string, unknown>;
|
|
198
|
+
/** Priority (0-100, higher = applied first) */
|
|
199
|
+
priority: number;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Evaluates and applies constraints to candidates
|
|
204
|
+
* Following SPECIFICATION.md §13.4
|
|
205
|
+
*/
|
|
206
|
+
export declare class ConstraintsEvaluator {
|
|
207
|
+
/**
|
|
208
|
+
* Applies a single constraint to candidates
|
|
209
|
+
* @param candidates - Current candidate elements
|
|
210
|
+
* @param constraint - Constraint to apply
|
|
211
|
+
* @returns Filtered candidates
|
|
212
|
+
*/
|
|
213
|
+
applyConstraint(candidates: Element[], constraint: Constraint): Element[];
|
|
214
|
+
/**
|
|
215
|
+
* Applies text proximity constraint using Levenshtein distance
|
|
216
|
+
*/
|
|
217
|
+
private applyTextProximity;
|
|
218
|
+
/**
|
|
219
|
+
* Applies position constraint
|
|
220
|
+
*/
|
|
221
|
+
private applyPosition;
|
|
222
|
+
/**
|
|
223
|
+
* Gets the top-most element by bounding rect
|
|
224
|
+
*/
|
|
225
|
+
private getTopMost;
|
|
226
|
+
/**
|
|
227
|
+
* Gets the left-most element by bounding rect
|
|
228
|
+
*/
|
|
229
|
+
private getLeftMost;
|
|
230
|
+
/**
|
|
231
|
+
* Calculates Levenshtein distance between two strings
|
|
232
|
+
*/
|
|
233
|
+
private levenshteinDistance;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Constraint type identifiers
|
|
238
|
+
* Following SPECIFICATION.md §13.4
|
|
239
|
+
*/
|
|
240
|
+
export declare type ConstraintType = 'uniqueness' | 'text-proximity' | 'position';
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Create a new EID cache instance
|
|
244
|
+
*/
|
|
245
|
+
export declare function createEIDCache(options?: EIDCacheOptions): EIDCache;
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Generates CSS selectors from Element Identity
|
|
249
|
+
* Following SPECIFICATION.md §13.1
|
|
250
|
+
*
|
|
251
|
+
* Priority order (highest to lowest):
|
|
252
|
+
* 1. ID (100)
|
|
253
|
+
* 2. data-testid, data-qa, data-cy (95)
|
|
254
|
+
* 3. aria-label (90)
|
|
255
|
+
* 4. name (85)
|
|
256
|
+
* 5. href, src (80) - semantic for <a>, <img>, etc.
|
|
257
|
+
* 6. role (75)
|
|
258
|
+
* 7. type (70)
|
|
259
|
+
* 8. alt, title, for (60)
|
|
260
|
+
* 9. Stable classes (35)
|
|
261
|
+
* 10. nth-of-type (last resort, added when ensureUnique=true)
|
|
262
|
+
*/
|
|
263
|
+
export declare class CssGenerator {
|
|
264
|
+
/**
|
|
265
|
+
* Builds CSS selector from Element Identity
|
|
266
|
+
* @param eid - Element Identity to convert
|
|
267
|
+
* @param options - Optional uniqueness control settings
|
|
268
|
+
* @returns CSS selector string (simple) or BuildSelectorResult (with options)
|
|
269
|
+
*/
|
|
270
|
+
buildSelector(eid: ElementIdentity, options?: BuildSelectorOptions): string;
|
|
271
|
+
buildSelector(eid: ElementIdentity, options: BuildSelectorOptions & {
|
|
272
|
+
ensureUnique: true;
|
|
273
|
+
}): BuildSelectorResult;
|
|
274
|
+
/**
|
|
275
|
+
* Builds selector for anchor only (used in fallback)
|
|
276
|
+
* @param eid - Element Identity
|
|
277
|
+
* @returns CSS selector for anchor
|
|
278
|
+
*/
|
|
279
|
+
buildAnchorSelector(eid: ElementIdentity): string;
|
|
280
|
+
/**
|
|
281
|
+
* Ensures selector uniqueness by progressively adding classes and nth-of-type
|
|
282
|
+
*/
|
|
283
|
+
private ensureUniqueSelector;
|
|
284
|
+
/**
|
|
285
|
+
* Builds full DOM path selector by traversing actual DOM from anchor
|
|
286
|
+
* This handles cases where intermediate div/span elements were filtered out
|
|
287
|
+
*/
|
|
288
|
+
private buildFullDomPathSelector;
|
|
289
|
+
/**
|
|
290
|
+
* Scores how well a candidate's DOM path matches the EID path
|
|
291
|
+
* Compares tags, classes, attributes, and nthChild positions
|
|
292
|
+
* @param candidate - Target element candidate
|
|
293
|
+
* @param anchor - Anchor element
|
|
294
|
+
* @param eidPath - EID path nodes
|
|
295
|
+
* @returns Score (higher = better match)
|
|
296
|
+
*/
|
|
297
|
+
private scorePathMatch;
|
|
298
|
+
/**
|
|
299
|
+
* Finds target elements within an anchor by matching semantics
|
|
300
|
+
*/
|
|
301
|
+
private findTargetWithinAnchor;
|
|
302
|
+
/**
|
|
303
|
+
* Disambiguates a parent element by trying attributes, classes, then nth-of-type
|
|
304
|
+
* Priority: stable attributes > one stable class > nth-of-type
|
|
305
|
+
* @param element The DOM element to disambiguate
|
|
306
|
+
* @param tag The tag name
|
|
307
|
+
* @param pathNode EID path node with semantics (if available)
|
|
308
|
+
* @param fullPath Current selector path (for uniqueness testing)
|
|
309
|
+
* @param root Root element for queries
|
|
310
|
+
* @returns Disambiguated selector part (e.g., "div[role='main']" or "div.sidebar" or "div:nth-of-type(3)")
|
|
311
|
+
*/
|
|
312
|
+
private disambiguateParent;
|
|
313
|
+
/**
|
|
314
|
+
* Builds CSS selector path from anchor to target by traversing actual DOM
|
|
315
|
+
*/
|
|
316
|
+
private buildPathFromAnchorToTarget;
|
|
317
|
+
/**
|
|
318
|
+
* Builds a minimal selector for a DOM element
|
|
319
|
+
* @param element The DOM element to create a selector for
|
|
320
|
+
* @returns A minimal CSS selector for the element
|
|
321
|
+
*/
|
|
322
|
+
private buildElementSelector;
|
|
323
|
+
/**
|
|
324
|
+
* Checks if ID is dynamic (generated)
|
|
325
|
+
*/
|
|
326
|
+
private isDynamicId;
|
|
327
|
+
/**
|
|
328
|
+
* Safe querySelectorAll that doesn't throw
|
|
329
|
+
*/
|
|
330
|
+
private querySelectorSafe;
|
|
331
|
+
/**
|
|
332
|
+
* Finds element by matching text content
|
|
333
|
+
* Returns the matching element (used with getNthSelector for table-aware positioning)
|
|
334
|
+
*/
|
|
335
|
+
private findNthElementByText;
|
|
336
|
+
/**
|
|
337
|
+
* Checks if selector matches exactly one element
|
|
338
|
+
*/
|
|
339
|
+
private isUnique;
|
|
340
|
+
/**
|
|
341
|
+
* Gets nth-of-type index for an element
|
|
342
|
+
*/
|
|
343
|
+
private getNthOfTypeIndex;
|
|
344
|
+
/**
|
|
345
|
+
* FIX 2: Ensures anchor selector is unique in the document
|
|
346
|
+
* Priority order: tag → tag.class → tag[attr] → tag:nth-of-type(N)
|
|
347
|
+
* @param eid - Element Identity with anchor information
|
|
348
|
+
* @param root - Root element for uniqueness check
|
|
349
|
+
* @returns Unique selector for anchor
|
|
350
|
+
*/
|
|
351
|
+
private ensureUniqueAnchor;
|
|
352
|
+
/**
|
|
353
|
+
* FIX 2: Finds element by matching semantics
|
|
354
|
+
* @param elements - Array of candidate elements
|
|
355
|
+
* @param semantics - Semantics to match against
|
|
356
|
+
* @returns Matching element or null
|
|
357
|
+
*/
|
|
358
|
+
private findElementBySemantics;
|
|
359
|
+
/**
|
|
360
|
+
* FIX 3: Gets nth selector - nth-child for tables, nth-of-type for others
|
|
361
|
+
* This method is now ACTIVELY INTEGRATED in selector generation logic
|
|
362
|
+
* to ensure table elements use position-specific nth-child selectors
|
|
363
|
+
* @param element - Element to get selector for
|
|
364
|
+
* @param tag - Tag name
|
|
365
|
+
* @returns nth selector string (e.g., ":nth-child(2)" or ":nth-of-type(2)")
|
|
366
|
+
*/
|
|
367
|
+
private getNthSelector;
|
|
368
|
+
/**
|
|
369
|
+
* Gets attribute priority for sorting
|
|
370
|
+
* @param attrName - Attribute name
|
|
371
|
+
* @returns Priority number (higher = more priority)
|
|
372
|
+
*/
|
|
373
|
+
private getAttributePriority;
|
|
374
|
+
/**
|
|
375
|
+
* Checks if attribute should be ignored
|
|
376
|
+
* @param attrName - Attribute name
|
|
377
|
+
* @returns True if should be ignored
|
|
378
|
+
*/
|
|
379
|
+
private shouldIgnoreAttribute;
|
|
380
|
+
/**
|
|
381
|
+
* Gets attributes sorted by priority
|
|
382
|
+
* @param attributes - Attributes object
|
|
383
|
+
* @returns Sorted array of attributes with priority
|
|
384
|
+
*/
|
|
385
|
+
private getSortedAttributes;
|
|
386
|
+
/**
|
|
387
|
+
* Builds selector for a single node
|
|
388
|
+
* Priority: ID → semantic attributes → role → classes
|
|
389
|
+
*/
|
|
390
|
+
private buildNodeSelector;
|
|
391
|
+
/**
|
|
392
|
+
* Escapes special characters for CSS selector
|
|
393
|
+
*/
|
|
394
|
+
private escapeCSS;
|
|
395
|
+
/**
|
|
396
|
+
* Escapes quotes for attribute values
|
|
397
|
+
*/
|
|
398
|
+
private escapeAttr;
|
|
399
|
+
/**
|
|
400
|
+
* Checks if element tag is an SVG child element
|
|
401
|
+
* @param tag - Element tag name
|
|
402
|
+
* @returns True if element is an SVG child
|
|
403
|
+
*/
|
|
404
|
+
private isSvgChildElement;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Default generator options
|
|
409
|
+
* Note: cache is optional and not included in defaults
|
|
410
|
+
*/
|
|
411
|
+
export declare const DEFAULT_GENERATOR_OPTIONS: Omit<Required<GeneratorOptions>, 'cache'> & Pick<GeneratorOptions, 'cache'>;
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Default resolver options
|
|
415
|
+
*/
|
|
416
|
+
export declare const DEFAULT_RESOLVER_OPTIONS: Required<ResolverOptions>;
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* EID specification version
|
|
420
|
+
*/
|
|
421
|
+
export declare const EID_VERSION: EIDVersion;
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* EID Cache for multi-level caching
|
|
425
|
+
* Provides caching for:
|
|
426
|
+
* - Complete EID identities (WeakMap)
|
|
427
|
+
* - Selector query results (LRU Map)
|
|
428
|
+
* - Anchor finder results (WeakMap)
|
|
429
|
+
* - Semantic extraction results (WeakMap)
|
|
430
|
+
*/
|
|
431
|
+
export declare class EIDCache {
|
|
432
|
+
private eidCache;
|
|
433
|
+
private selectorResultCache;
|
|
434
|
+
private anchorCache;
|
|
435
|
+
private semanticsCache;
|
|
436
|
+
private stats;
|
|
437
|
+
constructor(options?: EIDCacheOptions);
|
|
438
|
+
/**
|
|
439
|
+
* Get cached EID for element
|
|
440
|
+
*/
|
|
441
|
+
getEID(element: Element): ElementIdentity | undefined;
|
|
442
|
+
/**
|
|
443
|
+
* Cache EID for element
|
|
444
|
+
*/
|
|
445
|
+
setEID(element: Element, eid: ElementIdentity): void;
|
|
446
|
+
/**
|
|
447
|
+
* Get cached selector results
|
|
448
|
+
*/
|
|
449
|
+
getSelectorResults(selector: string): Element[] | undefined;
|
|
450
|
+
/**
|
|
451
|
+
* Cache selector results
|
|
452
|
+
*/
|
|
453
|
+
setSelectorResults(selector: string, results: Element[]): void;
|
|
454
|
+
/**
|
|
455
|
+
* Get cached anchor result
|
|
456
|
+
*/
|
|
457
|
+
getAnchor(element: Element): AnchorResult | null | undefined;
|
|
458
|
+
/**
|
|
459
|
+
* Cache anchor result
|
|
460
|
+
*/
|
|
461
|
+
setAnchor(element: Element, result: AnchorResult | null): void;
|
|
462
|
+
/**
|
|
463
|
+
* Get cached semantics
|
|
464
|
+
*/
|
|
465
|
+
getSemantics(element: Element): ElementSemantics | undefined;
|
|
466
|
+
/**
|
|
467
|
+
* Cache semantics
|
|
468
|
+
*/
|
|
469
|
+
setSemantics(element: Element, semantics: ElementSemantics): void;
|
|
470
|
+
/**
|
|
471
|
+
* Clear all caches
|
|
472
|
+
*/
|
|
473
|
+
clear(): void;
|
|
474
|
+
/**
|
|
475
|
+
* Invalidate cache for a specific element
|
|
476
|
+
* Note: WeakMaps don't support deletion, but we can clear selector cache
|
|
477
|
+
* if needed. This method is mainly for future extensibility.
|
|
478
|
+
*/
|
|
479
|
+
invalidateElement(_element: Element): void;
|
|
480
|
+
/**
|
|
481
|
+
* Invalidate a specific selector from cache
|
|
482
|
+
*/
|
|
483
|
+
invalidateSelector(selector: string): void;
|
|
484
|
+
/**
|
|
485
|
+
* Get cache statistics
|
|
486
|
+
*/
|
|
487
|
+
getStats(): CacheStats;
|
|
488
|
+
/**
|
|
489
|
+
* Get cache hit rate for EID cache
|
|
490
|
+
*/
|
|
491
|
+
getEIDHitRate(): number;
|
|
492
|
+
/**
|
|
493
|
+
* Get cache hit rate for selector cache
|
|
494
|
+
*/
|
|
495
|
+
getSelectorHitRate(): number;
|
|
496
|
+
/**
|
|
497
|
+
* Get cache hit rate for anchor cache
|
|
498
|
+
*/
|
|
499
|
+
getAnchorHitRate(): number;
|
|
500
|
+
/**
|
|
501
|
+
* Get cache hit rate for semantics cache
|
|
502
|
+
*/
|
|
503
|
+
getSemanticsHitRate(): number;
|
|
504
|
+
/**
|
|
505
|
+
* Get overall cache hit rate
|
|
506
|
+
*/
|
|
507
|
+
getOverallHitRate(): number;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Options for creating an EID cache
|
|
512
|
+
*/
|
|
513
|
+
export declare interface EIDCacheOptions {
|
|
514
|
+
/** Maximum size for selector cache (default: 1000) */
|
|
515
|
+
maxSelectorCacheSize?: number;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* EID metadata
|
|
520
|
+
*/
|
|
521
|
+
export declare interface EIDMeta {
|
|
522
|
+
/** Overall confidence score 0-1 */
|
|
523
|
+
confidence: number;
|
|
524
|
+
/** ISO timestamp when generated */
|
|
525
|
+
generatedAt: string;
|
|
526
|
+
/** Generator identifier */
|
|
527
|
+
generator: string;
|
|
528
|
+
/** Source context (e.g., 'rrweb-recorder') */
|
|
529
|
+
source: string;
|
|
530
|
+
/** Whether EID is degraded quality */
|
|
531
|
+
degraded: boolean;
|
|
532
|
+
/** Reason for degradation if degraded */
|
|
533
|
+
degradationReason?: string;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* EID version string
|
|
538
|
+
*/
|
|
539
|
+
export declare type EIDVersion = '1.0';
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Main Element Identity Descriptor (EID) structure - describes "what" an element is
|
|
543
|
+
* Following SPECIFICATION.md §14
|
|
544
|
+
*/
|
|
545
|
+
export declare interface ElementIdentity {
|
|
546
|
+
/** EID specification version */
|
|
547
|
+
version: EIDVersion;
|
|
548
|
+
/** Semantic root/context for the path */
|
|
549
|
+
anchor: AnchorNode;
|
|
550
|
+
/** Semantic path from anchor to target's parent */
|
|
551
|
+
path: PathNode[];
|
|
552
|
+
/** The target element description */
|
|
553
|
+
target: TargetNode;
|
|
554
|
+
/** Disambiguation constraints (applied during resolution) */
|
|
555
|
+
constraints: Constraint[];
|
|
556
|
+
/** Fallback behavior rules */
|
|
557
|
+
fallback: FallbackRules;
|
|
558
|
+
/** Metadata about generation */
|
|
559
|
+
meta: EIDMeta;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Semantic features for an EID node
|
|
564
|
+
* Following SPECIFICATION.md §10
|
|
565
|
+
*/
|
|
566
|
+
export declare interface ElementSemantics {
|
|
567
|
+
/** Stable ID (not dynamic) */
|
|
568
|
+
id?: string;
|
|
569
|
+
/** Semantic class names (utility classes filtered out) */
|
|
570
|
+
classes?: string[];
|
|
571
|
+
/** Relevant attributes (aria-*, name, type, role, etc.) */
|
|
572
|
+
attributes?: Record<string, string>;
|
|
573
|
+
/** Text content */
|
|
574
|
+
text?: TextContent;
|
|
575
|
+
/** SVG fingerprint (for SVG elements) */
|
|
576
|
+
svg?: SvgFingerprint;
|
|
577
|
+
/** ARIA role */
|
|
578
|
+
role?: string;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* Handles resolution fallback scenarios
|
|
583
|
+
* Following SPECIFICATION.md §13.5
|
|
584
|
+
*/
|
|
585
|
+
export declare class FallbackHandler {
|
|
586
|
+
private cssGenerator;
|
|
587
|
+
constructor();
|
|
588
|
+
/**
|
|
589
|
+
* Handles fallback when resolution fails
|
|
590
|
+
* @param eid - Element Identity being resolved
|
|
591
|
+
* @param dom - Document or element to search in
|
|
592
|
+
* @returns Fallback resolution result
|
|
593
|
+
*/
|
|
594
|
+
handleFallback(eid: ElementIdentity, dom: Document | Element): ResolveResult;
|
|
595
|
+
/**
|
|
596
|
+
* Attempts to find and return the anchor element as fallback
|
|
597
|
+
*/
|
|
598
|
+
private fallbackToAnchor;
|
|
599
|
+
/**
|
|
600
|
+
* Handles ambiguous results (multiple matches)
|
|
601
|
+
* @param elements - All matching elements
|
|
602
|
+
* @param eid - Original Element Identity
|
|
603
|
+
* @returns Resolution result based on fallback rules
|
|
604
|
+
*/
|
|
605
|
+
handleAmbiguous(elements: Element[], eid: ElementIdentity): ResolveResult;
|
|
606
|
+
/**
|
|
607
|
+
* Selects the best-scoring element from candidates
|
|
608
|
+
* Re-scores each element based on semantic match quality
|
|
609
|
+
*/
|
|
610
|
+
private selectBestScoring;
|
|
611
|
+
/**
|
|
612
|
+
* Scores how well an element matches the target semantics
|
|
613
|
+
* @returns Score from 0 to 1
|
|
614
|
+
*/
|
|
615
|
+
private scoreElementMatch;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Fallback rules for resolution
|
|
620
|
+
* Following SPECIFICATION.md §13.5
|
|
621
|
+
*/
|
|
622
|
+
export declare interface FallbackRules {
|
|
623
|
+
/** Behavior when multiple elements match */
|
|
624
|
+
onMultiple: 'allow-multiple' | 'best-score' | 'first';
|
|
625
|
+
/** Behavior when target is not found */
|
|
626
|
+
onMissing: 'anchor-only' | 'strict' | 'none';
|
|
627
|
+
/** Maximum depth for fallback search */
|
|
628
|
+
maxDepth: number;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Filters classes into semantic and utility
|
|
633
|
+
* Uses class-classifier for improved detection
|
|
634
|
+
* @param classes - Array of class names
|
|
635
|
+
* @returns Object with semantic and utility arrays
|
|
636
|
+
*/
|
|
637
|
+
export declare function filterClasses(classes: string[]): {
|
|
638
|
+
semantic: string[];
|
|
639
|
+
utility: string[];
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Generates EID (Element Identity) for a DOM element
|
|
644
|
+
* Following SPECIFICATION.md §7-11
|
|
645
|
+
*
|
|
646
|
+
* @param target - Target DOM element
|
|
647
|
+
* @param options - Generation options
|
|
648
|
+
* @returns Element identity or null if generation failed
|
|
649
|
+
*/
|
|
650
|
+
export declare function generateEID(target: Element, options?: GeneratorOptions): ElementIdentity | null;
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Generate EID for all elements matching criteria
|
|
654
|
+
*/
|
|
655
|
+
export declare function generateEIDBatch(options?: BatchGeneratorOptions): BatchResult;
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Generate EID for specific elements
|
|
659
|
+
*/
|
|
660
|
+
export declare function generateEIDForElements(elements: Element[], options?: Omit<BatchGeneratorOptions, 'root' | 'filter'>): BatchResult;
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Generate SEQL Selector directly from DOM element
|
|
664
|
+
*
|
|
665
|
+
* This is a convenience function that combines generateEID() and stringifySEQL().
|
|
666
|
+
*
|
|
667
|
+
* @param element - Target DOM element
|
|
668
|
+
* @param generatorOptions - Optional generation options
|
|
669
|
+
* @param stringifyOptions - Optional stringify options
|
|
670
|
+
* @returns SEQL Selector (canonical string)
|
|
671
|
+
*
|
|
672
|
+
* @example
|
|
673
|
+
* ```typescript
|
|
674
|
+
* const button = document.querySelector('.submit-button');
|
|
675
|
+
* const selector = generateSEQL(button);
|
|
676
|
+
* // "v1: form :: div.actions > button[type="submit",text="Submit Order"]"
|
|
677
|
+
*
|
|
678
|
+
* // Send to analytics
|
|
679
|
+
* gtag('event', 'click', { element_selector: selector });
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
682
|
+
export declare function generateSEQL(element: Element, generatorOptions?: GeneratorOptions, stringifyOptions?: StringifyOptions): string | null;
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Generator options
|
|
686
|
+
* Following SPECIFICATION.md §7-8
|
|
687
|
+
*/
|
|
688
|
+
export declare interface GeneratorOptions {
|
|
689
|
+
/** Maximum path depth (default: 10) */
|
|
690
|
+
maxPathDepth?: number;
|
|
691
|
+
/** Enable SVG fingerprinting (default: true) */
|
|
692
|
+
enableSvgFingerprint?: boolean;
|
|
693
|
+
/** Minimum confidence to return EID (default: 0.3) */
|
|
694
|
+
confidenceThreshold?: number;
|
|
695
|
+
/** Fallback to body if no anchor found (default: true) */
|
|
696
|
+
fallbackToBody?: boolean;
|
|
697
|
+
/** Include utility classes in EID (default: false) */
|
|
698
|
+
includeUtilityClasses?: boolean;
|
|
699
|
+
/** Source identifier for metadata */
|
|
700
|
+
source?: string;
|
|
701
|
+
/** Optional cache instance for performance optimization */
|
|
702
|
+
cache?: EIDCache;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Scores a class for semantic value
|
|
707
|
+
* Uses class-classifier for improved scoring
|
|
708
|
+
* @param className - Class name to score
|
|
709
|
+
* @returns Score from 0 to 1
|
|
710
|
+
*/
|
|
711
|
+
export declare function getClassScore(className: string): number;
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Get or create the global default cache
|
|
715
|
+
*/
|
|
716
|
+
export declare function getGlobalCache(): EIDCache;
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Checks if a value is a valid ElementIdentity object
|
|
720
|
+
* @param value - Value to check
|
|
721
|
+
* @returns True if valid ElementIdentity structure
|
|
722
|
+
*/
|
|
723
|
+
export declare function isEID(value: unknown): value is ElementIdentity;
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Checks if class is a utility/atomic CSS class
|
|
727
|
+
* Uses class-classifier for improved detection
|
|
728
|
+
* @param className - Class name to check
|
|
729
|
+
* @returns True if utility class
|
|
730
|
+
*/
|
|
731
|
+
export declare function isUtilityClass(className: string): boolean;
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Maximum path depth for traversal
|
|
735
|
+
* Following SPECIFICATION.md §8
|
|
736
|
+
*/
|
|
737
|
+
export declare const MAX_PATH_DEPTH = 10;
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* Normalizes text for comparison
|
|
741
|
+
* Following SPECIFICATION.md §11
|
|
742
|
+
*
|
|
743
|
+
* - Trims whitespace
|
|
744
|
+
* - Collapses multiple spaces
|
|
745
|
+
* - Replaces newlines/tabs with spaces
|
|
746
|
+
*/
|
|
747
|
+
export declare function normalizeText(text: string | null | undefined): string;
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Parses SEQL Selector back to EID structure
|
|
751
|
+
*
|
|
752
|
+
* @param selector - SEQL Selector string (similar to CSS Selector)
|
|
753
|
+
* @returns Element Identity Descriptor
|
|
754
|
+
* @throws {Error} if SEQL Selector is malformed or version unsupported
|
|
755
|
+
*
|
|
756
|
+
* @example
|
|
757
|
+
* ```typescript
|
|
758
|
+
* const selector = "v1: footer :: ul > li#3 > a[href='/contact']";
|
|
759
|
+
* const eid = parseSEQL(selector);
|
|
760
|
+
* const elements = resolve(eid, document);
|
|
761
|
+
* ```
|
|
762
|
+
*/
|
|
763
|
+
export declare function parseSEQL(selector: string): ElementIdentity;
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Builds semantic path from anchor to target
|
|
767
|
+
* Following SPECIFICATION.md §8
|
|
768
|
+
*/
|
|
769
|
+
export declare class PathBuilder {
|
|
770
|
+
private maxDepth;
|
|
771
|
+
private cache?;
|
|
772
|
+
constructor(options: GeneratorOptions, cache?: EIDCache);
|
|
773
|
+
/**
|
|
774
|
+
* Builds path from anchor to target (excluding both)
|
|
775
|
+
* @param anchor - Anchor element (start)
|
|
776
|
+
* @param target - Target element (end)
|
|
777
|
+
* @param extractor - Semantic extractor instance
|
|
778
|
+
* @returns Path build result with nodes and degradation info
|
|
779
|
+
*/
|
|
780
|
+
buildPath(anchor: Element, target: Element, extractor: SemanticExtractor): PathBuildResult;
|
|
781
|
+
/**
|
|
782
|
+
* Legacy method for backward compatibility
|
|
783
|
+
*/
|
|
784
|
+
buildPathNodes(anchor: Element, target: Element, extractor: SemanticExtractor): PathNode[];
|
|
785
|
+
/**
|
|
786
|
+
* Ensures path uniqueness by adding nodes if needed
|
|
787
|
+
* Following SPECIFICATION.md §8 Disambiguation Algorithm
|
|
788
|
+
*/
|
|
789
|
+
private ensureUniqueness;
|
|
790
|
+
/**
|
|
791
|
+
* Inserts node into path maintaining original order
|
|
792
|
+
*/
|
|
793
|
+
private insertNodeInOrder;
|
|
794
|
+
/**
|
|
795
|
+
* Builds a test CSS selector from path
|
|
796
|
+
*/
|
|
797
|
+
private buildTestSelector;
|
|
798
|
+
/**
|
|
799
|
+
* Converts element to basic CSS selector
|
|
800
|
+
*/
|
|
801
|
+
private elementToSelector;
|
|
802
|
+
/**
|
|
803
|
+
* Filters out noise/layout elements
|
|
804
|
+
*/
|
|
805
|
+
private filterNoise;
|
|
806
|
+
/**
|
|
807
|
+
* Determines if element should be included in path
|
|
808
|
+
*/
|
|
809
|
+
shouldInclude(element: Element): boolean;
|
|
810
|
+
/**
|
|
811
|
+
* Checks if element has meaningful semantic features
|
|
812
|
+
*/
|
|
813
|
+
private hasSemanticFeatures;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* Result of path building including degradation info
|
|
818
|
+
*/
|
|
819
|
+
declare interface PathBuildResult {
|
|
820
|
+
path: PathNode[];
|
|
821
|
+
degraded: boolean;
|
|
822
|
+
degradationReason?: string;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* Path node - intermediate element in the path
|
|
827
|
+
* Following SPECIFICATION.md §8
|
|
828
|
+
*/
|
|
829
|
+
export declare interface PathNode {
|
|
830
|
+
/** HTML tag name (lowercase) */
|
|
831
|
+
tag: string;
|
|
832
|
+
/** Semantic features */
|
|
833
|
+
semantics: ElementSemantics;
|
|
834
|
+
/** Quality score 0-1 */
|
|
835
|
+
score: number;
|
|
836
|
+
/** Position among siblings (1-based, for nth-child CSS selector) */
|
|
837
|
+
nthChild?: number;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Position constraint (degraded fallback)
|
|
842
|
+
*/
|
|
843
|
+
export declare interface PositionConstraint extends Constraint {
|
|
844
|
+
type: 'position';
|
|
845
|
+
params: {
|
|
846
|
+
strategy: 'top-most' | 'left-most' | 'first-in-dom';
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* Reset the global cache
|
|
852
|
+
*/
|
|
853
|
+
export declare function resetGlobalCache(): void;
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* Resolves Element Identity back to DOM element(s)
|
|
857
|
+
* Following SPECIFICATION.md §13 (5-phase algorithm)
|
|
858
|
+
*
|
|
859
|
+
* @param eid - Element Identity to resolve
|
|
860
|
+
* @param dom - Document or root element to search in
|
|
861
|
+
* @param options - Resolver options
|
|
862
|
+
* @returns Resolution result with matched elements
|
|
863
|
+
*/
|
|
864
|
+
export declare function resolve(eid: ElementIdentity, dom: Document | Element, options?: ResolverOptions): ResolveResult;
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* Resolve result
|
|
868
|
+
*/
|
|
869
|
+
export declare interface ResolveResult {
|
|
870
|
+
/** Resolution status */
|
|
871
|
+
status: ResolveStatus;
|
|
872
|
+
/** Matched elements (0, 1, or multiple) */
|
|
873
|
+
elements: Element[];
|
|
874
|
+
/** Warning messages */
|
|
875
|
+
warnings: string[];
|
|
876
|
+
/** Confidence score of match */
|
|
877
|
+
confidence: number;
|
|
878
|
+
/** Metadata about resolution */
|
|
879
|
+
meta: {
|
|
880
|
+
degraded: boolean;
|
|
881
|
+
degradationReason?: string;
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* Resolver options
|
|
887
|
+
* Following SPECIFICATION.md §13
|
|
888
|
+
*/
|
|
889
|
+
export declare interface ResolverOptions {
|
|
890
|
+
/** Strict mode: fail on ambiguity (default: false) */
|
|
891
|
+
strictMode?: boolean;
|
|
892
|
+
/** Enable fallback mechanisms (default: true) */
|
|
893
|
+
enableFallback?: boolean;
|
|
894
|
+
/** Maximum candidates to consider (default: 20) */
|
|
895
|
+
maxCandidates?: number;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
/**
|
|
899
|
+
* Resolve SEQL Selector directly to DOM elements
|
|
900
|
+
*
|
|
901
|
+
* This is a convenience function that combines parseSEQL() and resolve().
|
|
902
|
+
*
|
|
903
|
+
* @param selector - SEQL Selector string
|
|
904
|
+
* @param root - Root element or document to search in
|
|
905
|
+
* @param options - Optional resolver options
|
|
906
|
+
* @returns Array of matched elements (empty if not found)
|
|
907
|
+
*
|
|
908
|
+
* @example
|
|
909
|
+
* ```typescript
|
|
910
|
+
* // Parse SEQL Selector from analytics
|
|
911
|
+
* const selector = "v1: form :: button.submit";
|
|
912
|
+
* const elements = resolveSEQL(selector, document);
|
|
913
|
+
*
|
|
914
|
+
* if (elements.length > 0) {
|
|
915
|
+
* highlightElement(elements[0]);
|
|
916
|
+
* }
|
|
917
|
+
* ```
|
|
918
|
+
*/
|
|
919
|
+
export declare function resolveSEQL(selector: string, root: Document | Element, options?: ResolverOptions): Element[];
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* Resolution status
|
|
923
|
+
* Following SPECIFICATION.md §13.5
|
|
924
|
+
*/
|
|
925
|
+
export declare type ResolveStatus = 'success' | 'ambiguous' | 'error' | 'degraded-fallback';
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* Tier B role values for anchor detection
|
|
929
|
+
* Following SPECIFICATION.md §7
|
|
930
|
+
*/
|
|
931
|
+
export declare const ROLE_ANCHOR_VALUES: string[];
|
|
932
|
+
|
|
933
|
+
/**
|
|
934
|
+
* Tier A semantic anchor tags - highest priority
|
|
935
|
+
* Following SPECIFICATION.md §7
|
|
936
|
+
*/
|
|
937
|
+
export declare const SEMANTIC_ANCHOR_TAGS: string[];
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
* Semantic attributes to extract
|
|
941
|
+
*/
|
|
942
|
+
export declare const SEMANTIC_ATTRIBUTES: string[];
|
|
943
|
+
|
|
944
|
+
/**
|
|
945
|
+
* All semantic tags to include in path
|
|
946
|
+
* Following SPECIFICATION.md §8
|
|
947
|
+
*/
|
|
948
|
+
export declare const SEMANTIC_TAGS: string[];
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* Extracts semantic features from DOM elements
|
|
952
|
+
* Following SPECIFICATION.md §10
|
|
953
|
+
*/
|
|
954
|
+
export declare class SemanticExtractor {
|
|
955
|
+
private includeUtilityClasses;
|
|
956
|
+
private cache?;
|
|
957
|
+
constructor(options: GeneratorOptions, cache?: EIDCache);
|
|
958
|
+
/**
|
|
959
|
+
* Extracts semantic features from element
|
|
960
|
+
* @param element - DOM element to extract from
|
|
961
|
+
* @returns Semantic features object
|
|
962
|
+
*/
|
|
963
|
+
extract(element: Element): ElementSemantics;
|
|
964
|
+
/**
|
|
965
|
+
* Scores element based on semantic richness
|
|
966
|
+
* @param element - Element to score
|
|
967
|
+
* @returns Score from 0 to 1
|
|
968
|
+
*/
|
|
969
|
+
scoreElement(element: Element): number;
|
|
970
|
+
/**
|
|
971
|
+
* Checks if attribute should be ignored
|
|
972
|
+
* @param attrName - Attribute name
|
|
973
|
+
* @returns True if should be ignored
|
|
974
|
+
*/
|
|
975
|
+
private shouldIgnoreAttribute;
|
|
976
|
+
/**
|
|
977
|
+
* Gets attribute priority
|
|
978
|
+
* @param attrName - Attribute name
|
|
979
|
+
* @returns Priority number (higher = more priority)
|
|
980
|
+
*/
|
|
981
|
+
private getAttributePriority;
|
|
982
|
+
/**
|
|
983
|
+
* Checks if attribute value is dynamic (should be ignored)
|
|
984
|
+
* @param value - Attribute value
|
|
985
|
+
* @returns True if value is dynamic
|
|
986
|
+
*/
|
|
987
|
+
private isDynamicValue;
|
|
988
|
+
/**
|
|
989
|
+
* Extracts relevant semantic attributes from element
|
|
990
|
+
* Iterates through all attributes and filters by priority
|
|
991
|
+
*/
|
|
992
|
+
private extractAttributes;
|
|
993
|
+
/**
|
|
994
|
+
* Extracts and normalizes text content
|
|
995
|
+
*/
|
|
996
|
+
private extractText;
|
|
997
|
+
/**
|
|
998
|
+
* Gets direct text content excluding child elements
|
|
999
|
+
*/
|
|
1000
|
+
private getDirectTextContent;
|
|
1001
|
+
/**
|
|
1002
|
+
* Determines if text should be extracted for this element
|
|
1003
|
+
*/
|
|
1004
|
+
private shouldExtractText;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* Filters elements by semantic criteria
|
|
1009
|
+
* Following SPECIFICATION.md §13.2
|
|
1010
|
+
*/
|
|
1011
|
+
export declare class SemanticsMatcher {
|
|
1012
|
+
/**
|
|
1013
|
+
* Filters elements that match the semantics
|
|
1014
|
+
* @param elements - Candidate elements
|
|
1015
|
+
* @param semantics - Target semantics to match
|
|
1016
|
+
* @returns Filtered elements that match
|
|
1017
|
+
*/
|
|
1018
|
+
match(elements: Element[], semantics: ElementSemantics): Element[];
|
|
1019
|
+
/**
|
|
1020
|
+
* Checks if a single element matches the semantics
|
|
1021
|
+
*/
|
|
1022
|
+
private matchElement;
|
|
1023
|
+
/**
|
|
1024
|
+
* Matches text content
|
|
1025
|
+
* Prioritizes direct text nodes, but falls back to full textContent if no direct text
|
|
1026
|
+
*/
|
|
1027
|
+
matchText(element: Element, text: TextContent): boolean;
|
|
1028
|
+
/**
|
|
1029
|
+
* Matches attributes
|
|
1030
|
+
*/
|
|
1031
|
+
matchAttributes(element: Element, attrs: Record<string, string>): boolean;
|
|
1032
|
+
/**
|
|
1033
|
+
* Matches SVG fingerprint
|
|
1034
|
+
*/
|
|
1035
|
+
matchSvgFingerprint(element: SVGElement, fingerprint: SvgFingerprint): boolean;
|
|
1036
|
+
/**
|
|
1037
|
+
* Computes simple path hash (matching SvgFingerprinter)
|
|
1038
|
+
*/
|
|
1039
|
+
private computePathHash;
|
|
1040
|
+
/**
|
|
1041
|
+
* Computes geometry hash for non-path shapes (matching SvgFingerprinter)
|
|
1042
|
+
*/
|
|
1043
|
+
private computeGeomHash;
|
|
1044
|
+
/**
|
|
1045
|
+
* Simple hash function (matching SvgFingerprinter)
|
|
1046
|
+
*/
|
|
1047
|
+
private simpleHash;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
/**
|
|
1051
|
+
* SEQL Selector - canonical string representation of ElementIdentity
|
|
1052
|
+
* Similar to CSS Selector or XPath, but based on semantic features
|
|
1053
|
+
* @example "v1: footer > div.container > ul > li#3 > svg > rect"
|
|
1054
|
+
*/
|
|
1055
|
+
export declare type SeqlSelector = string;
|
|
1056
|
+
|
|
1057
|
+
/**
|
|
1058
|
+
* Options for SEQL Selector stringification
|
|
1059
|
+
*/
|
|
1060
|
+
declare interface StringifyOptions {
|
|
1061
|
+
/** Maximum number of classes to include per node (default: 2) */
|
|
1062
|
+
maxClasses?: number;
|
|
1063
|
+
/** Maximum number of attributes to include per node (default: 5) */
|
|
1064
|
+
maxAttributes?: number;
|
|
1065
|
+
/** Include text content as pseudo-attribute (default: true) */
|
|
1066
|
+
includeText?: boolean;
|
|
1067
|
+
/** Maximum text length to include (default: 50) */
|
|
1068
|
+
maxTextLength?: number;
|
|
1069
|
+
/** Simplify target node by removing redundant info (default: true) */
|
|
1070
|
+
simplifyTarget?: boolean;
|
|
1071
|
+
/** Include resolution constraints in SEQL Selector (default: true) */
|
|
1072
|
+
includeConstraints?: boolean;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
/**
|
|
1076
|
+
* Converts EID to canonical SEQL Selector string representation
|
|
1077
|
+
*
|
|
1078
|
+
* Requirements (per SEQL_SPECIFICATION_v1.0.md):
|
|
1079
|
+
* - Deterministic (same EID → same SEQL Selector)
|
|
1080
|
+
* - Canonical (one EID → one SEQL Selector)
|
|
1081
|
+
* - Versioned (includes protocol version)
|
|
1082
|
+
* - PII-safe (no personal data)
|
|
1083
|
+
* - Sorted attributes and classes
|
|
1084
|
+
*
|
|
1085
|
+
* @param eid - Element Identity Descriptor
|
|
1086
|
+
* @param options - Optional stringify options
|
|
1087
|
+
* @returns SEQL Selector (canonical string)
|
|
1088
|
+
*
|
|
1089
|
+
* @example
|
|
1090
|
+
* ```typescript
|
|
1091
|
+
* const eid = generateEID(element);
|
|
1092
|
+
* const selector = stringifySEQL(eid);
|
|
1093
|
+
* // "v1: footer :: ul.menu > li#3 > a[href="/contact"]"
|
|
1094
|
+
* ```
|
|
1095
|
+
*/
|
|
1096
|
+
export declare function stringifySEQL(eid: ElementIdentity, options?: StringifyOptions): string;
|
|
1097
|
+
|
|
1098
|
+
/**
|
|
1099
|
+
* SVG element fingerprint for stable identification
|
|
1100
|
+
* Following SPECIFICATION.md §9
|
|
1101
|
+
*/
|
|
1102
|
+
export declare interface SvgFingerprint {
|
|
1103
|
+
/** SVG shape type */
|
|
1104
|
+
shape: 'path' | 'circle' | 'rect' | 'line' | 'polyline' | 'polygon' | 'ellipse' | 'g' | 'text' | 'use' | 'svg';
|
|
1105
|
+
/** Hash of path data (first N commands) for <path> elements */
|
|
1106
|
+
dHash?: string;
|
|
1107
|
+
/** Geometry hash for non-path shapes */
|
|
1108
|
+
geomHash?: string;
|
|
1109
|
+
/** Whether element has animations */
|
|
1110
|
+
hasAnimation: boolean;
|
|
1111
|
+
/** ARIA role if present */
|
|
1112
|
+
role?: string;
|
|
1113
|
+
/** <title> text inside SVG */
|
|
1114
|
+
titleText?: string;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
/**
|
|
1118
|
+
* Generates stable fingerprints for SVG elements
|
|
1119
|
+
* Following SPECIFICATION.md §9
|
|
1120
|
+
*/
|
|
1121
|
+
export declare class SvgFingerprinter {
|
|
1122
|
+
/**
|
|
1123
|
+
* Generates fingerprint for SVG element
|
|
1124
|
+
* @param element - SVG element to fingerprint
|
|
1125
|
+
* @returns SVG fingerprint object
|
|
1126
|
+
*/
|
|
1127
|
+
fingerprint(element: SVGElement): SvgFingerprint;
|
|
1128
|
+
/**
|
|
1129
|
+
* Computes hash from path data (first N commands)
|
|
1130
|
+
* @param d - SVG path d attribute value
|
|
1131
|
+
* @returns Hash string
|
|
1132
|
+
*/
|
|
1133
|
+
computePathHash(d: string): string;
|
|
1134
|
+
/**
|
|
1135
|
+
* Gets the shape type from tag name
|
|
1136
|
+
*/
|
|
1137
|
+
private getShape;
|
|
1138
|
+
/**
|
|
1139
|
+
* Normalizes path data for consistent hashing
|
|
1140
|
+
*/
|
|
1141
|
+
private normalizePathData;
|
|
1142
|
+
/**
|
|
1143
|
+
* Computes geometry hash for non-path shapes
|
|
1144
|
+
*/
|
|
1145
|
+
private computeGeomHash;
|
|
1146
|
+
/**
|
|
1147
|
+
* Detects animations on SVG element
|
|
1148
|
+
*/
|
|
1149
|
+
hasAnimation(element: SVGElement): boolean;
|
|
1150
|
+
/**
|
|
1151
|
+
* Simple hash function for fingerprinting (not cryptographic)
|
|
1152
|
+
*/
|
|
1153
|
+
private simpleHash;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
/**
|
|
1157
|
+
* Target node - the element being identified
|
|
1158
|
+
*/
|
|
1159
|
+
export declare interface TargetNode extends PathNode {
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
/**
|
|
1163
|
+
* Text content with normalization
|
|
1164
|
+
* Following SPECIFICATION.md §11
|
|
1165
|
+
*/
|
|
1166
|
+
export declare interface TextContent {
|
|
1167
|
+
/** Original text (for debugging) */
|
|
1168
|
+
raw: string;
|
|
1169
|
+
/** Normalized text (trimmed, collapsed whitespace) */
|
|
1170
|
+
normalized: string;
|
|
1171
|
+
/** Matching mode for text comparison */
|
|
1172
|
+
matchMode?: 'exact' | 'partial';
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
/**
|
|
1176
|
+
* Text proximity constraint (Levenshtein distance)
|
|
1177
|
+
*/
|
|
1178
|
+
export declare interface TextProximityConstraint extends Constraint {
|
|
1179
|
+
type: 'text-proximity';
|
|
1180
|
+
params: {
|
|
1181
|
+
reference: string;
|
|
1182
|
+
maxDistance: number;
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
/**
|
|
1187
|
+
* Uniqueness constraint
|
|
1188
|
+
*/
|
|
1189
|
+
export declare interface UniquenessConstraint extends Constraint {
|
|
1190
|
+
type: 'uniqueness';
|
|
1191
|
+
params: {
|
|
1192
|
+
mode: 'strict' | 'best-score' | 'allow-multiple';
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* Validates EID structure for correctness
|
|
1198
|
+
* @param eid - The Element Identity to validate
|
|
1199
|
+
* @returns Validation result with errors and warnings
|
|
1200
|
+
*/
|
|
1201
|
+
export declare function validateEID(eid: ElementIdentity): ValidationResult;
|
|
1202
|
+
|
|
1203
|
+
/**
|
|
1204
|
+
* Validation result
|
|
1205
|
+
*/
|
|
1206
|
+
export declare interface ValidationResult {
|
|
1207
|
+
/** Whether DSL is valid */
|
|
1208
|
+
valid: boolean;
|
|
1209
|
+
/** Validation errors */
|
|
1210
|
+
errors: string[];
|
|
1211
|
+
/** Validation warnings */
|
|
1212
|
+
warnings: string[];
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
export { }
|