feat(element-selector): add stable selector config hashing - #1841
Draft
jxiwang wants to merge 4 commits into
Draft
feat(element-selector): add stable selector config hashing#1841jxiwang wants to merge 4 commits into
jxiwang wants to merge 4 commits into
Conversation
…uting Extracted from #1832. - Move canonical legacyCssPath walker into @amplitude/element-selector - Add generateSelector top-level helper for null-engine call sites - Route engine.generate through kill-switch and safety-net fallbacks - Publish package (remove private flag) - Bump size-limit cap to absorb consolidated walker
Add a deterministic fingerprint of the resolved selector-algorithm config so the autocapture zoning events (Page Viewed, Element Clicked, Rage Click, Viewport Content Updated) can record which config was active when they fired. - canonicalizeSelectorConfig: RFC 8785 (JCS) canonical JSON of a JSON-safe snapshot of ResolvedSelectorConfig. Hashes the fully-resolved config so an omitted field and an explicit default produce the same hash. NFC-normalizes strings; serializes RegExp via toString() so flags are part of the fingerprint; normalizes undefined depth to null. - hashSelectorConfig: synchronous SHA-256 (lowercase hex) of the canonical string. Sync + dependency-free so it works in insecure (http) contexts and on the synchronous tracking path, unlike crypto.subtle. - AMPLITUDE_EVENT_PROP_SELECTOR_ALGO_CONFIG_HASH constant, centralized here so the three independent emitting plugins can share one property key. Plugin integration lands separately.
size-limit report 📦
|
… merge The 'Merge main' commit left an extra blank line before the closing brace of createSelectorEngine, which failed the prettier lint check. Align with main.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a deterministic fingerprint of the resolved selector-algorithm config to
@amplitude/element-selector, so the autocapture "zoning" events ([Amplitude] Page Viewed,[Amplitude] Element Clicked,[Amplitude] Rage Click,[Amplitude] Viewport Content Updated) can later record which algorithm configuration was active when they fired.This PR is purely the element-selector primitives. Plugin integration (wiring the hash onto the actual events) lands separately. The constant and hash function live here because the four events are emitted by three independent plugins in separate packages (autocapture, frustration, page-view-tracking) — none can import from another, but all can depend on
@amplitude/element-selector, making it the single source of truth.What's added
canonicalizeSelectorConfig(config)— RFC 8785 (JCS) canonical JSON of a JSON-safe snapshot ofResolvedSelectorConfig, via thecanonicalizenpm package. Canonicalization decisions:canonicalize).toString()(/source/flags), not.source— the defaultautogeneratedIdPatternsships a flagged regex (/^[a-f0-9]{16,}$/i), and.sourcewould silently drop the flag. Pattern array order is preserved (it's part of the config).maxAncestorWalkDepth: undefinednormalized tonull.hashSelectorConfig(config)— synchronous SHA-256 (lowercase hex) of the canonical string.crypto.subtlebecause the latter is async and unavailable in insecure (http) contexts — both fatal for attaching a value on the synchronous tracking path. Output is byte-for-byte identical to Node'scrypto/TextEncoder(verified against a 500+ input corpus incl. multi-byte UTF-8, surrogate pairs, and all padding boundaries; lone surrogates map to U+FFFD to matchTextEncoder).AMPLITUDE_EVENT_PROP_SELECTOR_ALGO_CONFIG_HASH='[Amplitude] Selector Algo Config Hash'— centralized here so all three plugins share one property key.toSelectorConfigSnapshot,sha256Hex, typeSelectorConfigSnapshot.Verification
pnpm --filter @amplitude/element-selector test— 278 passed (added 37 tests acrosssha256andhash-config).pnpm build,pnpm lint(0 errors),pnpm docs:check— all pass.size-limit: element-selector ESM 3.28 kB / 7 kB cap (canonicalize + SHA-256 added ~0.6 kB gzipped).Checklist