@prosdevlab/experience-sdk-plugins 0.1.0 → 0.1.4

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.
@@ -0,0 +1,17 @@
1
+
2
+ > @prosdevlab/experience-sdk-plugins@0.1.4 build /home/runner/work/experience-sdk/experience-sdk/packages/plugins
3
+ > tsup
4
+
5
+ CLI Building entry: src/index.ts
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v8.5.1
8
+ CLI Using tsup config: /home/runner/work/experience-sdk/experience-sdk/packages/plugins/tsup.config.ts
9
+ CLI Target: es2024
10
+ CLI Cleaning output folder
11
+ ESM Build start
12
+ ESM dist/index.js 19.53 KB
13
+ ESM dist/index.js.map 48.09 KB
14
+ ESM ⚡️ Build success in 140ms
15
+ DTS Build start
16
+ DTS ⚡️ Build success in 857ms
17
+ DTS dist/index.d.ts 5.46 KB
package/CHANGELOG.md ADDED
@@ -0,0 +1,63 @@
1
+ # @prosdevlab/experience-sdk-plugins
2
+
3
+ ## 0.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - df2c286: feat(banner): add pushDown option to push content down instead of overlay
8
+
9
+ Add optional `pushDown` config to banner plugin that allows top banners to smoothly push page content down (add margin-top) instead of overlaying it.
10
+
11
+ **Usage:**
12
+
13
+ ```typescript
14
+ init({
15
+ banner: {
16
+ position: "top",
17
+ pushDown: "header", // CSS selector of element to push down
18
+ },
19
+ });
20
+ ```
21
+
22
+ **Benefits:**
23
+
24
+ - Opt-in feature (default behavior unchanged)
25
+ - Smooth transition with CSS animations
26
+ - Improves UX for sticky navigation
27
+ - Automatically removes margin when banner is dismissed
28
+
29
+ ## 0.1.3
30
+
31
+ ### Patch Changes
32
+
33
+ - 41c0aa5: Fix npm publishing error by adding repository field to package.json
34
+
35
+ - Add repository field required for npm provenance verification
36
+
37
+ ## 0.1.2
38
+
39
+ ### Patch Changes
40
+
41
+ - a6842e2: Fix npm publishing error by adding repository field to package.json
42
+
43
+ - Add repository field required for npm provenance verification
44
+
45
+ ## 0.1.1
46
+
47
+ ### Patch Changes
48
+
49
+ - c5e46c0: Fix BannerContent type definition, add CSS customization support, and implement HTML sanitization:
50
+
51
+ - Add `buttons` array property with variant and metadata support
52
+ - Add `position` property (top/bottom)
53
+ - Make `title` optional (message is the only required field)
54
+ - Add `className` and `style` props for banner and buttons
55
+ - Update banner plugin to use `.xp-*` CSS classes
56
+ - Provide minimal, functional default styles
57
+ - Add HTML sanitizer for XSS prevention in title and message fields
58
+ - Support safe HTML tags (strong, em, a, br, span, b, i, p)
59
+ - Block dangerous tags and event handlers
60
+ - Sanitize URLs to prevent javascript: and data: attacks
61
+ - Aligns core types with banner plugin implementation
62
+
63
+ This enables users to customize banners with Tailwind, design systems, or CSS frameworks while maintaining SDK's focus on targeting logic. HTML sanitization ensures safe rendering of user-provided content.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 prosdevlab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,154 @@
1
+ # @prosdevlab/experience-sdk-plugins
2
+
3
+ Official plugins for [Experience SDK](https://github.com/prosdevlab/experience-sdk).
4
+
5
+ **Size:** 13.4 KB (ESM)
6
+
7
+ ## Included Plugins
8
+
9
+ ### Banner Plugin
10
+
11
+ Renders banner experiences in the DOM with automatic positioning, theming, and responsive layout.
12
+
13
+ **Features:**
14
+ - Multiple buttons with variants (primary, secondary, link)
15
+ - Responsive layout (desktop inline, mobile stack)
16
+ - Automatic theme detection (light/dark mode)
17
+ - Top/bottom positioning
18
+ - Dismissable with close button
19
+ - **CSS customization** via `className` and `style` props
20
+ - Stable `.xp-*` CSS classes for styling
21
+
22
+ ```typescript
23
+ import { createInstance, bannerPlugin } from '@prosdevlab/experience-sdk-plugins';
24
+
25
+ const sdk = createInstance();
26
+ sdk.use(bannerPlugin);
27
+
28
+ sdk.banner.show({
29
+ id: 'welcome',
30
+ type: 'banner',
31
+ content: {
32
+ title: 'Welcome!',
33
+ message: 'Thanks for visiting.',
34
+ buttons: [
35
+ { text: 'Get Started', url: '/start', variant: 'primary' }
36
+ ],
37
+ position: 'top',
38
+ dismissable: true
39
+ }
40
+ });
41
+ ```
42
+
43
+ **Customization:**
44
+
45
+ The banner plugin uses `.xp-*` CSS classes and supports custom styling:
46
+
47
+ ```typescript
48
+ // With Tailwind
49
+ content: {
50
+ message: 'Flash Sale!',
51
+ className: 'bg-gradient-to-r from-blue-600 to-purple-600 text-white',
52
+ buttons: [{
53
+ text: 'Shop Now',
54
+ className: 'bg-white text-blue-600 hover:bg-gray-100'
55
+ }]
56
+ }
57
+
58
+ // With inline styles
59
+ content: {
60
+ message: 'Flash Sale!',
61
+ style: {
62
+ background: 'linear-gradient(90deg, #667eea 0%, #764ba2 100%)',
63
+ color: 'white'
64
+ }
65
+ }
66
+ ```
67
+
68
+ See the [Plugins documentation](https://prosdevlab.github.io/experience-sdk/reference/plugins#customization) for more customization examples.
69
+
70
+ ### Frequency Plugin
71
+
72
+ Manages impression tracking and frequency capping with persistent storage.
73
+
74
+ **Features:**
75
+ - Session/day/week impression tracking
76
+ - Automatic storage management
77
+ - Manual impression recording
78
+ - Reset capabilities
79
+
80
+ ```typescript
81
+ import { createInstance, frequencyPlugin } from '@prosdevlab/experience-sdk-plugins';
82
+
83
+ const sdk = createInstance();
84
+ sdk.use(frequencyPlugin);
85
+
86
+ // Check impression count
87
+ const count = sdk.frequency.getImpressionCount('welcome', 'session');
88
+
89
+ // Record impression
90
+ sdk.frequency.recordImpression('welcome');
91
+
92
+ // Reset counts
93
+ sdk.frequency.reset('welcome');
94
+ ```
95
+
96
+ ### Debug Plugin
97
+
98
+ Provides console logging and window event emission for debugging and Chrome extension integration.
99
+
100
+ **Features:**
101
+ - Console logging with prefix
102
+ - Window event emission
103
+ - Automatic decision logging
104
+ - Configurable logging levels
105
+
106
+ ```typescript
107
+ import { createInstance, debugPlugin } from '@prosdevlab/experience-sdk-plugins';
108
+
109
+ const sdk = createInstance({ debug: true });
110
+ sdk.use(debugPlugin);
111
+
112
+ // Manual logging
113
+ sdk.debug.log('Custom message', { foo: 'bar' });
114
+
115
+ // Listen to debug events
116
+ window.addEventListener('experiences:debug', (event) => {
117
+ console.log(event.detail);
118
+ });
119
+ ```
120
+
121
+ ## Installation
122
+
123
+ ```bash
124
+ npm install @prosdevlab/experience-sdk-plugins
125
+ ```
126
+
127
+ Or use the main package which includes these plugins:
128
+
129
+ ```bash
130
+ npm install @prosdevlab/experience-sdk
131
+ ```
132
+
133
+ ## Usage
134
+
135
+ These plugins are automatically included when using `@prosdevlab/experience-sdk`. You only need this package if you want to use the plugins separately with a custom sdk-kit setup.
136
+
137
+ ```typescript
138
+ import { createInstance } from '@prosdevlab/experience-sdk';
139
+
140
+ // Plugins are already included and available
141
+ const experiences = createInstance({ debug: true });
142
+ experiences.register('banner', { ... });
143
+ ```
144
+
145
+ ## Documentation
146
+
147
+ - [Full Documentation](https://prosdevlab.github.io/experience-sdk)
148
+ - [Plugins Guide](https://prosdevlab.github.io/experience-sdk/reference/plugins)
149
+ - [Banner Examples](https://prosdevlab.github.io/experience-sdk/demo/banner)
150
+
151
+ ## License
152
+
153
+ MIT
154
+
@@ -0,0 +1,230 @@
1
+ import { PluginFunction } from '@lytics/sdk-kit';
2
+
3
+ /**
4
+ * Shared types for Experience SDK plugins
5
+ * These types are re-exported by core for user convenience
6
+ */
7
+ /**
8
+ * Experience content - varies by type
9
+ */
10
+ type ExperienceContent = BannerContent | ModalContent | TooltipContent;
11
+ /**
12
+ * Banner content configuration
13
+ */
14
+ interface BannerContent {
15
+ title?: string;
16
+ message: string;
17
+ buttons?: Array<{
18
+ text: string;
19
+ action?: string;
20
+ url?: string;
21
+ variant?: 'primary' | 'secondary' | 'link';
22
+ metadata?: Record<string, any>;
23
+ className?: string;
24
+ style?: Record<string, string>;
25
+ }>;
26
+ dismissable?: boolean;
27
+ position?: 'top' | 'bottom';
28
+ className?: string;
29
+ style?: Record<string, string>;
30
+ }
31
+ /**
32
+ * Modal content configuration
33
+ */
34
+ interface ModalContent {
35
+ title: string;
36
+ message: string;
37
+ confirmText?: string;
38
+ cancelText?: string;
39
+ }
40
+ /**
41
+ * Modal content configuration
42
+ */
43
+ interface ModalContent {
44
+ title: string;
45
+ message: string;
46
+ confirmText?: string;
47
+ cancelText?: string;
48
+ }
49
+ /**
50
+ * Tooltip content configuration
51
+ */
52
+ interface TooltipContent {
53
+ message: string;
54
+ position?: 'top' | 'bottom' | 'left' | 'right';
55
+ }
56
+ /**
57
+ * Tooltip content configuration
58
+ */
59
+ interface TooltipContent {
60
+ message: string;
61
+ position?: 'top' | 'bottom' | 'left' | 'right';
62
+ }
63
+ /**
64
+ * Experience definition
65
+ */
66
+ interface Experience {
67
+ id: string;
68
+ type: 'banner' | 'modal' | 'tooltip';
69
+ targeting: Record<string, any>;
70
+ content: ExperienceContent;
71
+ frequency?: {
72
+ max: number;
73
+ per: 'session' | 'day' | 'week';
74
+ };
75
+ priority?: number;
76
+ }
77
+ /**
78
+ * Decision output from evaluation
79
+ */
80
+ interface Decision {
81
+ show: boolean;
82
+ experienceId?: string;
83
+ reasons: string[];
84
+ trace: TraceStep[];
85
+ context: Record<string, any>;
86
+ metadata: DecisionMetadata;
87
+ }
88
+ /**
89
+ * Trace step for decision path
90
+ */
91
+ interface TraceStep {
92
+ step: string;
93
+ timestamp: number;
94
+ duration: number;
95
+ input?: any;
96
+ output?: any;
97
+ passed: boolean;
98
+ }
99
+ /**
100
+ * Decision metadata
101
+ */
102
+ interface DecisionMetadata {
103
+ evaluatedAt: number;
104
+ experienceCount: number;
105
+ evaluationTimeMs: number;
106
+ }
107
+
108
+ /**
109
+ * Banner Plugin
110
+ *
111
+ * Renders banner experiences at the top or bottom of the page.
112
+ * Auto-shows banners when experiences are evaluated.
113
+ */
114
+
115
+ interface BannerPluginConfig {
116
+ banner?: {
117
+ position?: 'top' | 'bottom';
118
+ dismissable?: boolean;
119
+ zIndex?: number;
120
+ pushDown?: string;
121
+ };
122
+ }
123
+ interface BannerPlugin {
124
+ show(experience: Experience): void;
125
+ remove(): void;
126
+ isShowing(): boolean;
127
+ }
128
+ /**
129
+ * Banner Plugin
130
+ *
131
+ * Automatically renders banner experiences when they are evaluated.
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * import { createInstance } from '@prosdevlab/experience-sdk';
136
+ * import { bannerPlugin } from '@prosdevlab/experience-sdk-plugins';
137
+ *
138
+ * // Basic usage (banner overlays at top)
139
+ * const sdk = createInstance({
140
+ * banner: {
141
+ * position: 'top',
142
+ * dismissable: true
143
+ * }
144
+ * });
145
+ * sdk.use(bannerPlugin);
146
+ *
147
+ * // With pushDown (pushes navigation down instead of overlaying)
148
+ * const sdk = createInstance({
149
+ * banner: {
150
+ * position: 'top',
151
+ * dismissable: true,
152
+ * pushDown: 'header' // CSS selector of element to push down
153
+ * }
154
+ * });
155
+ * sdk.use(bannerPlugin);
156
+ * ```
157
+ */
158
+ declare const bannerPlugin: PluginFunction;
159
+
160
+ /**
161
+ * Debug Plugin
162
+ *
163
+ * Emits structured debug events to window and optionally logs to console.
164
+ * Useful for debugging and Chrome extension integration.
165
+ */
166
+
167
+ interface DebugPluginConfig {
168
+ debug?: {
169
+ enabled?: boolean;
170
+ console?: boolean;
171
+ window?: boolean;
172
+ };
173
+ }
174
+ interface DebugPlugin {
175
+ log(message: string, data?: unknown): void;
176
+ isEnabled(): boolean;
177
+ }
178
+ /**
179
+ * Debug Plugin
180
+ *
181
+ * Listens to all SDK events and emits them as window events for debugging.
182
+ * Also optionally logs to console.
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * import { createInstance } from '@prosdevlab/experience-sdk';
187
+ * import { debugPlugin } from '@prosdevlab/experience-sdk-plugins';
188
+ *
189
+ * const sdk = createInstance({ debug: { enabled: true, console: true } });
190
+ * sdk.use(debugPlugin);
191
+ * ```
192
+ */
193
+ declare const debugPlugin: PluginFunction;
194
+
195
+ /**
196
+ * Frequency Capping Plugin
197
+ *
198
+ * Tracks experience impressions and enforces frequency caps.
199
+ * Uses sdk-kit's storage plugin for persistence.
200
+ */
201
+
202
+ interface FrequencyPluginConfig {
203
+ frequency?: {
204
+ enabled?: boolean;
205
+ namespace?: string;
206
+ };
207
+ }
208
+ interface FrequencyPlugin {
209
+ getImpressionCount(experienceId: string): number;
210
+ hasReachedCap(experienceId: string, max: number, per: 'session' | 'day' | 'week'): boolean;
211
+ recordImpression(experienceId: string): void;
212
+ }
213
+ /**
214
+ * Frequency Capping Plugin
215
+ *
216
+ * Automatically tracks impressions and enforces frequency caps.
217
+ * Requires storage plugin for persistence.
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * import { createInstance } from '@prosdevlab/experience-sdk';
222
+ * import { frequencyPlugin } from '@prosdevlab/experience-sdk-plugins';
223
+ *
224
+ * const sdk = createInstance({ frequency: { enabled: true } });
225
+ * sdk.use(frequencyPlugin);
226
+ * ```
227
+ */
228
+ declare const frequencyPlugin: PluginFunction;
229
+
230
+ export { type BannerContent, type BannerPlugin, type BannerPluginConfig, type DebugPlugin, type DebugPluginConfig, type Decision, type DecisionMetadata, type Experience, type ExperienceContent, type FrequencyPlugin, type FrequencyPluginConfig, type ModalContent, type TooltipContent, type TraceStep, bannerPlugin, debugPlugin, frequencyPlugin };