@cognior/iap-sdk 0.0.2 → 0.2.0

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.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
- # Digital Adoption Platform (DAP) SDK
1
+ # Intelligent Adoption Platform (IAP) SDK
2
2
 
3
- A framework-agnostic JavaScript/TypeScript SDK for creating interactive user flows, onboarding experiences, tooltips, surveys, and walkthroughs in web applications.
3
+ A framework-agnostic JavaScript/TypeScript SDK for creating interactive user flows, onboarding experiences, tooltips, modals, surveys, and walkthroughs in web applications.
4
+
5
+ This README is for **end users integrating the SDK from the npm registry**.
4
6
 
5
7
  ## Overview
6
8
 
@@ -46,1072 +48,174 @@ The DAP SDK enables developers to create guided user experiences driven by backe
46
48
  - **Mobile**: Responsive design with touch support
47
49
  - **Accessibility**: WCAG 2.1 AA compliant components
48
50
 
49
- ## Installation
51
+ ---
50
52
 
51
- ### Option A: NPM Package (Recommended for Modern Development)
53
+ ## Install
52
54
 
53
55
  ```bash
54
- # Install via npm
55
- npm install @cognior/dap-sdk
56
-
57
- # Or install via yarn
58
- yarn add @cognior/dap-sdk
59
- ```
60
-
61
- **ES Modules (Webpack, Vite, Rollup)**
62
- ```javascript
63
- import { init, setUser } from '@cognior/dap-sdk';
64
-
65
- await init({
66
- configUrl: 'https://api.yourcompany.com/config'
67
- });
68
-
69
- setUser({
70
- id: 'user_123',
71
- role: 'admin',
72
- email: 'admin@company.com'
73
- });
74
- ```
75
-
76
- **CommonJS (Node.js, Legacy Bundlers)**
77
- ```javascript
78
- const { init, setUser } = require('@cognior/dap-sdk');
79
-
80
- init({
81
- configUrl: 'https://api.yourcompany.com/config'
82
- }).then(() => {
83
- setUser({
84
- id: 'user_123',
85
- role: 'admin'
86
- });
87
- });
56
+ npm install @cognior/iap-sdk
57
+ # or
58
+ yarn add @cognior/iap-sdk
88
59
  ```
89
60
 
90
- ### Option B: Script Tag (Quick Setup/Testing)
91
-
92
- ```html
93
- <!DOCTYPE html>
94
- <html>
95
- <head>
96
- <!-- Load DAP SDK -->
97
- <script src="https://cdn.your-domain.com/dap-sdk/latest/dap.min.js"></script>
98
- </head>
99
- <body>
100
- <script>
101
- // Initialize after page load
102
- window.addEventListener('DOMContentLoaded', async () => {
103
- await window.DAP.init({
104
- configUrl: 'https://api.your-domain.com/config',
105
- debug: false
106
- });
107
-
108
- // Set user context for personalized experiences
109
- window.DAP.setUser({
110
- id: 'user_123',
111
- role: 'user',
112
- email: 'user@company.com'
113
- });
114
- });
115
- </script>
116
- </body>
117
- </html>
118
- ```
119
-
120
- ### Option C: Direct Download
121
-
122
- Download the latest build files from the [releases page](https://github.com/CogniorAI/WebUserModule/releases) and include in your project:
123
-
124
- - `index.umd.js` - For script tag usage (global `DAP` variable)
125
- - `index.esm.js` - For ES module imports
126
- - `index.cjs.js` - For CommonJS require()
127
- - `index.d.ts` - TypeScript definitions
128
-
129
- ## SDK Initialization
130
-
131
- ### Required Configuration
132
-
133
- | Option | Description | Example |
134
- |--------|-------------|---------|
135
- | `configUrl` | URL to fetch DAP configuration | `"https://api.dap.com/config"` |
136
-
137
- ### Optional Configuration
138
-
139
- | Option | Description | Default |
140
- |--------|-------------|---------|
141
- | `debug` | Enable verbose console logging | `false` |
142
- | `screenId` | Custom screen identifier | Current pathname |
143
- | `user` | Initial user context for personalized flows | `undefined` |
144
-
145
- ### Example Initialization
146
-
147
- ```javascript
148
- // Basic initialization
149
- await DAP.init({
150
- configUrl: 'https://api.yourcompany.com/config',
151
- debug: false
152
- });
61
+ ---
153
62
 
154
- // With user context and debug mode
155
- await DAP.init({
156
- configUrl: 'https://api.yourcompany.com/config',
157
- debug: true,
158
- screenId: 'dashboard',
159
- user: {
160
- id: 'user_123',
161
- role: 'admin',
162
- email: 'admin@company.com',
163
- attributes: {
164
- department: 'engineering',
165
- subscription: 'enterprise'
166
- }
167
- }
168
- });
169
- ```
63
+ ## What you need to integrate
170
64
 
171
- ### Configuration File Format
65
+ ### 1) A configuration endpoint (`configUrl`) (required)
66
+ You must provide a URL that returns the IAP configuration JSON.
172
67
 
173
- The `configUrl` should return a JSON configuration with the following structure:
68
+ Example response:
174
69
 
175
70
  ```json
176
71
  {
177
72
  "organizationid": "your-org-id",
178
- "siteid": "your-site-id",
73
+ "siteid": "your-site-id",
179
74
  "apikey": "your-api-key",
180
75
  "apiurl": "https://api.yourcompany.com",
181
76
  "enableDraggableModals": true
182
77
  }
183
-
184
- ## User Context Management
185
-
186
- ### Setting User Information
187
-
188
- The SDK supports comprehensive user context management for personalized experiences and analytics. User information should be provided after initialization or when user state changes.
189
-
190
- #### User Data Structure
191
-
192
- ```typescript
193
- interface DapUser {
194
- id: string; // Required: Unique user identifier
195
- role?: string; // Optional: User role (admin, user, guest)
196
- email?: string; // Optional: User email address
197
- attributes?: Record<string, string>; // Optional: Custom user attributes
198
- }
199
78
  ```
200
79
 
201
- #### Setting User Context
202
-
203
- ```javascript
204
- // Set complete user context
205
- DAP.setUser({
206
- id: 'user_12345',
207
- role: 'premium',
208
- email: 'user@company.com',
209
- attributes: {
210
- department: 'engineering',
211
- experience_level: 'advanced',
212
- subscription: 'pro',
213
- signup_date: '2024-01-15'
214
- }
215
- });
216
-
217
- // Update existing user context (merges with existing data)
218
- DAP.updateUser({
219
- role: 'admin',
220
- attributes: {
221
- last_login: '2024-01-22'
222
- }
223
- });
224
-
225
- // Get current user context
226
- const user = DAP.getUser();
227
- console.log('Current user:', user);
80
+ ### 2) Initialization in your app (required)
81
+ Initialize once (typically on app startup) and pass `configUrl`.
228
82
 
229
- // Clear user context (for logout)
230
- DAP.clearUser();
231
- ```
83
+ ---
232
84
 
233
- #### Integration Examples
85
+ ## Usage (recommended): ES Modules (Webpack/Vite/Rollup)
234
86
 
235
- **React Integration**
236
87
  ```javascript
237
- // In your authentication component
238
- useEffect(() => {
239
- if (authUser) {
240
- DAP.setUser({
241
- id: authUser.id,
242
- role: authUser.role,
243
- email: authUser.email,
244
- attributes: {
245
- subscription_tier: authUser.subscription,
246
- signup_date: authUser.createdAt,
247
- last_active: new Date().toISOString()
248
- }
249
- });
250
- } else {
251
- DAP.clearUser();
252
- }
253
- }, [authUser]);
254
- ```
255
-
256
- **Angular Integration**
257
- ```typescript
258
- // In your auth service
259
- @Injectable()
260
- export class AuthService {
261
- private updateDapUser(user: User) {
262
- DAP.setUser({
263
- id: user.id,
264
- role: user.role,
265
- email: user.email,
266
- attributes: {
267
- department: user.department,
268
- experience_level: user.experience,
269
- feature_flags: user.featureFlags?.join(',') || ''
270
- }
271
- });
272
- }
273
- }
274
- ```
88
+ import { init, setUser } from "@cognior/iap-sdk";
275
89
 
276
- **Login/Logout Workflow**
277
- ```javascript
278
- // On successful login
279
- async function handleLogin(credentials) {
280
- const user = await authenticate(credentials);
281
-
282
- // Set user context for DAP
283
- DAP.setUser({
284
- id: user.id,
285
- role: user.role,
286
- email: user.email,
287
- attributes: {
288
- login_method: 'email',
289
- user_segment: user.segment,
290
- onboarding_completed: user.onboardingCompleted.toString()
291
- }
292
- });
293
-
294
- // Flows will now be evaluated with user context
295
- }
296
-
297
- // On logout
298
- function handleLogout() {
299
- DAP.clearUser();
300
- // User-specific flows will stop, anonymous flows may continue
301
- }
302
- ```
303
-
304
- ### User Context Benefits
305
-
306
- #### Personalized Experiences
307
- ```javascript
308
- // Flows can target specific user roles
309
- {
310
- "targeting": {
311
- "userAttributes": {
312
- "role": "admin",
313
- "experience_level": "beginner"
314
- }
315
- }
316
- }
317
-
318
- // Dynamic content based on user data
319
- {
320
- "modalContent": {
321
- "title": "Welcome {{user.attributes.department}} Team!"
322
- }
323
- }
324
- ```
325
-
326
- #### Analytics & Insights
327
- - **User Journey Tracking**: Complete user flow analytics
328
- - **Segmentation**: Analyze behavior by role, department, subscription tier
329
- - **Personalization**: Adapt experiences based on user attributes
330
- - **A/B Testing**: Target specific user segments for experiments
331
-
332
- #### Privacy & Security
333
- - **Data Minimization**: Only required data is stored
334
- - **Session Storage**: User context persists only during browser session
335
- - **Anonymous Fallback**: SDK works without user context using anonymous IDs
336
- - **Secure Handling**: No sensitive data logged or exposed
337
-
338
- ### Best Practices
339
-
340
- #### Required vs Optional Data
341
- ```javascript
342
- // ✅ Minimal required data
343
- DAP.setUser({
344
- id: 'user_123' // Only ID is required
90
+ await init({
91
+ configUrl: "https://api.yourcompany.com/config",
92
+ debug: false
345
93
  });
346
94
 
347
- // Rich context for better targeting
348
- DAP.setUser({
349
- id: 'user_123',
350
- role: 'admin',
95
+ // Optional: set user context for targeting and analytics
96
+ setUser({
97
+ id: "user_123",
98
+ role: "admin",
99
+ email: "admin@company.com",
351
100
  attributes: {
352
- subscription: 'enterprise',
353
- onboarding_step: '3'
101
+ department: "engineering"
354
102
  }
355
103
  });
356
104
  ```
357
105
 
358
- #### Attribute Naming Conventions
359
- ```javascript
360
- // ✅ Use consistent, descriptive attribute names
361
- attributes: {
362
- 'subscription_tier': 'pro',
363
- 'signup_date': '2024-01-15',
364
- 'feature_access': 'advanced',
365
- 'user_segment': 'power_user'
366
- }
367
-
368
- // ❌ Avoid unclear or inconsistent naming
369
- attributes: {
370
- 'sub': 'pro', // Too abbreviated
371
- 'dt': '2024-01-15', // Unclear meaning
372
- 'hasAccess': 'true' // Inconsistent format
373
- }
374
- ```
375
-
376
- #### Timing Considerations
377
- ```javascript
378
- // ✅ Set user context early in app lifecycle
379
- async function initializeApp() {
380
- // Initialize DAP with user context
381
- await DAP.init({
382
- configUrl: 'https://api.yourcompany.com/config',
383
- user: currentUser,
384
- debug: process.env.NODE_ENV === 'development'
385
- });
386
-
387
- // Flows will evaluate with proper context immediately
388
- }
389
-
390
- // ✅ Update context on relevant changes
391
- function handleSubscriptionUpgrade(newTier) {
392
- DAP.updateUser({
393
- attributes: {
394
- subscription_tier: newTier,
395
- upgrade_date: new Date().toISOString()
396
- }
397
- });
398
- }
399
- ```
400
-
401
- #### Error Handling
402
- ```javascript
403
- try {
404
- DAP.setUser({
405
- id: user.id,
406
- role: user.role,
407
- email: user.email,
408
- attributes: userAttributes
409
- });
410
- } catch (error) {
411
- console.warn('Failed to set DAP user context:', error);
412
- // Application continues to work, flows may use anonymous context
413
- }
414
- ```
415
-
416
- ## Embedding the SDK
417
-
418
- ### Single Page Applications (SPA)
106
+ ---
419
107
 
420
- For SPAs, initialize the SDK once and it will automatically track page changes:
108
+ ## Usage: CommonJS
421
109
 
422
110
  ```javascript
423
- // Initialize once on app startup
424
- await DAP.init({
425
- configUrl: 'https://api.yourcompany.com/config',
426
- debug: false,
427
- user: currentUser // Optional: set initial user context
428
- });
429
-
430
- // The SDK automatically detects route changes via:
431
- // - History API changes (pushState/replaceState)
432
- // - PopState events (back/forward buttons)
433
- // - Hash changes
434
- // No manual refresh needed for most frameworks
435
- ```
436
-
437
- ### Multi-Page Applications (MPA)
111
+ const { init, setUser } = require("@cognior/iap-sdk");
438
112
 
439
- Initialize on each page load:
440
-
441
- ```javascript
442
- // Add to your main JavaScript file
443
- window.addEventListener('DOMContentLoaded', async () => {
444
- await DAP.init({
445
- configUrl: 'https://api.yourcompany.com/config'
446
- });
447
- // Flows automatically start based on page context
113
+ init({
114
+ configUrl: "https://api.yourcompany.com/config"
115
+ }).then(() => {
116
+ setUser({ id: "user_123" });
448
117
  });
449
118
  ```
450
119
 
451
- ### Page Change Detection
452
-
453
- The SDK automatically detects:
454
- - Browser navigation (back/forward buttons)
455
- - History API changes (`pushState`/`replaceState`)
456
- - Hash changes
457
- - Manual page transitions
120
+ ---
458
121
 
459
- ### Selector Best Practices
122
+ ## Usage: Script tag (UMD)
460
123
 
461
- Use stable, semantic selectors for reliable step targeting:
124
+ If you can’t use bundlers/modules, you can load the UMD build and access the global variable.
462
125
 
463
126
  ```html
464
- <!-- ✅ Good: Stable, semantic selectors -->
465
- <button data-dap="onboarding-next" id="next-step">Next</button>
466
- <div class="user-profile" data-testid="profile-section">...</div>
467
-
468
- <!-- ❌ Avoid: Generated classes, fragile selectors -->
469
- <button class="btn-x7j2k9">Next</button>
470
- <div class="css-1234567">...</div>
471
- ```
472
-
473
- ## Flow Execution Model
474
-
475
- ### Execution Types
476
-
477
- **Linear Flows**: Steps execute in sequential order
478
- ```json
479
- {
480
- "execution": {
481
- "mode": "Linear"
482
- },
483
- "steps": [
484
- { "stepOrder": 1, "stepType": "Mandatory", "stepId": "step1" },
485
- { "stepOrder": 2, "stepType": "Optional", "stepId": "step2" },
486
- { "stepOrder": 3, "stepType": "Mandatory", "stepId": "step3" }
487
- ]
488
- }
489
- ```
490
-
491
- **AnyOrder Flows**: Steps can be completed in any sequence
492
- ```json
493
- {
494
- "execution": {
495
- "mode": "AnyOrder"
496
- },
497
- "steps": [
498
- { "stepType": "Mandatory", "stepId": "intro" },
499
- { "stepType": "Optional", "stepId": "tooltip1" },
500
- { "stepType": "Mandatory", "stepId": "survey" }
501
- ]
502
- }
503
- ```
504
-
505
- ### Step Types
506
-
507
- - **Mandatory**: Required for flow completion
508
- - **Optional**: Can be skipped without blocking flow completion
509
-
510
- ### Trigger Precedence
511
-
512
- 1. `step.trigger` - Direct step trigger override
513
- 2. `step.uxExperience.elementTrigger` - Component-specific trigger
514
- 3. Default component trigger (e.g., "click" for buttons)
515
-
516
- ### Rule-based Branching
517
-
518
- Steps can include conditional rules that determine next flow transitions:
519
-
520
- ```json
521
- {
522
- "stepType": "Rule",
523
- "userInputSelector": "#user-role-select",
524
- "conditionRuleBlocks": [
525
- {
526
- "ruleBlockId": "admin-path",
527
- "rules": [{"condition": "equals", "value": "admin"}],
528
- "nextFlowId": "admin-onboarding"
529
- },
530
- {
531
- "ruleBlockId": "user-path",
532
- "rules": [{"condition": "equals", "value": "user"}],
533
- "nextFlowId": "user-onboarding"
534
- }
535
- ]
536
- }
537
- ```
538
-
539
- ## Trigger System
540
-
541
- ### Trigger Types
542
-
543
- | Type | Description | Example |
544
- |------|-------------|---------|
545
- | **Dom** | Element interaction triggers | `click`, `hover`, `focus`, `blur` |
546
- | **Input** | Form input events | `change`, `input`, `keydown`, `keyup` |
547
- | **Lifecycle** | Page/application events | `page load`, `on page load`, `pageload` |
548
-
549
- ### Trigger Normalization
550
-
551
- The SDK automatically normalizes trigger strings from the backend:
552
-
553
- ```javascript
554
- // These all normalize to the same trigger:
555
- "click" → "click"
556
- "on click" → "click"
557
- "Click" → "click"
558
-
559
- // Hover triggers:
560
- "hover" → "mouseenter"
561
- "on hover" → "mouseenter"
562
- "mouseover" → "mouseenter"
563
-
564
- // Page load triggers:
565
- "page load" → "pageload" (synthetic)
566
- "on page load" → "pageload" (synthetic)
567
- "pageload" → "pageload" (synthetic)
568
-
569
- // Input triggers:
570
- "input" → "input"
571
- "typing" → "input"
572
- "on input" → "input"
573
- ```
574
-
575
- ### Single vs Composite Triggers
576
-
577
- **Single Triggers**: Direct element events
578
- ```json
579
- {
580
- "elementSelector": "#get-started-btn",
581
- "elementTrigger": "click"
582
- }
583
- ```
584
-
585
- **Normalized Triggers**: Backend trigger strings are automatically normalized
586
- ```json
587
- {
588
- "elementSelector": "#form-input",
589
- "elementTrigger": "on input" // Becomes "input" event
590
- }
591
- ```
592
-
593
- ### Debounce and Once Behavior
594
-
595
- - **Debounce**: Prevents rapid-fire trigger execution
596
- - **Once**: Ensures triggers fire only once per session
597
- - **Automatic**: Intelligent trigger management for optimal UX
598
-
599
- ## Analytics & Telemetry
600
-
601
- ### Captured Events
602
-
603
- - **Flow Events**: Start, complete, abandon, skip
604
- - **Step Events**: View, interact, complete, error
605
- - **User Behavior**: Click patterns, time on step, navigation paths
606
- - **Performance**: Load times, render performance, error rates
607
-
608
- ### Event Timing
609
-
610
- - **Real-time**: Critical events sent immediately
611
- - **Batched**: Non-critical events batched for efficiency
612
- - **Offline**: Events queued when offline, sent when reconnected
613
-
614
- ### Privacy Considerations
615
-
616
- - **User Consent**: Respects user privacy preferences
617
- - **Data Minimization**: Only necessary data collected
618
- - **Anonymization**: Personal data anonymized by default
619
- - **GDPR Compliant**: Supports data protection regulations
620
-
621
- ### Debug vs Production Logging
622
-
623
- ```javascript
624
- // Enable debug mode for development
625
- await DAP.init({
626
- configUrl: 'https://api.yourcompany.com/config',
627
- debug: true // Verbose console logging
628
- });
629
-
630
- // Production mode (default)
631
- await DAP.init({
632
- configUrl: 'https://api.yourcompany.com/config'
633
- }); // Minimal logging
634
- ```
635
-
636
- ## Error Handling & Debugging
637
-
638
- ### Common Issues
639
-
640
- **Selector Not Found**
641
- ```javascript
642
- // Check selector specificity
643
- console.log(document.querySelector('#my-button'));
644
-
645
- // Ensure element exists before step triggers
646
- await DAP.waitForElement('#my-button', { timeout: 5000 });
647
- ```
648
-
649
- **Step Not Triggering**
650
- ```javascript
651
- // Verify trigger configuration
652
- console.log(step.elementTrigger); // Check trigger type
653
- console.log(step.elementSelector); // Verify selector
654
-
655
- // Check page context
656
- console.log(DAP.getCurrentPageContext());
657
- ```
658
-
659
- **Flow Not Starting**
660
- ```javascript
661
- // Verify flow targeting
662
- console.log(await DAP.getVisibleFlows()); // Check available flows
663
- console.log(DAP.isFlowRelevant(flowId)); // Check relevance
664
- ```
665
-
666
- ### Debug Mode
667
-
668
- Enable detailed logging for troubleshooting:
669
-
670
- ```javascript
671
- // Set debug flag globally
672
- window.__DAP_DEBUG__ = true;
673
-
674
- // Or via initialization
675
- await DAP.initialize({ ...config, debug: true });
676
-
677
- // Console output will include:
678
- // [DAP] Flow evaluation started
679
- // [DAP] Step triggered: tooltip-1
680
- // [DAP] Selector resolved: #help-button
681
- // [DAP] Analytics event sent: step_view
682
- ```
683
-
684
- ### Console Log Levels
685
-
686
- | Level | Purpose | Example |
687
- |-------|---------|---------|
688
- | `debug` | Detailed execution flow | Step transitions, selector resolution |
689
- | `info` | General information | Flow starts, completions |
690
- | `warn` | Potential issues | Missing selectors, deprecated features |
691
- | `error` | Critical problems | API failures, configuration errors |
692
-
693
- ## SDK Development Setup
694
-
695
- ### Prerequisites
696
-
697
- - **Node.js**: Version 18+ required
698
- - **Package Manager**: npm 8+ or yarn 1.22+
699
- - **TypeScript**: 5.0+ for type safety
700
-
701
- ### Local Development Setup
702
-
703
- ```bash
704
- # Clone the repository
705
- git clone https://github.com/your-org/dap-sdk.git
706
- cd dap-sdk
707
-
708
- # Install dependencies
709
- npm install
710
-
711
- # Start development server with hot reload
712
- npm run dev
713
-
714
- # Build for production
715
- npm run build
716
-
717
- # Serve built files locally (serves on http://localhost:5173)
718
- npm run serve
719
- ```
720
-
721
- ### Project Structure
722
-
723
- ```
724
- src/
725
- ├── core/ # Core engine and flow management
726
- │ ├── flowEngine.ts # Main flow execution engine
727
- │ └── triggerManager.ts # Trigger system management
728
- ├── experiences/ # UI component renderers
729
- │ ├── modal.ts # Modal experience
730
- │ ├── tooltip.ts # Tooltip experience
731
- │ ├── survey.ts # Survey components
732
- │ └── ... # Other UI experiences
733
- ├── services/ # Core services
734
- │ ├── flowManager.ts # Flow lifecycle management
735
- │ ├── userContextService.ts # User context tracking
736
- │ └── pageContextService.ts # Page navigation tracking
737
- ├── utils/ # Utility functions
738
- │ ├── selectors.ts # DOM selector helpers
739
- │ ├── analytics.ts # Analytics and tracking
740
- │ └── validation.ts # Input validation
741
- └── styles/ # Component styles
742
- ├── modal.css.ts # Modal styling
743
- └── ... # Other component styles
744
- ```
745
-
746
- ### Key Components
747
-
748
- - **FlowEngine**: Orchestrates flow execution and step management
749
- - **TriggerManager**: Handles DOM event binding and trigger evaluation
750
- - **PageContextService**: Tracks page navigation and context changes
751
- - **UserContextService**: Manages user state and preferences
752
- - **ValidationInterceptor**: Handles form validation integration
753
-
754
- ## Running & Testing
755
-
756
- ### Local Testing Strategy
757
-
758
- 1. **Development Server**: Use `npm run dev` for hot reloading
759
- 2. **Test Pages**: Create HTML pages in `public/` for manual testing
760
- 3. **Flow JSON**: Place test flow configurations in `public/test-flows/`
761
- 4. **Browser DevTools**: Use debug mode for real-time inspection
762
-
763
- ### Sample Flow JSON for Testing
764
-
765
- ```json
766
- {
767
- "flowId": "test-onboarding",
768
- "flowName": "Test Onboarding Flow",
769
- "execution": {
770
- "mode": "Linear",
771
- "frequency": {
772
- "type": "OneTime",
773
- "maxRuns": 1
774
- }
775
- },
776
- "steps": [
777
- {
778
- "stepId": "welcome-modal",
779
- "stepOrder": 1,
780
- "stepType": "Mandatory",
781
- "uxExperience": {
782
- "uxExperienceType": "modal",
783
- "elementSelector": "body",
784
- "elementTrigger": "immediate",
785
- "modalContent": {
786
- "title": "Welcome!",
787
- "body": [
788
- { "kind": "text", "html": "<p>Welcome to our application!</p>" },
789
- { "kind": "text", "html": "<p>Let's get you started!</p>" }
790
- ]
791
- }
792
- }
793
- },
794
- {
795
- "stepId": "feature-tooltip",
796
- "stepOrder": 2,
797
- "stepType": "Optional",
798
- "uxExperience": {
799
- "uxExperienceType": "tooltip",
800
- "elementSelector": "#main-feature",
801
- "elementTrigger": "hover",
802
- "content": {
803
- "text": "This is our main feature!"
804
- }
805
- }
806
- }
807
- ]
808
- }
127
+ <!doctype html>
128
+ <html>
129
+ <head>
130
+ <script src="https://unpkg.com/@cognior/iap-sdk@latest/dist/index.umd.js"></script>
131
+ </head>
132
+ <body>
133
+ <script>
134
+ window.addEventListener("DOMContentLoaded", async () => {
135
+ await window.DAP.init({
136
+ configUrl: "https://api.yourcompany.com/config",
137
+ debug: false
138
+ });
139
+
140
+ window.DAP.setUser({
141
+ id: "user_123",
142
+ role: "user"
143
+ });
144
+ });
145
+ </script>
146
+ </body>
147
+ </html>
809
148
  ```
810
149
 
811
- ### Debug Tips
812
-
813
- ```javascript
814
- // Inspect current SDK state
815
- console.log(DAP.getFlowState());
150
+ > Note: the UMD build exposes a global `DAP` variable (as shown above). This is part of the runtime API.
816
151
 
817
- // Check user context
818
- console.log(DAP.getUserState());
819
-
820
- // Execute custom flow
821
- await DAP.executeFlow(customFlowData);
822
-
823
- // Register flow for later execution
824
- DAP.registerFlow(flowData);
825
-
826
- // Start registered flow by ID
827
- await DAP.startFlow('my-flow-id');
828
-
829
- // Validate selectors
830
- const element = DAP.resolveSelector('#my-button'); // Returns element or null
152
+ ---
831
153
 
832
- // Debug utilities (only available when debug=true)
833
- if (window.__DAP_DEBUG__) {
834
- await DAP.testFlow('flow-id'); // Test specific flow
835
- DAP.renderModal(modalConfig); // Test modal rendering
836
- }
154
+ ## API (common integration points)
155
+
156
+ ### `init(opts)` (required)
157
+ Initializes the SDK.
158
+
159
+ ```ts
160
+ init(opts: {
161
+ configUrl: string;
162
+ debug?: boolean;
163
+ screenId?: string;
164
+ user?: {
165
+ id: string;
166
+ role?: string;
167
+ email?: string;
168
+ attributes?: Record<string, string>;
169
+ };
170
+ }): Promise<void>;
837
171
  ```
838
172
 
839
- ## Advanced API
840
-
841
- ### Flow Management
173
+ ### User context (optional but recommended)
174
+ Use user context to enable personalized experiences and better analytics.
842
175
 
843
- #### Register Custom Flows
844
176
  ```javascript
845
- // Register a flow for later execution
846
- DAP.registerFlow({
847
- flowId: 'custom-onboarding',
848
- flowName: 'Custom Onboarding Flow',
849
- execution: {
850
- mode: 'Linear',
851
- frequency: { type: 'OneTime', maxRuns: 1 }
852
- },
853
- steps: [
854
- {
855
- stepId: 'welcome',
856
- stepOrder: 1,
857
- stepType: 'Mandatory',
858
- uxExperience: {
859
- uxExperienceType: 'modal',
860
- elementTrigger: 'immediate',
861
- modalContent: {
862
- title: 'Welcome!',
863
- body: [{ kind: 'text', html: '<p>Welcome to our app!</p>' }]
864
- }
865
- }
866
- }
867
- ]
868
- });
177
+ import { setUser, updateUser, getUser, clearUser } from "@cognior/iap-sdk";
869
178
 
870
- // Execute registered flow
871
- await DAP.startFlow('custom-onboarding');
872
- ```
179
+ setUser({ id: "user_123", role: "admin" });
873
180
 
874
- #### Execute Dynamic Flows
875
- ```javascript
876
- // Execute a flow without registering
877
- await DAP.executeFlow({
878
- flowId: 'dynamic-help',
879
- flowName: 'Dynamic Help Flow',
880
- steps: [
881
- {
882
- stepId: 'help-tooltip',
883
- uxExperience: {
884
- uxExperienceType: 'tooltip',
885
- elementSelector: '#help-button',
886
- elementTrigger: 'hover',
887
- content: { text: 'Click here for help!' }
888
- }
889
- }
890
- ]
181
+ updateUser({
182
+ attributes: { subscription_tier: "pro" }
891
183
  });
892
- ```
893
-
894
- ### Debug and Development
895
-
896
- #### State Inspection
897
- ```javascript
898
- // Get current flow engine state
899
- const flowState = DAP.getFlowState();
900
- console.log('Active flow:', flowState.activeFlowId);
901
- console.log('Flow in progress:', flowState.flowInProgress);
902
184
 
903
- // Get user context debug state
904
- const userState = DAP.getUserState();
905
- console.log('Has user:', userState.hasUser);
906
- console.log('User ID:', userState.userId);
907
- console.log('Is anonymous:', userState.isAnonymous);
908
- ```
185
+ console.log(getUser());
909
186
 
910
- #### Element Resolution
911
- ```javascript
912
- // Test selector resolution (useful for debugging)
913
- const element = DAP.resolveSelector('#my-button');
914
- if (element) {
915
- console.log('Element found:', element);
916
- } else {
917
- console.warn('Element not found');
918
- }
187
+ clearUser(); // on logout
919
188
  ```
920
189
 
921
- #### Debug Mode Features
922
- ```javascript
923
- // Available only when debug=true during initialization
924
- if (window.__DAP_DEBUG__) {
925
- // Test any flow by ID
926
- await DAP.testFlow('flow-id-from-backend');
927
-
928
- // Test modal rendering directly
929
- DAP.renderModal({
930
- title: 'Test Modal',
931
- body: [{ kind: 'text', html: '<p>Testing modal</p>' }]
932
- });
933
- }
934
- ```
935
-
936
- ### Core Services Access
937
-
938
- For advanced use cases, you can access core services directly:
939
-
940
- ```javascript
941
- // Location context service
942
- const locationService = DAP.locationContext;
943
- console.log('Current context:', locationService.getContext());
944
-
945
- // User context service
946
- const userService = DAP.userContext;
947
- console.log('Analytics context:', userService.getAnalyticsContext());
948
-
949
- // Flow engine (use with caution)
950
- const engine = DAP.flowEngine;
951
- console.log('Engine state:', engine.getState());
952
- ```
953
-
954
- ## Configuration Reference
955
-
956
- ### Execution Configuration
957
-
958
- ```typescript
959
- interface ExecutionConfig {
960
- mode: 'Linear' | 'AnyOrder';
961
- multiPage?: boolean; // Enable multi-page flows
962
- frequency?: {
963
- type: 'OneTime' | 'Daily' | 'Weekly' | 'Monthly';
964
- maxRuns: number; // Maximum execution count
965
- };
966
- targeting?: {
967
- pages?: string[]; // URL patterns
968
- userSegments?: string[]; // User segments
969
- devices?: string[]; // Device types
970
- };
971
- }
972
- ```
973
-
974
- ### Trigger Configuration
975
-
976
- ```typescript
977
- interface TriggerConfig {
978
- elementSelector: string; // CSS selector
979
- elementTrigger: string; // Event type
980
- debounce?: number; // Debounce delay (ms)
981
- once?: boolean; // Fire only once
982
- conditions?: string[]; // Additional conditions
983
- }
984
- ```
985
-
986
- ### Step Configuration
987
-
988
- ```typescript
989
- interface StepConfig {
990
- stepId: string;
991
- stepOrder?: number; // For Linear flows
992
- stepType: 'Mandatory' | 'Optional' | 'Rule';
993
- uxExperience: UXExperience;
994
- targeting?: PageTargeting; // Step-specific targeting
995
- }
996
- ```
997
-
998
- ### Rule Configuration
999
-
1000
- ```typescript
1001
- interface RuleConfig {
1002
- userInputSelector: string; // Input element selector
1003
- conditionRuleBlocks: {
1004
- ruleBlockId: string;
1005
- rules: {
1006
- condition: 'equals' | 'contains' | 'matches';
1007
- value: string;
1008
- }[];
1009
- nextFlowId: string; // Target flow for this rule
1010
- }[];
1011
- }
1012
- ```
1013
-
1014
- ## FAQ
1015
-
1016
- ### Why isn't my step triggering?
1017
-
1018
- 1. **Check selector**: Verify the element exists: `document.querySelector(selector)`
1019
- 2. **Check page context**: Ensure you're on the correct page
1020
- 3. **Check timing**: Element might not be ready; add delays or use `waitForElement`
1021
- 4. **Check trigger type**: Verify the trigger event is appropriate for the element
1022
-
1023
- ### How does multi-page support work?
1024
-
1025
- The SDK automatically:
1026
- - Detects page navigation events
1027
- - Preserves flow state across pages
1028
- - Re-evaluates step relevance on each page
1029
- - Handles both SPA and traditional page navigation
1030
-
1031
- ### Why are rules evaluated late in the flow?
1032
-
1033
- Rule steps are evaluated when:
1034
- - The user interacts with the specified input element
1035
- - Input value changes trigger rule evaluation
1036
- - This allows for dynamic flow branching based on user choices
1037
-
1038
- ### How do I avoid selector issues?
1039
-
1040
- 1. **Use stable selectors**: Prefer `data-*` attributes over CSS classes
1041
- 2. **Test selectors**: Verify selectors work in browser DevTools
1042
- 3. **Add fallbacks**: Provide alternative selectors when possible
1043
- 4. **Use semantic HTML**: Leverage semantic elements with stable attributes
1044
-
1045
- ### Can I customize component styles?
1046
-
1047
- Yes! Components support:
1048
- - **CSS custom properties**: Override default styles
1049
- - **Theme configuration**: Pass custom themes via flow JSON
1050
- - **Style injection**: Inject custom CSS for specific experiences
1051
-
1052
- ### How do I handle dynamic content?
1053
-
1054
- - **Observer patterns**: SDK automatically observes DOM changes
1055
- - **Refresh triggers**: Call `DAP.refreshFlows()` after content updates
1056
- - **Dynamic selectors**: Use flexible selectors that work with dynamic IDs
1057
-
1058
- ## Versioning & Compatibility
1059
-
1060
- ### SDK Versioning
1061
-
1062
- The SDK follows [Semantic Versioning](https://semver.org/):
1063
-
1064
- - **Major** (X.0.0): Breaking changes, requires code updates
1065
- - **Minor** (0.X.0): New features, backward compatible
1066
- - **Patch** (0.0.X): Bug fixes, backward compatible
190
+ ---
1067
191
 
1068
- ### Flow JSON Compatibility
192
+ ## Integration guidance
1069
193
 
1070
- - **Backward Compatible**: New SDK versions support older Flow JSON schemas
1071
- - **Deprecation Notices**: Old features marked deprecated with migration guidance
1072
- - **Schema Evolution**: New flow features added incrementally
194
+ ### Single Page Apps (React/Angular/Vue/etc.)
195
+ - Initialize once on app startup.
196
+ - Set/clear user context when auth state changes.
1073
197
 
1074
- ### Upgrade Notes
198
+ ### Multi Page Apps
199
+ - Initialize on each page load (e.g., `DOMContentLoaded`).
1075
200
 
1076
- ```javascript
1077
- // Version 2.x 3.x Migration Example
1078
- // OLD (deprecated)
1079
- await DAP.init(config);
201
+ ### Selector best practices (for experiences that target elements)
202
+ Use stable selectors where possible (e.g., `data-*` attributes) to avoid breakage when CSS classes change.
1080
203
 
1081
- // NEW (recommended)
1082
- await DAP.initialize(config);
1083
-
1084
- // Check for deprecation warnings in console during development
204
+ ```html
205
+ <button data-iap="onboarding-next">Next</button>
1085
206
  ```
1086
207
 
1087
- ### Browser Support Policy
1088
-
1089
- - **Current**: Support for current and previous major browser versions
1090
- - **Legacy**: Best-effort support for IE 11 (with polyfills)
1091
- - **Testing**: Automated testing across major browser combinations
1092
-
1093
- ## License & Support
1094
-
1095
- ### License
1096
-
1097
- This SDK is proprietary software licensed under the [Your Company License Agreement]. See `LICENSE.md` for complete terms.
1098
-
1099
- ### Support & Contact
1100
-
1101
- - **Documentation**: [https://docs.your-company.com/dap-sdk](https://docs.your-company.com/dap-sdk)
1102
- - **Support Portal**: [https://support.your-company.com](https://support.your-company.com)
1103
- - **Community Forum**: [https://community.your-company.com](https://community.your-company.com)
1104
- - **Email Support**: [dap-support@your-company.com](mailto:dap-support@your-company.com)
1105
-
1106
- ### Contributing
208
+ ---
1107
209
 
1108
- We welcome contributions from the community! Please see `CONTRIBUTING.md` for guidelines on:
210
+ ## Build outputs (what you get when installed)
1109
211
 
1110
- - Code standards and style guide
1111
- - Testing requirements
1112
- - Pull request process
1113
- - Issue reporting templates
212
+ - `dist/index.esm.js` ES Module build
213
+ - `dist/index.cjs.js` — CommonJS build
214
+ - `dist/index.umd.js` UMD build (script tag / global)
215
+ - `dist/index.d.ts` TypeScript definitions
1114
216
 
1115
217
  ---
1116
218
 
1117
- **Built with ❤️ by the DAP Team**
219
+ ## License
220
+
221
+ See [LICENSE](LICENSE).