@veltdev/sdk
Version:
Velt is an SDK to add collaborative features to your product within minutes. Example: Comments like Figma, Frame.io, Google docs or sheets, Recording like Loom, Huddles like Slack and much more.
110 lines (109 loc) • 3.08 kB
TypeScript
/**
* Content hash for secure, privacy-preserving element validation.
*/
export interface ContentHash {
/** MD5 hash value (base36 encoded, ~12 characters) */
value: string;
/** Hashing algorithm (always 'md5') */
algorithm: 'md5';
/** Source of hash (always 'textContent') */
source: 'textContent';
}
/**
* Robust anchor record for reliable DOM element re-location.
*
* Survives:
* - Page reloads
* - Framework re-renders (React, Vue, Angular)
* - Dynamic ID changes
* - Minor DOM restructuring
*
* Does not survive:
* - Major redesigns
* - Content reordering (sort, filter)
* - Element removal
*
* **Resolution Strategy (priority order):**
* 1. id (90) - Stable, non-dynamic ID
* 2. css (80/60) - Attribute selector
* 3. robustXPath (50) - Attribute-based path
* 4. containerHints (40) - Scoped search
* 5. xPath variants (32-28) - Structural fallback
* 6. contentHash (15) - Hash-based scan
*
* **Validation boosts:** tagName (+10), contentHash (+30)
*
* **Security:** No plaintext storage, MD5 hash only.
*/
export interface AnchorRecord {
/** Schema version (current: "1.0") */
version: '1.0';
/**
* Stable element ID (non-dynamic only).
*
* Excluded patterns:
* - yui_* (YUI framework)
*/
id?: string;
/** Tag name (uppercase, e.g., 'DIV', 'BUTTON') */
tagName: string;
/**
* CSS selector from stable attributes.
*
* Example: `[data-testid='submit-btn'][role='button']`
*/
elementSelector?: string;
/**
* XPath variants (in order of stability):
*
* 1. robustXPath - Attribute-based (MOST STABLE)
* - Prioritizes: data-* > role > stable ID > aria-* > position
* - Example: `//div[@role='main']/.../li[5]/span`
* - Ignores dynamic IDs
* - Stops at landmarks (main, nav, etc.)
*
* 2. xPath - Basic XPath (uses IDs when available)
* 3. cfXPath - Positional with class hints
* 4. fXPath - Pure positional (most fragile)
*/
robustXPath?: string;
xPath?: string;
fXPath?: string;
cfXPath?: string;
/**
* Content hash for secure validation.
*/
contentHash?: ContentHash;
/** Creation timestamp (milliseconds since epoch) */
createdAt?: number;
/** Parent element anchor record */
parent?: AnchorRecord;
}
/**
* Result of anchor resolution.
*/
export interface AnchorResolution {
/** Resolved element (null if not found) */
element: Element | null;
/**
* Resolution method used.
* Values: 'id', 'css', 'robustXPath', 'xPath', 'cfXPath', 'fXPath', 'contentHash', 'ancestor+tag'
*/
matchedBy?: string;
/**
* Confidence score (0-120+).
*
* - 90+: High (unique ID)
* - 80-89: Good (unique CSS, stable attributes)
* - 40-79: Moderate (scoped search, multiple candidates)
* - 15-39: Low (XPath, hash-based fallback)
*/
score?: number;
/**
* Score breakdown.
*/
scoreBreakdown?: {
method: string;
score: number;
}[];
}