Skip to content

chore(element-selector): scaffold element selector types#1779

Open
jxiwang wants to merge 8 commits into
mainfrom
jessewang/sr-4608-element-selector-primitives-types-pattern-packs-helpers
Open

chore(element-selector): scaffold element selector types#1779
jxiwang wants to merge 8 commits into
mainfrom
jessewang/sr-4608-element-selector-primitives-types-pattern-packs-helpers

Conversation

@jxiwang
Copy link
Copy Markdown
Collaborator

@jxiwang jxiwang commented May 27, 2026

Summary

Second PR in the v1 element-selector groundwork chain. Lands the static + primitive pieces of @amplitude/element-selector: type definitions, both regex pattern packs, helper functions, and the two v1 strategies. Each piece is independently unit-tested — nothing drives them together yet. The orchestrator, fallback, config resolver, and engine factory land in the follow-up PR (SR-4609).

Closes SR-4608.

What's in this PR

Types (src/types.ts)

  • Strategy, StrategyContext — pluggable-strategy interface
  • ResolvedSelectorConfig — runtime config consumed by strategies / orchestrator / fallback
  • ElementSelectorRemoteConfig — remote-config payload shape (every field optional)
  • SelectorEngine — public engine interface (implementation lands in the orchestration PR)

Pattern packs

  • patterns/autogenerated-ids.tsDEFAULT_AUTOGENERATED_ID_PATTERNS (React useId, Radix, Headless UI, MUI, hex hashes, trailing-digit timestamps, 4+ consecutive digits) + compile() + isStableId()
  • patterns/unstable-classes.tsDEFAULT_UNSTABLE_CLASS_PATTERNS (Tailwind utilities + variants, CSS-in-JS / build hashes, Swiper / MUI / Radix runtime state classes) + compile() + filterClasses()

Helpers

  • helpers/get-stable-id.ts — single source of truth for "is this element's id usable?" (honors the explicit-tracking-attribute suppression signal + the autogen filter)
  • helpers/describe-relative.ts — positional descent builder, emits tag:nth-of-type(n)

Strategies

  • strategies/explicit-tracking-attribute.ts — anchor on data-amp-track-id (or the customer-configured attribute name)
  • strategies/stable-id.ts — anchor on tag#id when the id survives getStableId

Tests — one file per source file, all running on jsdom; pattern packs are table-driven with positive and negative cases drawn from real React / Radix / Headless UI / MUI / Swiper / Tailwind / CSS-modules / Emotion / styled-components samples.

What's NOT in this PR

  • Orchestrator with ancestor walk → SR-4609
  • fallbackCssPath → SR-4609
  • resolveSelectorConfig → SR-4609
  • createSelectorEngine factory + the runtime SelectorEngine instance → SR-4609
  • Logger integration with @amplitude/analytics-core → SR-4641 (verification PR)
  • Property tests, scenarios corpus, JSON schema, README → SR-4641

Why a separate package

The selector algorithm needs to be consumed by three surfaces — the autocapture SDK plugin, the app.amplitude.com tagging UI, and the Chrome extension visual tagger. Standing it up as a shared package now avoids the "copy the algorithm into each consumer" pattern currently in place with the legacy cssPath. Design doc at packages/plugin-autocapture-browser/element-selector-strategy-v1-no-classes.md.

Stack

Branches off SR-4560 (scaffolding, already merged). The next PR (SR-4609, orchestration) branches off this one.

Test plan

  • pnpm --filter @amplitude/element-selector test passes
  • pnpm --filter @amplitude/element-selector lint passes
  • pnpm --filter @amplitude/element-selector build produces both ESM + CJS output
  • No runtime dependencies added beyond tslib (logger integration arrives in SR-4641)
  • No exports added to src/index.ts that aren't documented in the design doc

Checklist

  • Does your PR title have the correct title format?
  • Does your PR have a breaking change?:

Note

Low Risk
New library code and exports only; no runtime wiring to autocapture yet, and behavior is covered by unit tests.

Overview
This PR expands @amplitude/element-selector from a placeholder entry point into the v1 foundation: public types (Strategy, ResolvedSelectorConfig, ElementSelectorRemoteConfig, SelectorEngine), default autogenerated-id and unstable-class regex packs with compile / isStableId / filterClasses, helpers (getStableId, describeRelative, internal escapeCssIdentifier), and the first two strategies (explicit tracking attribute, stable tag#id). index.ts now re-exports that surface for SDK, dashboard, and extension consumers.

Orchestrator, fallback walker, config resolver, and SelectorEngine implementation are intentionally out of scope (follow-up PR). Each new module ships with jsdom unit tests, including table-driven pattern coverage.

Reviewed by Cursor Bugbot for commit 9758d21. Bugbot is set up for automated code reviews on this repo. Configure here.

@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 27, 2026

SR-4608

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 27, 2026

size-limit report 📦

Path Size
packages/analytics-browser/lib/scripts/amplitude-min.js.gz 58.38 KB (0%)
packages/session-replay-browser/lib/scripts/session-replay-browser-min.js.gz 132.01 KB (0%)
packages/unified/lib/scripts/amplitude-min.umd.js.gz 209.43 KB (0%)

@jxiwang jxiwang force-pushed the jessewang/sr-4560-eng-001-set-up-amplitudeelement-selector-package branch 2 times, most recently from b6a7080 to b5fb5b7 Compare May 27, 2026 23:01
Base automatically changed from jessewang/sr-4560-eng-001-set-up-amplitudeelement-selector-package to main May 28, 2026 22:34
@jxiwang jxiwang force-pushed the jessewang/sr-4608-element-selector-primitives-types-pattern-packs-helpers branch from 64876df to f941f96 Compare June 2, 2026 22:52
@jxiwang jxiwang changed the title chore: scaffold element selector types chore(element-selector): scaffold element selector types Jun 2, 2026
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
@jxiwang jxiwang marked this pull request as ready for review June 2, 2026 23:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant