@cognior/iap-sdk 0.1.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.
Potentially problematic release.
This version of @cognior/iap-sdk might be problematic. Click here for more details.
- package/.github/copilot-instructions.md +95 -0
- package/README.md +79 -0
- package/TRACKING.md +105 -0
- package/USER_CONTEXT_README.md +284 -0
- package/package.json +154 -0
- package/src/config.ts +25 -0
- package/src/core/flowEngine.ts +1833 -0
- package/src/core/triggerManager.ts +1011 -0
- package/src/experiences/banner.ts +366 -0
- package/src/experiences/beacon.ts +668 -0
- package/src/experiences/hotspotTour.ts +654 -0
- package/src/experiences/hotspots.ts +566 -0
- package/src/experiences/modal.ts +1337 -0
- package/src/experiences/modalSequence.ts +1247 -0
- package/src/experiences/popover.ts +652 -0
- package/src/experiences/registry.ts +21 -0
- package/src/experiences/survey.ts +1639 -0
- package/src/experiences/taskList.ts +625 -0
- package/src/experiences/tooltip.ts +740 -0
- package/src/experiences/types.ts +395 -0
- package/src/experiences/walkthrough.ts +670 -0
- package/src/flow-sequence.ts +177 -0
- package/src/flows.ts +512 -0
- package/src/http.ts +61 -0
- package/src/index.ts +355 -0
- package/src/services/flowManager.ts +905 -0
- package/src/services/flowNormalizer.ts +74 -0
- package/src/services/locationContextService.ts +189 -0
- package/src/services/pageContextService.ts +221 -0
- package/src/services/userContextService.ts +286 -0
- package/src/state/appState.ts +0 -0
- package/src/state/hooks.ts +0 -0
- package/src/state/index.ts +0 -0
- package/src/state/migration.ts +0 -0
- package/src/state/store.ts +0 -0
- package/src/styles/banner.css.ts +0 -0
- package/src/styles/hotspot.css.ts +0 -0
- package/src/styles/hotspotTour.css.ts +0 -0
- package/src/styles/modal.css.ts +564 -0
- package/src/styles/survey.css.ts +1013 -0
- package/src/styles/taskList.css.ts +0 -0
- package/src/styles/tooltip.css.ts +149 -0
- package/src/styles/walkthrough.css.ts +0 -0
- package/src/tourUtils.ts +0 -0
- package/src/tracking.ts +223 -0
- package/src/utils/debounce.ts +66 -0
- package/src/utils/eventSequenceValidator.ts +124 -0
- package/src/utils/flowTrackingSystem.ts +524 -0
- package/src/utils/idGenerator.ts +155 -0
- package/src/utils/immediateValidationPrevention.ts +184 -0
- package/src/utils/normalize.ts +50 -0
- package/src/utils/privacyManager.ts +166 -0
- package/src/utils/ruleEvaluator.ts +199 -0
- package/src/utils/sanitize.ts +79 -0
- package/src/utils/selectors.ts +107 -0
- package/src/utils/stepExecutor.ts +345 -0
- package/src/utils/triggerNormalizer.ts +149 -0
- package/src/utils/validationInterceptor.ts +650 -0
- package/tsconfig.json +13 -0
- package/tsup.config.ts +13 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
// src/experiences/types.ts
|
|
2
|
+
|
|
3
|
+
/** Shared placement type for tooltip/popover */
|
|
4
|
+
export type CornerPlacement =
|
|
5
|
+
| "top-right" | "top-left" | "bottom-right" | "bottom-left"
|
|
6
|
+
| "right" | "left" | "top" | "bottom";
|
|
7
|
+
|
|
8
|
+
/* ------------------ Enhanced Trigger System Types ------------------ */
|
|
9
|
+
|
|
10
|
+
/** Logical operators for composite triggers */
|
|
11
|
+
export type LogicalOperator = "And" | "Or";
|
|
12
|
+
|
|
13
|
+
/** Rule operators for condition evaluation */
|
|
14
|
+
export type RuleOperator =
|
|
15
|
+
| "Equals" | "NotEquals" | "Contains" | "NotContains"
|
|
16
|
+
| "StartsWith" | "EndsWith"
|
|
17
|
+
| "GreaterThan" | "LessThan"
|
|
18
|
+
| "GreaterThanOrEqual" | "LessThanOrEqual"
|
|
19
|
+
| "In" | "NotIn" | "Regex" | "Empty";
|
|
20
|
+
|
|
21
|
+
/** Trigger types */
|
|
22
|
+
export type TriggerType = "Single" | "Composite";
|
|
23
|
+
|
|
24
|
+
/** Trigger condition kinds */
|
|
25
|
+
export type TriggerConditionKind =
|
|
26
|
+
| "Dom" | "Lifecycle" | "Input" | "Time" | "Media" | "System";
|
|
27
|
+
|
|
28
|
+
/** Flow execution modes */
|
|
29
|
+
export type FlowExecutionMode = "Linear" | "AnyOrder";
|
|
30
|
+
|
|
31
|
+
/** Flow frequency types */
|
|
32
|
+
export type FlowFrequencyType = "OneTime" | "Recurring";
|
|
33
|
+
|
|
34
|
+
/** Step types */
|
|
35
|
+
export type StepType = "Mandatory" | "Optional";
|
|
36
|
+
|
|
37
|
+
/** Branch types */
|
|
38
|
+
export type BranchType = "Flow" | "Step" | "Continue";
|
|
39
|
+
|
|
40
|
+
/** Individual trigger condition */
|
|
41
|
+
export interface TriggerCondition {
|
|
42
|
+
kind: TriggerConditionKind;
|
|
43
|
+
event: string;
|
|
44
|
+
selector?: string;
|
|
45
|
+
operator?: RuleOperator;
|
|
46
|
+
value?: any;
|
|
47
|
+
debounceMs?: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Step-level trigger definition */
|
|
51
|
+
export interface TriggerDefinition {
|
|
52
|
+
type: TriggerType;
|
|
53
|
+
operator: LogicalOperator;
|
|
54
|
+
once: boolean;
|
|
55
|
+
conditions: TriggerCondition[];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Runtime trigger evaluation context */
|
|
59
|
+
export interface TriggerEvaluationContext {
|
|
60
|
+
stepId: string;
|
|
61
|
+
flowId: string;
|
|
62
|
+
element?: HTMLElement;
|
|
63
|
+
event?: Event;
|
|
64
|
+
userInput?: any;
|
|
65
|
+
pageState?: any;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Trigger evaluation result */
|
|
69
|
+
export interface TriggerEvaluationResult {
|
|
70
|
+
triggered: boolean;
|
|
71
|
+
matchedConditions: number;
|
|
72
|
+
totalConditions: number;
|
|
73
|
+
evaluationTime: number;
|
|
74
|
+
debugInfo?: any;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* ------------------ Step State Management for FlowRunner ------------------ */
|
|
78
|
+
|
|
79
|
+
export type StepExecutionState = "idle" | "waiting-for-trigger" | "rendered" | "completed";
|
|
80
|
+
|
|
81
|
+
export interface StepExecutionContext {
|
|
82
|
+
stepIndex: number;
|
|
83
|
+
stepId: string;
|
|
84
|
+
state: StepExecutionState;
|
|
85
|
+
hasElementTrigger: boolean;
|
|
86
|
+
targetElement?: HTMLElement;
|
|
87
|
+
triggerListeners?: (() => void)[];
|
|
88
|
+
lastTriggeredTime?: number;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface FlowRunnerState {
|
|
92
|
+
currentStepIndex: number;
|
|
93
|
+
stepContexts: Map<number, StepExecutionContext>;
|
|
94
|
+
isMultiStep: boolean;
|
|
95
|
+
pageLoadTriggersExecuted: Set<string>;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* ------------------ Rule condition types for dynamic flow switching ------------------ */
|
|
99
|
+
|
|
100
|
+
export type ConditionOperator = "Equals" | "NotEquals" | "Contains" | "NotContains" | "GreaterThan" | "LessThan";
|
|
101
|
+
export type ConditionValueType = "String" | "Number" | "Boolean";
|
|
102
|
+
|
|
103
|
+
export interface RuleCondition {
|
|
104
|
+
propertyName: string | null;
|
|
105
|
+
operator: ConditionOperator;
|
|
106
|
+
valueType: ConditionValueType;
|
|
107
|
+
value: string | number | boolean;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface ConditionRuleBlock {
|
|
111
|
+
ruleBlockId: string;
|
|
112
|
+
selector: string;
|
|
113
|
+
logicalOperator: LogicalOperator;
|
|
114
|
+
conditions: RuleCondition[];
|
|
115
|
+
nextFlowId: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* ------------------ Rule step for flow sequences ------------------ */
|
|
119
|
+
|
|
120
|
+
export interface RuleStep {
|
|
121
|
+
kind: "rule";
|
|
122
|
+
stepId: string;
|
|
123
|
+
inputSelector: string;
|
|
124
|
+
rules: ConditionRuleBlock[];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* ------------------ Modal content blocks ------------------ */
|
|
128
|
+
|
|
129
|
+
export type ModalText = { kind: "text"; html: string };
|
|
130
|
+
export type ModalLink = { kind: "link"; href: string; label?: string };
|
|
131
|
+
export type ModalImage = { kind: "image"; url: string; alt?: string };
|
|
132
|
+
export type ModalVideoSource = { src: string; type?: string };
|
|
133
|
+
export type ModalVideo = { kind: "video"; sources: ModalVideoSource[] };
|
|
134
|
+
export type ModalYouTube = { kind: "youtube"; href: string; id?: string; title?: string; thumbnail?: string };
|
|
135
|
+
export type ModalArticle = { kind: "article"; url: string; fileName?: string; mime?: string };
|
|
136
|
+
|
|
137
|
+
/* ------------------ Knowledge Base blocks ------------------ */
|
|
138
|
+
|
|
139
|
+
export type KBItemType = "link" | "youtube" | "video" | "image" | "article" | "pdf" | "doc" | "docx";
|
|
140
|
+
|
|
141
|
+
export interface KBItem {
|
|
142
|
+
kind: "kb-item";
|
|
143
|
+
itemType: KBItemType;
|
|
144
|
+
title?: string;
|
|
145
|
+
description?: string;
|
|
146
|
+
url: string; // presigned or absolute URL
|
|
147
|
+
fileName?: string; // for articles
|
|
148
|
+
mime?: string; // optional hint
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface ModalKB {
|
|
152
|
+
kind: "kb";
|
|
153
|
+
title?: string;
|
|
154
|
+
items: KBItem[];
|
|
155
|
+
viewState?: "list" | "item"; // Internal view state
|
|
156
|
+
currentItem?: KBItem; // Currently viewed item
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* ------------------ KB Item Viewer Content Types ------------------ */
|
|
160
|
+
|
|
161
|
+
export interface ModalKBItemViewer {
|
|
162
|
+
kind: "kb-item-viewer";
|
|
163
|
+
item: KBItem;
|
|
164
|
+
kbTitle?: string; // Parent KB title for breadcrumb
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* ------------------ Unions ------------------ */
|
|
168
|
+
|
|
169
|
+
export type ModalContent =
|
|
170
|
+
| ModalText
|
|
171
|
+
| ModalLink
|
|
172
|
+
| ModalImage
|
|
173
|
+
| ModalVideo
|
|
174
|
+
| ModalYouTube
|
|
175
|
+
| ModalArticle
|
|
176
|
+
| ModalKB
|
|
177
|
+
| ModalKBItemViewer;
|
|
178
|
+
|
|
179
|
+
/* ------------------ Modal Sequence (flows rendered by modalSequence) ------------------ */
|
|
180
|
+
|
|
181
|
+
export interface TooltipPayload {
|
|
182
|
+
targetSelector: string; // CSS selector or XPath
|
|
183
|
+
text: string;
|
|
184
|
+
placement?: string; // "auto" | "top" | "bottom" | "left" | "right" | corners
|
|
185
|
+
trigger?: "hover" | "focus" | "click";
|
|
186
|
+
stepId?: string; // Unique step identifier for tracking
|
|
187
|
+
_completionTracker?: CompletionTracker;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Rich popover support (text/links/buttons/forms/images) */
|
|
191
|
+
export type PopoverText = { kind: "text"; html: string };
|
|
192
|
+
export type PopoverLink = { kind: "link"; href: string; label?: string };
|
|
193
|
+
export type PopoverButton = {
|
|
194
|
+
kind: "button";
|
|
195
|
+
label: string;
|
|
196
|
+
action: string; // "btn_next" | "btn_close" | "custom:save" ...
|
|
197
|
+
variant?: "primary" | "secondary" | "danger";
|
|
198
|
+
};
|
|
199
|
+
export type PopoverImage = { kind: "image"; url: string; alt?: string; width?: number; height?: number };
|
|
200
|
+
export type PopoverFormField =
|
|
201
|
+
| { type: "text" | "email" | "number"; name: string; label?: string; placeholder?: string; required?: boolean }
|
|
202
|
+
| { type: "textarea"; name: string; label?: string; placeholder?: string; required?: boolean; rows?: number }
|
|
203
|
+
| { type: "select"; name: string; label?: string; required?: boolean; options: Array<{ label: string; value: string }> }
|
|
204
|
+
| { type: "checkbox"; name: string; label: string; required?: boolean };
|
|
205
|
+
export type PopoverForm = {
|
|
206
|
+
kind: "form";
|
|
207
|
+
id: string;
|
|
208
|
+
fields: PopoverFormField[];
|
|
209
|
+
submitLabel?: string;
|
|
210
|
+
cancelLabel?: string;
|
|
211
|
+
};
|
|
212
|
+
export type PopoverBlock = PopoverText | PopoverLink | PopoverButton | PopoverImage | PopoverForm;
|
|
213
|
+
|
|
214
|
+
export interface PopoverPayload {
|
|
215
|
+
title?: string;
|
|
216
|
+
body?: string; // legacy HTML (sanitized)
|
|
217
|
+
bodyBlocks?: PopoverBlock[]; // preferred
|
|
218
|
+
targetSelector: string;
|
|
219
|
+
placement?: string;
|
|
220
|
+
trigger?: "hover" | "focus" | "click";
|
|
221
|
+
showArrow?: boolean;
|
|
222
|
+
stepId?: string; // Unique step identifier for tracking
|
|
223
|
+
_completionTracker?: CompletionTracker;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export interface ModalSequenceStep {
|
|
227
|
+
kind: "modal" | "tooltip" | "popover" | "survey" | "rule";
|
|
228
|
+
title?: string;
|
|
229
|
+
footerText?: string;
|
|
230
|
+
body?: ModalContent[]; // modal content blocks
|
|
231
|
+
size?: ModalSize; // modal size variant
|
|
232
|
+
tooltip?: TooltipPayload; // tooltip payload
|
|
233
|
+
popover?: PopoverPayload; // popover payload
|
|
234
|
+
stepId?: string; // Unique step identifier for tracking
|
|
235
|
+
survey?: any; // survey payload
|
|
236
|
+
rule?: RuleStep; // rule payload for conditional flow switching
|
|
237
|
+
|
|
238
|
+
// Trigger information for step-level triggering
|
|
239
|
+
elementSelector?: string; // CSS/XPath selector for trigger element
|
|
240
|
+
elementTrigger?: string; // Trigger type: "click", "hover", "on page load", etc.
|
|
241
|
+
elementLocation?: string; // Location context for the trigger element
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export interface CompletionTracker {
|
|
245
|
+
onComplete: () => void;
|
|
246
|
+
onStepAdvance?: (stepId: string) => void;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export interface ModalSequencePayload {
|
|
250
|
+
startAt?: number;
|
|
251
|
+
theme?: Record<string, string>;
|
|
252
|
+
steps: ModalSequenceStep[];
|
|
253
|
+
/** Total number of steps in the sequence - used for tracking completion */
|
|
254
|
+
stepsCount?: number;
|
|
255
|
+
_completionTracker?: CompletionTracker;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* ------------------ Back-compat (for existing modal.ts using ModalPayload) ------------------ */
|
|
259
|
+
export type ModalSize = "small" | "medium" | "large" | "fullscreen";
|
|
260
|
+
|
|
261
|
+
export interface ModalPayload {
|
|
262
|
+
title?: string;
|
|
263
|
+
footerText?: string;
|
|
264
|
+
body?: ModalContent[];
|
|
265
|
+
size?: ModalSize;
|
|
266
|
+
theme?: Record<string, string>;
|
|
267
|
+
draggable?: boolean; // Enable/disable dragging behavior (default: true)
|
|
268
|
+
_completionTracker?: CompletionTracker;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/* ------------------ Banner Experience ------------------ */
|
|
272
|
+
export interface BannerPayload {
|
|
273
|
+
message: string;
|
|
274
|
+
variant?: "info" | "warning" | "error" | "success";
|
|
275
|
+
position?: "top" | "bottom";
|
|
276
|
+
dismissible?: boolean;
|
|
277
|
+
autoHide?: number; // auto-hide after N seconds
|
|
278
|
+
actions?: Array<{
|
|
279
|
+
label: string;
|
|
280
|
+
action: "dismiss" | "navigate" | "custom";
|
|
281
|
+
href?: string; // for navigate action
|
|
282
|
+
customAction?: string; // for custom action
|
|
283
|
+
}>;
|
|
284
|
+
theme?: Record<string, string>;
|
|
285
|
+
_completionTracker?: CompletionTracker;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* ------------------ Hotspots Experience ------------------ */
|
|
289
|
+
export interface HotspotItem {
|
|
290
|
+
id: string;
|
|
291
|
+
selector: string; // CSS selector for target element
|
|
292
|
+
title: string;
|
|
293
|
+
description: string;
|
|
294
|
+
placement?: CornerPlacement;
|
|
295
|
+
pulseColor?: string;
|
|
296
|
+
required?: boolean; // if true, user must click this hotspot
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export interface HotspotsPayload {
|
|
300
|
+
title?: string;
|
|
301
|
+
description?: string;
|
|
302
|
+
hotspots: HotspotItem[];
|
|
303
|
+
showProgress?: boolean;
|
|
304
|
+
allowSkip?: boolean;
|
|
305
|
+
theme?: Record<string, string>;
|
|
306
|
+
_completionTracker?: CompletionTracker;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* ------------------ Hotspot Tour Experience ------------------ */
|
|
310
|
+
export interface HotspotTourStep {
|
|
311
|
+
id: string;
|
|
312
|
+
selector: string; // CSS selector for target element
|
|
313
|
+
title: string;
|
|
314
|
+
description: string;
|
|
315
|
+
placement?: CornerPlacement;
|
|
316
|
+
action?: "next" | "close" | "custom";
|
|
317
|
+
customAction?: string; // for custom action
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export interface HotspotTourPayload {
|
|
321
|
+
title?: string;
|
|
322
|
+
description?: string;
|
|
323
|
+
steps: HotspotTourStep[];
|
|
324
|
+
showProgress?: boolean;
|
|
325
|
+
allowSkip?: boolean;
|
|
326
|
+
autoAdvance?: number; // auto-advance after N seconds
|
|
327
|
+
theme?: Record<string, string>;
|
|
328
|
+
_completionTracker?: CompletionTracker;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/* ------------------ Task List Experience ------------------ */
|
|
332
|
+
export interface TaskItem {
|
|
333
|
+
id: string;
|
|
334
|
+
title: string;
|
|
335
|
+
description?: string;
|
|
336
|
+
completed?: boolean;
|
|
337
|
+
required?: boolean;
|
|
338
|
+
action?: string; // custom action when completed
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export interface TaskListPayload {
|
|
342
|
+
title?: string;
|
|
343
|
+
description?: string;
|
|
344
|
+
tasks: TaskItem[];
|
|
345
|
+
allowPartialCompletion?: boolean;
|
|
346
|
+
showProgress?: boolean;
|
|
347
|
+
theme?: Record<string, string>;
|
|
348
|
+
_completionTracker?: CompletionTracker;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/* ------------------ Walkthrough Experience ------------------ */
|
|
352
|
+
export interface WalkthroughStep {
|
|
353
|
+
title: string;
|
|
354
|
+
content: string;
|
|
355
|
+
target?: string; // CSS selector
|
|
356
|
+
position?: 'top' | 'bottom' | 'left' | 'right';
|
|
357
|
+
autoAdvance?: boolean;
|
|
358
|
+
autoAdvanceDelay?: number; // ms
|
|
359
|
+
autoScroll?: boolean;
|
|
360
|
+
waitTimeout?: number; // ms
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export interface WalkthroughPayload {
|
|
364
|
+
steps: WalkthroughStep[];
|
|
365
|
+
theme?: Record<string, string>;
|
|
366
|
+
_completionTracker?: CompletionTracker;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/* ------------------ Beacon Experience ------------------ */
|
|
370
|
+
export interface BeaconPayload {
|
|
371
|
+
title?: string;
|
|
372
|
+
body?: string;
|
|
373
|
+
icon?: string; // emoji or icon character
|
|
374
|
+
position?: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right' | 'center';
|
|
375
|
+
targetSelector?: string; // CSS selector for element to attach beacon to
|
|
376
|
+
trigger?: 'hover' | 'focus' | 'click' | 'on hover' | 'on focus' | 'on click' | 'on page load';
|
|
377
|
+
autoDismiss?: number; // auto-dismiss after N seconds
|
|
378
|
+
action?: string; // custom action when clicked
|
|
379
|
+
beaconStyles?: {
|
|
380
|
+
enabled?: boolean;
|
|
381
|
+
color1?: string; // primary pulse color
|
|
382
|
+
color2?: string; // secondary pulse color
|
|
383
|
+
duration?: string; // animation duration
|
|
384
|
+
padding?: string; // pulse padding
|
|
385
|
+
borderWidth?: string; // pulse border width
|
|
386
|
+
borderRadius?: string; // pulse border radius
|
|
387
|
+
shadowSize?: string; // pulse shadow size
|
|
388
|
+
};
|
|
389
|
+
_completionTracker?: CompletionTracker;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* ===================== Note =====================
|
|
393
|
+
MicroSurveyPayload has been merged into SurveyPayload in survey.ts
|
|
394
|
+
The unified survey system handles both modal and inline survey modes
|
|
395
|
+
================================================ */
|