-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Phase 1 - Display Condition Plugins #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
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
…cture - Add trigger state tracking to core Context type - Implement trigger:* event listener in ExperienceRuntime - Create exitIntentPlugin with Pathfora-compatible algorithm - Mouse position tracking (last 30 positions) - Upward movement detection with velocity check - Configurable: sensitivity, minTimeOnPage, delay, disableOnMobile - Session-based suppression (one trigger per session) - Clean API: isTriggered(), reset(), getPositions() - Add comprehensive test suite (21 tests covering all Pathfora use cases) - Event-driven pattern: plugins emit events, core orchestrates evaluation - Composable: use context.triggers.exitIntent.triggered in custom rules Foundation for all display condition plugins (scroll depth, page visits, etc). All tests passing (222 total, up from 201).
- spec.md: goals, scope, user stories, architecture - plan.md: implementation details for all 4 plugins - tasks.md: 14 GitHub issues (tasks 1-2 complete) Exit intent plugin complete. Remaining: scroll depth, page visits, time delay.
All 13 tasks completed: - Core runtime + types - Plugins (frequency, debug, banner) - Integration + testing - Playground deployed (https://xp-examples.vercel.app/) - Bundle size: 8.4 KB gzipped (target: <15 KB) 222 tests passing, docs complete.
Phase 0 (Foundation) is complete. Phase 1 (Display Conditions) is next. No intermediate phase needed.
- Multiple thresholds support [25, 50, 75, 100] default - Configurable throttling (100ms default) - Max scroll percentage tracking - Both viewport calculation methods (inclusive/exclusive) - Reset capability for SPAs and testing - Resize handling for responsive layouts - Device detection (mobile/tablet/desktop) with opt-out - Advanced metrics (opt-in via trackAdvancedMetrics flag): * Velocity tracking (scroll speed, px/ms) * Direction change detection (seeking behavior) * Time-to-threshold metrics (engagement speed) * Engagement quality scoring (0-100) * Time spent scrolling up (UX friction indicator) - TypeScript types for all configs - Comprehensive test suite (25 tests, 100% coverage) Closes #34
Session and lifetime visit tracking for client-side SDKs. Features: - Session-scoped counter (sessionStorage) - Lifetime counter with timestamps (localStorage) - First-visit detection - DNT (Do Not Track) support - Automatic storage plugin loading - TTL/expiration for GDPR compliance - Event emission (pageVisits:incremented, pageVisits:reset) - Generic sdk-kit plugin (designed for contribution back) - Composable with frequencyPlugin Plugin follows sdk-kit patterns: - Reuses storagePlugin for persistence - Event-driven architecture (same as exitIntent/scrollDepth) - Auto-registers in ExperienceRuntime - Updates Context triggers for evaluation API: - getTotalCount(): number - getSessionCount(): number - isFirstVisit(): boolean - getFirstVisitTime(): number | undefined - getLastVisitTime(): number | undefined - increment(): void - reset(): void - getState(): PageVisitsEvent Tests: - 36 comprehensive tests covering all features - Session and lifetime counting - First-visit detection - DNT support - Storage persistence - API methods - Event emission - Custom configuration - Integration scenarios All tests pass (283/283 total) Related to #35
- Convert index files to barrel exports
- Extract pure functions for improved testability:
- Exit Intent: isMobileDevice, hasMinTimeElapsed,
calculateVelocity, shouldTriggerExitIntent,
createExitIntentEvent
- Scroll Depth: detectDevice, throttle,
calculateScrollPercent, calculateEngagementScore
- Page Visits: respectsDNT, buildStorageKey,
createVisitsEvent
- Update biome.json to allow 'any' in plugin impl files
- Remove all biome-ignore comments from codebase
All tests passing (283/283), linting clean
- Create time delay plugin with millisecond precision - Support pause/resume on Page Visibility API - Track active vs total elapsed time - Extract pure functions for testability - Expose API: getElapsed, getActiveElapsed, getRemaining, isPaused, isTriggered, reset - Auto-register in core runtime - Add 19 comprehensive tests (302 total passing) - Update TriggerState interface for timeDelay - Barrel export pattern for clean imports Event-driven architecture with full timer lifecycle management
- Test plugin composition (all 4 plugins loaded together) - Test multiple triggers firing independently - Test complex targeting logic (AND, OR, NOT) - Test performance (overhead, memory leaks) - Test cleanup on destroy - Test real-world scenarios (engaged user, returning visitor, first-time welcome) 12 new tests, 314 total tests passing
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.
Phase 1: Display Condition Plugins
Implements 4 industry-leading display condition plugins with event-driven architecture, comprehensive testing, and complete documentation.
Overview
This PR implements the complete Phase 1 display condition plugins system with modern, composable, event-driven architecture.
What's Included
🎯 Display Condition Plugins (4 new plugins)
Exit Intent Plugin - Closes [Phase 1] Scroll Depth Plugin #34
Scroll Depth Plugin - Closes [Phase 1] Scroll Depth Plugin #34
Page Visits Plugin - Closes [Phase 1] Page Visits Plugin #35
Time Delay Plugin - Closes [Phase 1] Time Delay Plugin #36
🏗️ Core Infrastructure
trigger:*events, core listens & updates contextTriggerStateinterface✅ Integration & Testing - Closes #37
📚 Documentation - Closes #32
🔧 Developer Experience
anyin plugin implementation files for flexibilityKey Features
Composability
Plugins work independently or together using custom targeting logic:
Advanced Metrics
Scroll Depth Plugin tracks:
Privacy-First
Page Visits Plugin:
Breaking Changes
None. All changes are backward compatible.
Stats
Testing
All 314 tests passing ✅
Next Steps
experience-sdk-playgroundrepo