@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.

Files changed (60) hide show
  1. package/.github/copilot-instructions.md +95 -0
  2. package/README.md +79 -0
  3. package/TRACKING.md +105 -0
  4. package/USER_CONTEXT_README.md +284 -0
  5. package/package.json +154 -0
  6. package/src/config.ts +25 -0
  7. package/src/core/flowEngine.ts +1833 -0
  8. package/src/core/triggerManager.ts +1011 -0
  9. package/src/experiences/banner.ts +366 -0
  10. package/src/experiences/beacon.ts +668 -0
  11. package/src/experiences/hotspotTour.ts +654 -0
  12. package/src/experiences/hotspots.ts +566 -0
  13. package/src/experiences/modal.ts +1337 -0
  14. package/src/experiences/modalSequence.ts +1247 -0
  15. package/src/experiences/popover.ts +652 -0
  16. package/src/experiences/registry.ts +21 -0
  17. package/src/experiences/survey.ts +1639 -0
  18. package/src/experiences/taskList.ts +625 -0
  19. package/src/experiences/tooltip.ts +740 -0
  20. package/src/experiences/types.ts +395 -0
  21. package/src/experiences/walkthrough.ts +670 -0
  22. package/src/flow-sequence.ts +177 -0
  23. package/src/flows.ts +512 -0
  24. package/src/http.ts +61 -0
  25. package/src/index.ts +355 -0
  26. package/src/services/flowManager.ts +905 -0
  27. package/src/services/flowNormalizer.ts +74 -0
  28. package/src/services/locationContextService.ts +189 -0
  29. package/src/services/pageContextService.ts +221 -0
  30. package/src/services/userContextService.ts +286 -0
  31. package/src/state/appState.ts +0 -0
  32. package/src/state/hooks.ts +0 -0
  33. package/src/state/index.ts +0 -0
  34. package/src/state/migration.ts +0 -0
  35. package/src/state/store.ts +0 -0
  36. package/src/styles/banner.css.ts +0 -0
  37. package/src/styles/hotspot.css.ts +0 -0
  38. package/src/styles/hotspotTour.css.ts +0 -0
  39. package/src/styles/modal.css.ts +564 -0
  40. package/src/styles/survey.css.ts +1013 -0
  41. package/src/styles/taskList.css.ts +0 -0
  42. package/src/styles/tooltip.css.ts +149 -0
  43. package/src/styles/walkthrough.css.ts +0 -0
  44. package/src/tourUtils.ts +0 -0
  45. package/src/tracking.ts +223 -0
  46. package/src/utils/debounce.ts +66 -0
  47. package/src/utils/eventSequenceValidator.ts +124 -0
  48. package/src/utils/flowTrackingSystem.ts +524 -0
  49. package/src/utils/idGenerator.ts +155 -0
  50. package/src/utils/immediateValidationPrevention.ts +184 -0
  51. package/src/utils/normalize.ts +50 -0
  52. package/src/utils/privacyManager.ts +166 -0
  53. package/src/utils/ruleEvaluator.ts +199 -0
  54. package/src/utils/sanitize.ts +79 -0
  55. package/src/utils/selectors.ts +107 -0
  56. package/src/utils/stepExecutor.ts +345 -0
  57. package/src/utils/triggerNormalizer.ts +149 -0
  58. package/src/utils/validationInterceptor.ts +650 -0
  59. package/tsconfig.json +13 -0
  60. 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
+ ================================================ */