@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 +107 -1003
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.umd.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
#
|
|
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
|
-
|
|
51
|
+
---
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
## Install
|
|
52
54
|
|
|
53
55
|
```bash
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
65
|
+
### 1) A configuration endpoint (`configUrl`) (required)
|
|
66
|
+
You must provide a URL that returns the IAP configuration JSON.
|
|
172
67
|
|
|
173
|
-
|
|
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
|
-
|
|
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
|
-
|
|
230
|
-
DAP.clearUser();
|
|
231
|
-
```
|
|
83
|
+
---
|
|
232
84
|
|
|
233
|
-
|
|
85
|
+
## Usage (recommended): ES Modules (Webpack/Vite/Rollup)
|
|
234
86
|
|
|
235
|
-
**React Integration**
|
|
236
87
|
```javascript
|
|
237
|
-
|
|
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
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
-
//
|
|
348
|
-
|
|
349
|
-
id:
|
|
350
|
-
role:
|
|
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
|
-
|
|
353
|
-
onboarding_step: '3'
|
|
101
|
+
department: "engineering"
|
|
354
102
|
}
|
|
355
103
|
});
|
|
356
104
|
```
|
|
357
105
|
|
|
358
|
-
|
|
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
|
-
|
|
108
|
+
## Usage: CommonJS
|
|
421
109
|
|
|
422
110
|
```javascript
|
|
423
|
-
|
|
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
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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
|
-
|
|
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
|
-
|
|
122
|
+
## Usage: Script tag (UMD)
|
|
460
123
|
|
|
461
|
-
|
|
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
|
-
|
|
465
|
-
<
|
|
466
|
-
<
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
<
|
|
470
|
-
<
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
871
|
-
await DAP.startFlow('custom-onboarding');
|
|
872
|
-
```
|
|
179
|
+
setUser({ id: "user_123", role: "admin" });
|
|
873
180
|
|
|
874
|
-
|
|
875
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
192
|
+
## Integration guidance
|
|
1069
193
|
|
|
1070
|
-
|
|
1071
|
-
-
|
|
1072
|
-
-
|
|
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
|
-
###
|
|
198
|
+
### Multi Page Apps
|
|
199
|
+
- Initialize on each page load (e.g., `DOMContentLoaded`).
|
|
1075
200
|
|
|
1076
|
-
|
|
1077
|
-
|
|
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
|
-
|
|
1082
|
-
|
|
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
|
-
|
|
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
|
-
|
|
210
|
+
## Build outputs (what you get when installed)
|
|
1109
211
|
|
|
1110
|
-
-
|
|
1111
|
-
-
|
|
1112
|
-
-
|
|
1113
|
-
-
|
|
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
|
-
|
|
219
|
+
## License
|
|
220
|
+
|
|
221
|
+
See [LICENSE](LICENSE).
|