@active-reach/web-sdk 1.14.1 → 1.19.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.
Files changed (66) hide show
  1. package/README.md +35 -54
  2. package/dist/aegis-sw.js +1 -1
  3. package/dist/aegis.min.js +1 -1
  4. package/dist/aegis.min.js.map +1 -1
  5. package/dist/{analytics-CjLItVo2.mjs → analytics-DblhjFhs.mjs} +66 -3
  6. package/dist/analytics-DblhjFhs.mjs.map +1 -0
  7. package/dist/cdn.d.ts +5 -2
  8. package/dist/cdn.d.ts.map +1 -1
  9. package/dist/chat/AegisChat.d.ts +138 -0
  10. package/dist/chat/AegisChat.d.ts.map +1 -0
  11. package/dist/chat/index.d.ts +3 -0
  12. package/dist/chat/index.d.ts.map +1 -0
  13. package/dist/core/analytics.d.ts +37 -2
  14. package/dist/core/analytics.d.ts.map +1 -1
  15. package/dist/ecommerce/index.d.ts +32 -14
  16. package/dist/ecommerce/index.d.ts.map +1 -1
  17. package/dist/inapp/AegisInAppManager.d.ts +349 -1
  18. package/dist/inapp/AegisInAppManager.d.ts.map +1 -1
  19. package/dist/inapp/devicePairing.d.ts +70 -0
  20. package/dist/inapp/devicePairing.d.ts.map +1 -0
  21. package/dist/inapp/index.d.ts +2 -0
  22. package/dist/inapp/index.d.ts.map +1 -1
  23. package/dist/inapp/renderPreview.d.ts.map +1 -1
  24. package/dist/inapp/renderers/active-web-chat.d.ts +38 -0
  25. package/dist/inapp/renderers/active-web-chat.d.ts.map +1 -0
  26. package/dist/inapp/renderers/carousel-cards.d.ts.map +1 -1
  27. package/dist/inapp/renderers/coachmark-tour.d.ts.map +1 -1
  28. package/dist/inapp/renderers/games.d.ts +27 -0
  29. package/dist/inapp/renderers/games.d.ts.map +1 -0
  30. package/dist/inapp/renderers/index.d.ts +8 -3
  31. package/dist/inapp/renderers/index.d.ts.map +1 -1
  32. package/dist/inapp/renderers/product-recommendation.d.ts +4 -4
  33. package/dist/inapp/renderers/product-recommendation.d.ts.map +1 -1
  34. package/dist/inapp/renderers/progress-bar.d.ts +14 -0
  35. package/dist/inapp/renderers/progress-bar.d.ts.map +1 -1
  36. package/dist/inapp/renderers/sticky-bar.d.ts.map +1 -1
  37. package/dist/inapp/renderers/stories.d.ts +31 -0
  38. package/dist/inapp/renderers/stories.d.ts.map +1 -0
  39. package/dist/inapp/renderers/types.d.ts +73 -2
  40. package/dist/inapp/renderers/types.d.ts.map +1 -1
  41. package/dist/inapp/renderers/video.d.ts +20 -0
  42. package/dist/inapp/renderers/video.d.ts.map +1 -0
  43. package/dist/index.d.ts +5 -3
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +8696 -3093
  46. package/dist/index.js.map +1 -1
  47. package/dist/loyalty/AegisLoyaltyManager.d.ts +120 -0
  48. package/dist/loyalty/AegisLoyaltyManager.d.ts.map +1 -0
  49. package/dist/loyalty/index.d.ts +3 -0
  50. package/dist/loyalty/index.d.ts.map +1 -0
  51. package/dist/push/AegisWebPush.d.ts.map +1 -1
  52. package/dist/push/AegisWebPush.js +13 -2
  53. package/dist/push/AegisWebPush.js.map +1 -1
  54. package/dist/react.js +1 -1
  55. package/dist/runtime/AegisMessageRuntime.d.ts +96 -1
  56. package/dist/runtime/AegisMessageRuntime.d.ts.map +1 -1
  57. package/dist/triggers/ContactScoresFetcher.d.ts +105 -0
  58. package/dist/triggers/ContactScoresFetcher.d.ts.map +1 -0
  59. package/dist/triggers/IntentRuleEvaluator.d.ts +1 -1
  60. package/dist/triggers/IntentRuleEvaluator.d.ts.map +1 -1
  61. package/dist/triggers/index.d.ts +2 -0
  62. package/dist/triggers/index.d.ts.map +1 -1
  63. package/package.json +4 -4
  64. package/dist/analytics-CjLItVo2.mjs.map +0 -1
  65. package/dist/placements/AegisPlacementManager.d.ts +0 -97
  66. package/dist/placements/AegisPlacementManager.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @active-reach/web-sdk
2
2
 
3
- Web SDK for **Active Reach Intelligence** — lightweight event tracking, identity resolution, in-app messaging, web push, and inline content placements.
3
+ Web SDK for **Active Reach Intelligence** — lightweight event tracking, identity resolution, in-app messaging (overlays, embedded cards, interactive widgets), and web push.
4
4
 
5
5
  **12KB gzipped** | **<1KB async loader** | **Zero impact on page load**
6
6
 
@@ -426,90 +426,71 @@ Copy `dist/aegis-sw.js` to your `public/` directory so the service worker is ser
426
426
 
427
427
  ---
428
428
 
429
- ## In-App Messaging
429
+ ## In-App Messaging & Widgets
430
+
431
+ Every in-app format — modals, banners, tooltips, full-screen takeovers, bottom sheets, and interactive widgets (spin-the-wheel, scratch cards, NPS/CSAT surveys, quizzes, countdown offers, star ratings, polls, multi-step forms) — is delivered through a **single entry point**: `AegisMessageRuntime`.
430
432
 
431
433
  ```typescript
432
- import { AegisInAppManager } from '@active-reach/web-sdk';
434
+ import { AegisMessageRuntime } from '@active-reach/web-sdk';
433
435
 
434
- const inApp = new AegisInAppManager({
436
+ const runtime = new AegisMessageRuntime({
435
437
  writeKey: 'YOUR_WRITE_KEY',
436
438
  apiHost: 'https://YOUR_CELL.activereach.ai',
437
- contactId: 'user_123',
439
+ contactId: 'user_123', // optional — set once the visitor is known
438
440
  organizationId: 'org_456',
441
+ propertyId: 'prop_789', // the SDK install (website/app) this page is
439
442
  });
440
443
 
441
- await inApp.initialize();
444
+ await runtime.initialize();
442
445
  ```
443
446
 
444
- Campaign display rules (modal, banner, tooltip, slide-in) are configured server-side. The SDK evaluates client-side triggers (scroll depth, time on page, exit intent, inactivity) and renders campaigns automatically.
447
+ > **Migrating from an older version?** `AegisInAppManager`, `AegisWidgetManager`, and `AegisPlacementManager` are no longer part of the public API `AegisMessageRuntime` is the one supported entry point and renders all formats. The standalone "placement" system has been removed; inline content is now delivered as **embedded cards** (see below).
445
448
 
446
- ---
449
+ Campaign content, audience, schedule, and frequency caps are configured server-side in the dashboard (**In-App Personalization**). The SDK evaluates client-side triggers (scroll depth, time on page, exit intent, inactivity, custom events) and renders the matching campaign automatically.
447
450
 
448
- ## Inline Content Placements
451
+ ### Drive triggers & identity from your app
449
452
 
450
453
  ```typescript
451
- import { AegisPlacementManager } from '@active-reach/web-sdk';
452
-
453
- const placements = new AegisPlacementManager({
454
- writeKey: 'YOUR_WRITE_KEY',
455
- apiHost: 'https://YOUR_CELL.activereach.ai',
456
- contactId: 'user_123',
457
- organizationId: 'org_456',
458
- enableSSE: true,
459
- });
460
-
461
- await placements.initialize();
462
-
463
- // Register a slot in your page
464
- placements.registerSlot({
465
- placementId: 'homepage_hero',
466
- containerId: 'aegis-hero-slot',
467
- fallbackContent: '<p>Loading...</p>',
468
- });
454
+ runtime.track('added_to_cart'); // fire event-based display triggers
455
+ runtime.notifyConversion('purchase'); // suppress a campaign after it converts
456
+ await runtime.updateContactId('contact_42'); // re-evaluate once the visitor signs in
469
457
  ```
470
458
 
471
- Placements support banner, card, carousel, video, and HTML content types. Content is managed server-side and delivered via SSE for real-time updates.
459
+ ### Placement how a campaign reaches the customer
472
460
 
473
- > **HTML Placements:** For full HTML content rendering, add [DOMPurify](https://github.com/cure53/DOMPurify) to your page. Without it, HTML placements fall back to text-only rendering.
474
- >
475
- > ```html
476
- > <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.2.4/purify.min.js"></script>
477
- > ```
461
+ Each campaign picks one or more **delivery modes** in the dashboard's **Placement** tab. They are not mutually exclusive:
478
462
 
479
- ---
463
+ | Delivery mode | What it is | What you do on your site |
464
+ |---|---|---|
465
+ | **Pop up (overlay)** | A modal / banner / etc. the SDK renders over the page at runtime | Nothing — `runtime.initialize()` shows it when the trigger matches |
466
+ | **Embedded card** | The campaign renders *inline*, inside a slot you place on the page | Add an empty `<div data-aegis-slot="…">` where you want it |
467
+ | **Standalone page** | The campaign gets its own tokenized URL (great for SMS / email / QR) | Link to the URL shown in the dashboard |
480
468
 
481
- ## Widgets (Exit Intent, Surveys, Gamification)
469
+ #### Embedded cards (inline placement)
482
470
 
483
- ```typescript
484
- import { AegisWidgetManager, TriggerEngine } from '@active-reach/web-sdk';
471
+ Drop an empty element wherever you want the card to appear. Its `data-aegis-slot` value must equal the campaign's **category** (`widget_category` in the dashboard). On load, the SDK fills the first eligible campaign for that category:
485
472
 
486
- const triggerEngine = new TriggerEngine();
487
- const widgets = new AegisWidgetManager({
488
- writeKey: 'YOUR_WRITE_KEY',
489
- apiHost: 'https://YOUR_CELL.activereach.ai',
490
- contactId: 'user_123',
491
- organizationId: 'org_456',
492
- triggerEngine,
493
- enablePrefetch: true,
494
- });
495
-
496
- await widgets.initialize();
473
+ ```html
474
+ <!-- Renders the active "promo" campaign here, inline in your page -->
475
+ <div data-aegis-slot="promo"></div>
497
476
  ```
498
477
 
499
- ### Cart Recovery (Platform Auto-Detection)
478
+ No per-slot script and no manual registration — `runtime.initialize()` scans for every `[data-aegis-slot]` element and fills it. It re-scans on each SSE/poll refresh and skips slots it has already filled.
479
+
480
+ ### Cart recovery (platform auto-detection)
500
481
 
501
- The SDK auto-detects cart data from:
482
+ For cart-abandonment campaigns the widget subsystem auto-detects cart data:
502
483
 
503
- | Platform | Detection Method | Setup |
484
+ | Platform | Detection method | Setup |
504
485
  |----------|-----------------|-------|
505
486
  | **Shopify** | `window.Shopify.checkout` / DOM `#cart-json` | None |
506
487
  | **WooCommerce** | `window.aegis_cart` (injected by plugin) | Install WP plugin |
507
488
  | **Magento 2** | `localStorage['mage-cache-storage']` | None |
508
- | **Custom / Mobile** | Manual via `setCartData()` | Required |
489
+ | **Custom / Mobile** | Manual | Call `setCartData()` |
509
490
 
510
491
  ```typescript
511
- // For custom platforms only
512
- widgets.setCartData({
492
+ // Custom platforms only — reach the widget subsystem via runtime.widgets
493
+ runtime.widgets.setCartData({
513
494
  cart_id: 'cart_123',
514
495
  cart_total: 149.99,
515
496
  cart_currency: 'INR',
package/dist/aegis-sw.js CHANGED
@@ -1 +1 @@
1
- !function(){"use strict";function i(i){self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(t=>{for(const a of t)a.postMessage(i)}).catch(()=>{})}self.addEventListener("install",()=>{self.skipWaiting()}),self.addEventListener("activate",i=>{i.waitUntil(self.clients.claim())}),self.addEventListener("push",t=>{var a,n;if(!t.data)return;let o;try{o=t.data.json()}catch{o={title:t.data.text()||"Notification"}}const e=o.title||"Notification",c={campaign_id:o.campaign_id,action_url:o.action_url||o.url,action_type:null==(a=o.data)?void 0:a.action_type,action_payload:null==(n=o.data)?void 0:n.action_payload,timestamp:Date.now()},s={body:o.body||"",icon:o.icon||void 0,badge:o.badge||void 0,image:o.image||void 0,tag:o.tag||o.campaign_id||void 0,data:c,...Array.isArray(o.actions)&&o.actions.length>0?{actions:o.actions.slice(0,2)}:{},requireInteraction:o.require_interaction??!1};t.waitUntil(self.registration.showNotification(e,s).then(()=>{i({type:"push.delivered",campaign_id:o.campaign_id})}).catch(t=>(console.error("[aegis-sw] showNotification failed, retrying minimal:",t),self.registration.showNotification(e,{body:o.body||"",data:c}).then(()=>{i({type:"push.delivered",campaign_id:o.campaign_id,degraded:!0})}).catch(i=>{console.error("[aegis-sw] minimal showNotification also failed:",i)}))))}),self.addEventListener("notificationclick",t=>{t.notification.close();const a=t.notification.data||{},n=a.action_url||"/";let o=n;if(t.action&&Array.isArray(t.notification.actions)){if(t.notification.actions.find(i=>i.action===t.action)){const i=a.action_urls||{};o=i[t.action]||n}}t.waitUntil(self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(n=>{const e=n.find(i=>new URL(i.url).origin===self.location.origin);return e?(e.postMessage({type:"push.clicked",campaign_id:a.campaign_id,action_url:o,action:t.action||"default",action_type:a.action_type,action_payload:a.action_payload}),e.focus()):(i({type:"push.clicked",campaign_id:a.campaign_id,action_url:o,action:t.action||"default",action_type:a.action_type,action_payload:a.action_payload}),self.clients.openWindow(o))}))}),self.addEventListener("notificationclose",t=>{i({type:"push.dismissed",campaign_id:(t.notification.data||{}).campaign_id})}),self.addEventListener("pushsubscriptionchange",t=>{var a,n;t.waitUntil(self.registration.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:(null==(n=null==(a=t.oldSubscription)?void 0:a.options)?void 0:n.applicationServerKey)||void 0}).then(t=>{i({type:"push.resubscribed",subscription:t.toJSON()})}).catch(i=>{console.error("[aegis-sw] Failed to resubscribe:",i)}))})}();
1
+ !function(){"use strict";function i(i){self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(t=>{for(const o of t)o.postMessage(i)}).catch(()=>{})}self.addEventListener("install",()=>{self.skipWaiting()}),self.addEventListener("activate",i=>{i.waitUntil(self.clients.claim())}),self.addEventListener("push",t=>{if(!t.data)return;let o;try{o=t.data.json()}catch{o={title:t.data.text()||"Notification"}}const n=o.title||"Notification",e=o.data,a={campaign_id:o.campaign_id,journey_execution_id:o.journey_execution_id||(null==e?void 0:e.journey_execution_id),lifecycle_fork_id:o.lifecycle_fork_id||(null==e?void 0:e.lifecycle_fork_id),location_id:o.location_id||(null==e?void 0:e.location_id),action_url:o.action_url||o.url,action_type:null==e?void 0:e.action_type,action_payload:null==e?void 0:e.action_payload,timestamp:Date.now()},c={body:o.body||"",icon:o.icon||void 0,badge:o.badge||void 0,image:o.image||void 0,tag:o.tag||o.campaign_id||void 0,data:a,...Array.isArray(o.actions)&&o.actions.length>0?{actions:o.actions.slice(0,2)}:{},requireInteraction:o.require_interaction??!1};t.waitUntil(self.registration.showNotification(n,c).then(()=>{i({type:"push.delivered",campaign_id:o.campaign_id,journey_execution_id:a.journey_execution_id,lifecycle_fork_id:a.lifecycle_fork_id,location_id:a.location_id})}).catch(t=>(console.error("[aegis-sw] showNotification failed, retrying minimal:",t),self.registration.showNotification(n,{body:o.body||"",data:a}).then(()=>{i({type:"push.delivered",campaign_id:o.campaign_id,degraded:!0})}).catch(i=>{console.error("[aegis-sw] minimal showNotification also failed:",i)}))))}),self.addEventListener("notificationclick",t=>{t.notification.close();const o=t.notification.data||{},n=o.action_url||"/";let e=n;if(t.action&&Array.isArray(t.notification.actions)){if(t.notification.actions.find(i=>i.action===t.action)){const i=o.action_urls||{};e=i[t.action]||n}}t.waitUntil(self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(n=>{const a=n.find(i=>new URL(i.url).origin===self.location.origin);return a?(a.postMessage({type:"push.clicked",campaign_id:o.campaign_id,journey_execution_id:o.journey_execution_id,lifecycle_fork_id:o.lifecycle_fork_id,location_id:o.location_id,action_url:e,action:t.action||"default",action_type:o.action_type,action_payload:o.action_payload}),a.focus()):(i({type:"push.clicked",campaign_id:o.campaign_id,action_url:e,action:t.action||"default",action_type:o.action_type,action_payload:o.action_payload}),self.clients.openWindow(e))}))}),self.addEventListener("notificationclose",t=>{const o=t.notification.data||{};i({type:"push.dismissed",campaign_id:o.campaign_id,journey_execution_id:o.journey_execution_id,lifecycle_fork_id:o.lifecycle_fork_id,location_id:o.location_id})}),self.addEventListener("pushsubscriptionchange",t=>{var o,n;t.waitUntil(self.registration.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:(null==(n=null==(o=t.oldSubscription)?void 0:o.options)?void 0:n.applicationServerKey)||void 0}).then(t=>{i({type:"push.resubscribed",subscription:t.toJSON()})}).catch(i=>{console.error("[aegis-sw] Failed to resubscribe:",i)}))})}();