@active-reach/web-sdk 1.43.1 → 1.43.3

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 (185) hide show
  1. package/dist/aegis-push.min.js +2 -0
  2. package/dist/aegis-push.min.js.map +1 -0
  3. package/dist/aegis-sw.js +1 -0
  4. package/dist/aegis.min.js +2 -0
  5. package/dist/aegis.min.js.map +1 -0
  6. package/dist/analytics-C-Go3Pm5.mjs +3509 -0
  7. package/dist/analytics-C-Go3Pm5.mjs.map +1 -0
  8. package/dist/cdn.d.ts +26 -0
  9. package/dist/cdn.d.ts.map +1 -0
  10. package/dist/chat/AegisChat.d.ts +180 -0
  11. package/dist/chat/AegisChat.d.ts.map +1 -0
  12. package/dist/chat/index.d.ts +3 -0
  13. package/dist/chat/index.d.ts.map +1 -0
  14. package/dist/core/analytics.d.ts +320 -0
  15. package/dist/core/analytics.d.ts.map +1 -0
  16. package/dist/core/bootstrap.d.ts +96 -0
  17. package/dist/core/bootstrap.d.ts.map +1 -0
  18. package/dist/core/prefetch-bundle-client.d.ts +175 -0
  19. package/dist/core/prefetch-bundle-client.d.ts.map +1 -0
  20. package/dist/core/queue.d.ts +35 -0
  21. package/dist/core/queue.d.ts.map +1 -0
  22. package/dist/core/rate-limiter.d.ts +45 -0
  23. package/dist/core/rate-limiter.d.ts.map +1 -0
  24. package/dist/core/sdk-config-poller.d.ts +59 -0
  25. package/dist/core/sdk-config-poller.d.ts.map +1 -0
  26. package/dist/core/session.d.ts +52 -0
  27. package/dist/core/session.d.ts.map +1 -0
  28. package/dist/core/transport.d.ts +50 -0
  29. package/dist/core/transport.d.ts.map +1 -0
  30. package/dist/core/user-namespace.d.ts +48 -0
  31. package/dist/core/user-namespace.d.ts.map +1 -0
  32. package/dist/ecommerce/index.d.ts +94 -0
  33. package/dist/ecommerce/index.d.ts.map +1 -0
  34. package/dist/ecommerce/types.d.ts +81 -0
  35. package/dist/ecommerce/types.d.ts.map +1 -0
  36. package/dist/governance/bloom-filter.d.ts +47 -0
  37. package/dist/governance/bloom-filter.d.ts.map +1 -0
  38. package/dist/governance/index.d.ts +8 -0
  39. package/dist/governance/index.d.ts.map +1 -0
  40. package/dist/governance/murmur3.d.ts +43 -0
  41. package/dist/governance/murmur3.d.ts.map +1 -0
  42. package/dist/governance/name-governor.d.ts +98 -0
  43. package/dist/governance/name-governor.d.ts.map +1 -0
  44. package/dist/governance/trait-governor.d.ts +63 -0
  45. package/dist/governance/trait-governor.d.ts.map +1 -0
  46. package/dist/inapp/AegisInAppManager.d.ts +894 -0
  47. package/dist/inapp/AegisInAppManager.d.ts.map +1 -0
  48. package/dist/inapp/actions.d.ts +91 -0
  49. package/dist/inapp/actions.d.ts.map +1 -0
  50. package/dist/inapp/devicePairing.d.ts +70 -0
  51. package/dist/inapp/devicePairing.d.ts.map +1 -0
  52. package/dist/inapp/eval-throttle.d.ts +33 -0
  53. package/dist/inapp/eval-throttle.d.ts.map +1 -0
  54. package/dist/inapp/font.d.ts +16 -0
  55. package/dist/inapp/font.d.ts.map +1 -0
  56. package/dist/inapp/index.d.ts +8 -0
  57. package/dist/inapp/index.d.ts.map +1 -0
  58. package/dist/inapp/lucide-svg.d.ts +46 -0
  59. package/dist/inapp/lucide-svg.d.ts.map +1 -0
  60. package/dist/inapp/renderPreview.d.ts +40 -0
  61. package/dist/inapp/renderPreview.d.ts.map +1 -0
  62. package/dist/inapp/renderers/active-web-chat.d.ts +45 -0
  63. package/dist/inapp/renderers/active-web-chat.d.ts.map +1 -0
  64. package/dist/inapp/renderers/card-style.d.ts +31 -0
  65. package/dist/inapp/renderers/card-style.d.ts.map +1 -0
  66. package/dist/inapp/renderers/card-template.d.ts +233 -0
  67. package/dist/inapp/renderers/card-template.d.ts.map +1 -0
  68. package/dist/inapp/renderers/carousel-cards.d.ts +15 -0
  69. package/dist/inapp/renderers/carousel-cards.d.ts.map +1 -0
  70. package/dist/inapp/renderers/coachmark-tour.d.ts +24 -0
  71. package/dist/inapp/renderers/coachmark-tour.d.ts.map +1 -0
  72. package/dist/inapp/renderers/games.d.ts +27 -0
  73. package/dist/inapp/renderers/games.d.ts.map +1 -0
  74. package/dist/inapp/renderers/hero.d.ts +23 -0
  75. package/dist/inapp/renderers/hero.d.ts.map +1 -0
  76. package/dist/inapp/renderers/index.d.ts +22 -0
  77. package/dist/inapp/renderers/index.d.ts.map +1 -0
  78. package/dist/inapp/renderers/interactive-contract.d.ts +48 -0
  79. package/dist/inapp/renderers/interactive-contract.d.ts.map +1 -0
  80. package/dist/inapp/renderers/product-recommendation.d.ts +37 -0
  81. package/dist/inapp/renderers/product-recommendation.d.ts.map +1 -0
  82. package/dist/inapp/renderers/progress-bar.d.ts +38 -0
  83. package/dist/inapp/renderers/progress-bar.d.ts.map +1 -0
  84. package/dist/inapp/renderers/progress-core.d.ts +80 -0
  85. package/dist/inapp/renderers/progress-core.d.ts.map +1 -0
  86. package/dist/inapp/renderers/reviews.d.ts +38 -0
  87. package/dist/inapp/renderers/reviews.d.ts.map +1 -0
  88. package/dist/inapp/renderers/scratch-engine.d.ts +66 -0
  89. package/dist/inapp/renderers/scratch-engine.d.ts.map +1 -0
  90. package/dist/inapp/renderers/sticky-bar.d.ts +14 -0
  91. package/dist/inapp/renderers/sticky-bar.d.ts.map +1 -0
  92. package/dist/inapp/renderers/stories.d.ts +31 -0
  93. package/dist/inapp/renderers/stories.d.ts.map +1 -0
  94. package/dist/inapp/renderers/types.d.ts +152 -0
  95. package/dist/inapp/renderers/types.d.ts.map +1 -0
  96. package/dist/inapp/renderers/video.d.ts +20 -0
  97. package/dist/inapp/renderers/video.d.ts.map +1 -0
  98. package/dist/inbox/AegisInbox.d.ts +106 -0
  99. package/dist/inbox/AegisInbox.d.ts.map +1 -0
  100. package/dist/inbox/index.d.ts +3 -0
  101. package/dist/inbox/index.d.ts.map +1 -0
  102. package/dist/index.d.ts +42 -0
  103. package/dist/index.d.ts.map +1 -0
  104. package/dist/index.js +15546 -0
  105. package/dist/index.js.map +1 -0
  106. package/dist/integrations/react.d.ts +19 -0
  107. package/dist/integrations/react.d.ts.map +1 -0
  108. package/dist/loyalty/AegisLoyaltyManager.d.ts +120 -0
  109. package/dist/loyalty/AegisLoyaltyManager.d.ts.map +1 -0
  110. package/dist/loyalty/index.d.ts +3 -0
  111. package/dist/loyalty/index.d.ts.map +1 -0
  112. package/dist/plugins/registry.d.ts +13 -0
  113. package/dist/plugins/registry.d.ts.map +1 -0
  114. package/dist/push/AegisWebPush.d.ts +199 -0
  115. package/dist/push/AegisWebPush.d.ts.map +1 -0
  116. package/dist/push/AegisWebPush.js +542 -0
  117. package/dist/push/AegisWebPush.js.map +1 -0
  118. package/dist/push/cdn-push.d.ts +21 -0
  119. package/dist/push/cdn-push.d.ts.map +1 -0
  120. package/dist/react.js +70 -0
  121. package/dist/react.js.map +1 -0
  122. package/dist/runtime/AegisMessageRuntime.d.ts +276 -0
  123. package/dist/runtime/AegisMessageRuntime.d.ts.map +1 -0
  124. package/dist/runtime/index.d.ts +3 -0
  125. package/dist/runtime/index.d.ts.map +1 -0
  126. package/dist/snippet.min.js +1 -0
  127. package/dist/state/intent_ledger.d.ts +136 -0
  128. package/dist/state/intent_ledger.d.ts.map +1 -0
  129. package/dist/triggers/ContactScoresFetcher.d.ts +113 -0
  130. package/dist/triggers/ContactScoresFetcher.d.ts.map +1 -0
  131. package/dist/triggers/IntentRuleEvaluator.d.ts +213 -0
  132. package/dist/triggers/IntentRuleEvaluator.d.ts.map +1 -0
  133. package/dist/triggers/IntentSnapshotCollector.d.ts +83 -0
  134. package/dist/triggers/IntentSnapshotCollector.d.ts.map +1 -0
  135. package/dist/triggers/SelectorBinder.d.ts +118 -0
  136. package/dist/triggers/SelectorBinder.d.ts.map +1 -0
  137. package/dist/triggers/TriggerEngine.d.ts +296 -0
  138. package/dist/triggers/TriggerEngine.d.ts.map +1 -0
  139. package/dist/triggers/behaviouralTriggers.d.ts +44 -0
  140. package/dist/triggers/behaviouralTriggers.d.ts.map +1 -0
  141. package/dist/triggers/index.d.ts +11 -0
  142. package/dist/triggers/index.d.ts.map +1 -0
  143. package/dist/triggers/microIntentTriggers.d.ts +80 -0
  144. package/dist/triggers/microIntentTriggers.d.ts.map +1 -0
  145. package/dist/types/config.d.ts +77 -0
  146. package/dist/types/config.d.ts.map +1 -0
  147. package/dist/types/events.d.ts +147 -0
  148. package/dist/types/events.d.ts.map +1 -0
  149. package/dist/types/index.d.ts +5 -0
  150. package/dist/types/index.d.ts.map +1 -0
  151. package/dist/types/plugin.d.ts +21 -0
  152. package/dist/types/plugin.d.ts.map +1 -0
  153. package/dist/types/type-safe-events.d.ts +14 -0
  154. package/dist/types/type-safe-events.d.ts.map +1 -0
  155. package/dist/utils/canonical-identity.d.ts +29 -0
  156. package/dist/utils/canonical-identity.d.ts.map +1 -0
  157. package/dist/utils/consent.d.ts +40 -0
  158. package/dist/utils/consent.d.ts.map +1 -0
  159. package/dist/utils/debounce.d.ts +3 -0
  160. package/dist/utils/debounce.d.ts.map +1 -0
  161. package/dist/utils/device.d.ts +6 -0
  162. package/dist/utils/device.d.ts.map +1 -0
  163. package/dist/utils/identity.d.ts +27 -0
  164. package/dist/utils/identity.d.ts.map +1 -0
  165. package/dist/utils/index.d.ts +7 -0
  166. package/dist/utils/index.d.ts.map +1 -0
  167. package/dist/utils/logger.d.ts +15 -0
  168. package/dist/utils/logger.d.ts.map +1 -0
  169. package/dist/utils/meta-cookies.d.ts +65 -0
  170. package/dist/utils/meta-cookies.d.ts.map +1 -0
  171. package/dist/utils/redact-url.d.ts +56 -0
  172. package/dist/utils/redact-url.d.ts.map +1 -0
  173. package/dist/utils/storage.d.ts +20 -0
  174. package/dist/utils/storage.d.ts.map +1 -0
  175. package/dist/utils/url-parser.d.ts +61 -0
  176. package/dist/utils/url-parser.d.ts.map +1 -0
  177. package/dist/utils/uuid.d.ts +4 -0
  178. package/dist/utils/uuid.d.ts.map +1 -0
  179. package/dist/utils/visitor.d.ts +43 -0
  180. package/dist/utils/visitor.d.ts.map +1 -0
  181. package/dist/widgets/AegisWidgetManager.d.ts +209 -0
  182. package/dist/widgets/AegisWidgetManager.d.ts.map +1 -0
  183. package/dist/widgets/index.d.ts +3 -0
  184. package/dist/widgets/index.d.ts.map +1 -0
  185. package/package.json +2 -1
package/dist/cdn.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { Aegis } from './core/analytics';
2
+ import { AegisMessageRuntime } from './runtime';
3
+ import { TriggerEngine } from './triggers';
4
+ import { AegisChat } from './chat';
5
+ import { bootstrap } from './core/bootstrap';
6
+ declare global {
7
+ interface Window {
8
+ aegis: any;
9
+ Aegis: typeof Aegis;
10
+ AegisMessageRuntime: typeof AegisMessageRuntime;
11
+ TriggerEngine: typeof TriggerEngine;
12
+ /** Customer chat launcher ("Shopping Assistant") constructor (Track A).
13
+ * Usually mounted via `new AegisMessageRuntime({ enableChat: true })`,
14
+ * but exposed for host pages that want to construct it standalone. */
15
+ AegisChat: typeof AegisChat;
16
+ /**
17
+ * `/v1/sdk/bootstrap` handshake. Exposed for integrations that embed the
18
+ * CDN bundle and need to retrieve `eventGovernance`, `vapidPublicKey`, etc.
19
+ * Added in SDK 1.4.0 alongside SDK-side event-governance.
20
+ */
21
+ aegisBootstrap: typeof bootstrap;
22
+ }
23
+ }
24
+ declare const instance: Aegis;
25
+ export default instance;
26
+ //# sourceMappingURL=cdn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAuB,MAAM,QAAQ,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAU7C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,KAAK,EAAE,GAAG,CAAC;QACX,KAAK,EAAE,OAAO,KAAK,CAAC;QACpB,mBAAmB,EAAE,OAAO,mBAAmB,CAAC;QAChD,aAAa,EAAE,OAAO,aAAa,CAAC;QACpC;;+EAEuE;QACvE,SAAS,EAAE,OAAO,SAAS,CAAC;QAC5B;;;;WAIG;QACH,cAAc,EAAE,OAAO,SAAS,CAAC;KAClC;CACF;AAKD,QAAA,MAAM,QAAQ,OAAc,CAAC;AA0E7B,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * AegisChat — the website / in-app "Shopping Assistant" launcher (Track A).
3
+ *
4
+ * A floating bottom-right bubble that expands into a chat panel, letting a
5
+ * customer converse with the SAME channel-neutral chat agent that powers
6
+ * WhatsApp. This is pure transport + surface — it does NOT contain any agent
7
+ * intelligence. Messages go to the gateway (`POST /v1/chat/message` →
8
+ * `chatbot.inbound channel='web'`); replies arrive as a thin `chat.message`
9
+ * SSE nudge (per-session, ticket-authed) that triggers a re-fetch of the
10
+ * rendered thread from `GET /v1/chat/history`. REST polling is the fallback
11
+ * when the panel is closed or SSE drops.
12
+ *
13
+ * Identity: true-anonymous visitors work — we send the SDK's `anonymous_id`
14
+ * (first-party cookie) and the server resolves/creates a stable contact. The
15
+ * server returns the opaque `contact_id`, which we echo on every subsequent
16
+ * message so the server hits the indexed PK path (and the anon→known stitch
17
+ * upgrades the contact when the customer later identifies).
18
+ *
19
+ * Rendering reuses the `web` payload the backend already emits
20
+ * (`chat_response_renderer.py`): text + `{type:'product_carousel', products:[…]}`.
21
+ */
22
+ export interface AegisChatConfig {
23
+ writeKey: string;
24
+ /** Gateway origin (the single public SDK surface). Falls back to same-origin. */
25
+ apiHost?: string;
26
+ organizationId?: string;
27
+ /** Known contact id when the visitor is already identified; else anonymous. */
28
+ contactId?: string;
29
+ /** 'web' (browser) or 'in_app' (mobile webview). Opaque to the agent. */
30
+ channel?: 'web' | 'in_app';
31
+ debugMode?: boolean;
32
+ /** Launcher header title shown to the customer. Default "Shopping Assistant";
33
+ * the storefront passes "Ask {Brand}". */
34
+ title?: string;
35
+ /** First assistant greeting bubble + attention tooltip text. */
36
+ greeting?: string;
37
+ /** Accent colour for the bubble + customer bubbles. Defaults to brand. */
38
+ accentColor?: string;
39
+ /** Bubble icon style. 'sparkle' (default, signals AI) | 'chat' (plain bubble)
40
+ * | 'logo' (renders `logoUrl`). No robot — brand-friendly by design. */
41
+ icon?: 'sparkle' | 'chat' | 'logo';
42
+ /** Image URL used when `icon: 'logo'` (brand logo / mascot). */
43
+ logoUrl?: string;
44
+ /** Corner the launcher docks to. */
45
+ position?: 'bottom-right' | 'bottom-left';
46
+ /** Surface style for the accent-filled chrome — the header AND the customer's
47
+ * sent message bubbles. 'solid' (default) = full accent fill + white text.
48
+ * 'tinted' = a soft accent wash over white + dark text (matches the
49
+ * storefront's tinted header band). Campaign-driven (`interactive_config.chat_theme`). */
50
+ surfaceStyle?: 'solid' | 'tinted';
51
+ /** Chat agent persona key bound to this launcher (campaign-driven). Sent to
52
+ * the backend on /v1/chat/message; honored server-side (Active Web Chat
53
+ * Phase E). Absent = the tenant's default persona. */
54
+ agentPersona?: string;
55
+ /** Quick-reply chips offered under the greeting (campaign-driven). */
56
+ quickReplies?: string[];
57
+ /** Fired when the panel transitions closed→open — a chat session begins.
58
+ * Used by the Active Web Chat renderer to report a campaign engagement. */
59
+ onSessionStart?: () => void;
60
+ /** Fired when the panel transitions open→closed — the session ends. */
61
+ onSessionEnd?: () => void;
62
+ /** Fired after a customer message is accepted by the server. */
63
+ onMessageSent?: () => void;
64
+ /** Presentation: 'bubble' (default, floating launcher) or 'nav' (headless —
65
+ * no bubble; the panel mounts but opens only via openPanel() / the public
66
+ * `aegis.chat.open()` API / a host trigger). Use 'nav' when the host owns
67
+ * the entry point (e.g. a mobile bottom-nav "Ask" button). */
68
+ displayMode?: 'bubble' | 'nav';
69
+ }
70
+ /** The single mounted launcher, or null if chat isn't active on this page. */
71
+ export declare function getCurrentLauncher(): AegisChat | null;
72
+ /** Open the chat panel (no-op if no launcher is mounted). */
73
+ export declare function openChat(prefill?: string): void;
74
+ /** Close the chat panel. */
75
+ export declare function closeChat(): void;
76
+ export declare class AegisChat {
77
+ private readonly writeKey;
78
+ private readonly organizationId?;
79
+ private readonly apiHost;
80
+ private contactId?;
81
+ private readonly channel;
82
+ private readonly debugMode;
83
+ private readonly title;
84
+ private readonly greeting;
85
+ private readonly accent;
86
+ private readonly icon;
87
+ private readonly logoUrl?;
88
+ private readonly position;
89
+ private readonly surfaceStyle;
90
+ private readonly displayMode;
91
+ private readonly agentPersona?;
92
+ private readonly quickReplies?;
93
+ private readonly onSessionStart?;
94
+ private readonly onSessionEnd?;
95
+ private readonly onMessageSent?;
96
+ private anonymousId?;
97
+ /** Per-session SSE ticket from the last /message response. Authorizes both
98
+ * the SSE subscription AND the contact-scoped /history read (the server
99
+ * requires it — chat history is not readable by contact_id alone). */
100
+ private sseTicket?;
101
+ /** True once a resume attempt ran this page-load (one /session call max). */
102
+ private sessionResumed;
103
+ private open;
104
+ private initialized;
105
+ private root?;
106
+ private bubble?;
107
+ private panel?;
108
+ private thread?;
109
+ private input?;
110
+ private unread;
111
+ private badge?;
112
+ private eventSource?;
113
+ private pollTimer?;
114
+ private renderedIds;
115
+ /** Contents of optimistically-rendered customer messages awaiting their
116
+ * server echo — used to dedup the history refetch (double-message fix). */
117
+ private pendingEcho;
118
+ private typingEl?;
119
+ private greetingTip?;
120
+ private attentionTimer?;
121
+ private hasInteracted;
122
+ constructor(config: AegisChatConfig);
123
+ initialize(): void;
124
+ /** Called by the runtime when the visitor identifies. */
125
+ updateContactId(contactId: string): void;
126
+ /** Programmatic open (used by the proactive TriggerEngine wiring). */
127
+ openPanel(prefill?: string): void;
128
+ closePanel(): void;
129
+ destroy(): void;
130
+ private send;
131
+ /** Validate + upload a picked file, then send it as a media message. */
132
+ private handleFile;
133
+ /** Read a File as bare base64 (strip the `data:…;base64,` prefix). */
134
+ private fileToBase64;
135
+ private connectSSE;
136
+ private disconnectSSE;
137
+ private startPolling;
138
+ private stopPolling;
139
+ private refreshHistory;
140
+ /** Bubble glyph by config. Default 'sparkle' (signals AI, brand-friendly —
141
+ * never a robot). 'logo' renders the brand image; falls back to sparkle. */
142
+ private bubbleIconHtml;
143
+ private mount;
144
+ /** Campaign-configured quick-reply chips shown under the greeting. Tapping a
145
+ * chip sends it as the customer's first message, then the row is removed. */
146
+ private renderQuickReplies;
147
+ private appendBubble;
148
+ /** Render one interactive message: the `web`-format product_carousel, or the
149
+ * WhatsApp-shape reply_button / list the store picker stores. */
150
+ private renderInteractive;
151
+ /** WhatsApp-shape `reply_button` (store picker: Nearest / Other stores / Change
152
+ * store). The body is already the bubble text, so only the buttons render. A
153
+ * tap sends the button title (the same text WhatsApp's inbound hands the bot)
154
+ * and disables the whole group, so one tap is one answer. */
155
+ private renderReplyButtons;
156
+ /** WhatsApp-shape `list` (store picker rows, incl. "Other stores"). Rows render
157
+ * expanded as tappable items; a tap sends the row title (an `outlet_N` row id
158
+ * is 0-based and does not resolve a store, the title does). */
159
+ private renderListRows;
160
+ private buildChoiceGroup;
161
+ private appendSystem;
162
+ private appendSystemGreeting;
163
+ private bumpUnread;
164
+ private clearUnread;
165
+ private scrollToBottom;
166
+ private readAnonId;
167
+ private readStoredContactId;
168
+ private persistContactId;
169
+ /** Restore a returning visitor's thread on open. Resolves an existing contact
170
+ * + mints a per-session ticket WITHOUT sending a message (history is ticket-
171
+ * gated). No-ops for brand-new visitors and once a ticket is already held. */
172
+ private resumeSession;
173
+ private showTyping;
174
+ private hideTyping;
175
+ private scheduleAttention;
176
+ private dismissAttention;
177
+ private log;
178
+ private injectStyles;
179
+ }
180
+ //# sourceMappingURL=AegisChat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AegisChat.d.ts","sourceRoot":"","sources":["../../src/chat/AegisChat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { AegisChat, openChat, closeChat, getCurrentLauncher } from './AegisChat';
2
+ export type { AegisChatConfig } from './AegisChat';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/chat/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjF,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,320 @@
1
+ import { AegisConfig, CellEndpoint } from '../types/config';
2
+ import { Plugin } from '../types/plugin';
3
+ import { ConsentPreferences, ConsentCategory } from '../utils/consent';
4
+ import { type LinkAttribution } from '../utils/url-parser';
5
+ import { EcommerceTracker } from '../ecommerce';
6
+ import { EventGovernanceHint } from '../governance';
7
+ import { UserNamespace } from './user-namespace';
8
+ /** One redeemable reward for the identified contact (from `contact_entitlements`). */
9
+ export interface EntitlementItem {
10
+ id: string;
11
+ /** coupon | discount | points | free_delivery | freebie */
12
+ type: string;
13
+ label: string | null;
14
+ /** Real, redeemable code (coupon/discount) — apply at checkout. */
15
+ coupon_code: string | null;
16
+ /** Awarded points (points grants). */
17
+ points: number | null;
18
+ /** Outlet the grant is attributed to; null = org-wide. */
19
+ location_id: string | null;
20
+ /** ISO 8601 expiry, or null for no expiry. */
21
+ expires_at: string | null;
22
+ }
23
+ /** Response of `aegis.getRewards()` / `GET /api/v1/sdk/entitlements`. */
24
+ export interface RewardsResponse {
25
+ contact_id: string;
26
+ loyalty: {
27
+ points_balance: number;
28
+ tier: string | null;
29
+ };
30
+ entitlements: EntitlementItem[];
31
+ }
32
+ export declare class Aegis {
33
+ private config;
34
+ private storage;
35
+ private identity;
36
+ /** Server-minted proof of the current contact (C1b). No setter is wired
37
+ * from `identify()` today — a host with a runtime (AegisMessageRuntime)
38
+ * calls `setContactToken()` alongside `runtime.updateContactId()`. */
39
+ private contactToken?;
40
+ private session;
41
+ private queue;
42
+ private transport;
43
+ private plugins;
44
+ private initPromise;
45
+ private consent;
46
+ private _ecommerce;
47
+ private _user;
48
+ private rateLimiter;
49
+ private nameGovernor;
50
+ private traitGovernor;
51
+ private _lastPageUrl;
52
+ private _popstateHandler;
53
+ private _originalPushState;
54
+ private _originalReplaceState;
55
+ private _lastEventIds;
56
+ private _workspaceCodes;
57
+ private _runtimeWorkspace;
58
+ private _runtimeLocation;
59
+ init(writeKey: string, config?: Partial<AegisConfig>): Promise<void>;
60
+ private _init;
61
+ /**
62
+ * SPA navigation tracking — monkey-patches pushState/replaceState and
63
+ * listens for popstate to fire page() on every client-side route change.
64
+ */
65
+ private startSPATracking;
66
+ private stopSPATracking;
67
+ private buildConfig;
68
+ private shouldRespectDNT;
69
+ private captureAdClickIDsOnInit;
70
+ private initializePlugins;
71
+ use(plugin: Plugin): void;
72
+ /**
73
+ * Symmetric counterpart to `use(plugin)`. Calls the plugin's `destroy()`
74
+ * hook (if defined) and removes it from the registry so its hooks no
75
+ * longer fire on subsequent events. Safe to call with a name that
76
+ * isn't registered — logs a warning and returns.
77
+ *
78
+ * Primary use case: React components that register a plugin in
79
+ * `useEffect` and need to unregister in the cleanup function so HMR /
80
+ * provider remount doesn't leak listeners. See cashier-portal's
81
+ * MetaPixelInjector for an example.
82
+ */
83
+ removePlugin(name: string): void;
84
+ /**
85
+ * Plugin-handshake P1 — ingest the workspace_code allowlist from the
86
+ * bootstrap response. Pass `result.workspaceCodes` from `bootstrap()`
87
+ * here so the SDK can do path-segment workspace detection on
88
+ * customer-facing pages like `/south/rewards`, `/ghatkopar/feedback`.
89
+ *
90
+ * Empty array is the right answer for single-outlet tenants — SDK
91
+ * will skip the path cascade and fall through to query param /
92
+ * setWorkspace() / gateway origin lookup.
93
+ *
94
+ * Safe to call before init() — the set is consulted at event-fire time.
95
+ */
96
+ ingestWorkspaceCodes(codes: string[] | null | undefined): void;
97
+ /**
98
+ * Plugin-handshake P1 (Track E) — explicitly set the workspace for
99
+ * subsequent events. Used by:
100
+ * - SPAs where workspace context changes via in-app routing
101
+ * - Mobile / RN apps that have no URL
102
+ * - Custom integrations that resolve workspace from their own state
103
+ *
104
+ * Pass null to clear (or call clearWorkspace()).
105
+ *
106
+ * Persisted to sessionStorage so SPA reloads / page transitions on the
107
+ * same outlet inherit it without re-calling.
108
+ */
109
+ setWorkspace(codeOrId: string | null): void;
110
+ /** Symmetric helper to clear the runtime workspace. */
111
+ clearWorkspace(): void;
112
+ /**
113
+ * P15.1 — ingest the outlet-code allowlist from bootstrap. The
114
+ * SDK consults this set when reading the URL path segment to
115
+ * decide whether `location.pathname.split('/')[1]` is a valid
116
+ * outlet code vs a generic route.
117
+ *
118
+ * Empty array = single-outlet tenant; SDK skips the path-segment
119
+ * cascade for location resolution.
120
+ *
121
+ * Safe to call before init(); the set is consulted at event-
122
+ * fire time.
123
+ */
124
+ ingestLocationCodes(codes: string[] | null | undefined): void;
125
+ /**
126
+ * P15.1 — explicitly set the active outlet for subsequent events.
127
+ * Used by:
128
+ * - Storefronts where outlet picker fires `aegis.setLocation()`
129
+ * on selection (so events that follow carry that outlet's
130
+ * location_id without the SDK having to re-parse the URL).
131
+ * - SPAs where outlet context changes via in-app routing.
132
+ * - Mobile/RN apps that have no URL.
133
+ *
134
+ * Pass null to clear (or call clearLocation()).
135
+ *
136
+ * Persisted to sessionStorage so SPA reloads + route transitions
137
+ * on the same outlet inherit it without re-calling.
138
+ */
139
+ setLocation(codeOrId: string | null): void;
140
+ /** Symmetric helper to clear the runtime location. */
141
+ clearLocation(): void;
142
+ /**
143
+ * P15.1 — same logic as `getPathWorkspaceCode()` but expresses
144
+ * the semantic correctly: under the new hierarchy, the first
145
+ * path segment after the brand subdomain IS the outlet code.
146
+ * Returns `undefined` when no outlet code matches the allowlist.
147
+ */
148
+ private getPathLocationCode;
149
+ /**
150
+ * P15.1 — resolve the effective `location_id` for the next event.
151
+ * Independent of `getEffectiveWorkspaceId()`: both run on every
152
+ * event so workspace_id (brand) and location_id (outlet) land
153
+ * on the same event when both are resolvable.
154
+ *
155
+ * Cascade (highest precedence first):
156
+ * 1. `this.config.location_id` — explicit operator config.
157
+ * 2. `?location=` query param (also accepts `?ws=` for back-
158
+ * compat with storefronts that pass outlet via the old
159
+ * param name — the value is the same; param naming only).
160
+ * 3. URL path segment matching the outlet-code allowlist.
161
+ * 4. Runtime `aegis.setLocation()` (in-memory).
162
+ * 5. sessionStorage `aegis_runtime_location`.
163
+ * 6. `undefined` — event-ingress treats as brand-tier
164
+ * (no outlet attribution).
165
+ */
166
+ getEffectiveLocationId(): string | undefined;
167
+ /**
168
+ * Inspect the URL's first path segment and return it if it's in the
169
+ * org's workspace_code allowlist. Skips well-known non-workspace prefixes
170
+ * (e.g. `b` for bill short codes; `s` is the storefront app slug).
171
+ *
172
+ * Returns undefined when:
173
+ * - window is undefined (SSR / Node)
174
+ * - path is empty / root
175
+ * - first segment isn't in `_workspaceCodes` (e.g. /products, /cart)
176
+ *
177
+ * The returned value is a workspace CODE (slug like "south"), not a
178
+ * UUID. The gateway normalizes code → UUID server-side via
179
+ * workspace_subaccounts lookup with Redis cache.
180
+ */
181
+ private getPathWorkspaceCode;
182
+ /**
183
+ * Resolve the effective `workspace_id` for the next event.
184
+ *
185
+ * Cascade (highest precedence first):
186
+ * 1. `this.config.workspace_id` — explicit operator config (headless
187
+ * SDK usage, server-rendered apps, native shells).
188
+ * 2. `?ws=` query param on the current URL — the P3 storefront URL
189
+ * contract. The outlet picker writes this via `router.replace`.
190
+ * 3. URL path segment (P1 Track A) — `/south/rewards` → "south" when
191
+ * "south" is in the org's workspace_code allowlist.
192
+ * 4. `aegis.setWorkspace()` runtime override (P1 Track E) — SPAs +
193
+ * mobile + custom integrations.
194
+ * 5. sessionStorage `aegis_runtime_ws` — persists setWorkspace across
195
+ * reloads/SPA route changes.
196
+ * 6. `undefined` — gateway falls back to `resolveByOrigin` lookup
197
+ * against the property's allowed_origins.
198
+ *
199
+ * The returned value can be EITHER a UUID (from config / ?ws=) or a
200
+ * workspace CODE slug (from path / setWorkspace). The gateway
201
+ * normalizes slug → UUID server-side; analytics layer never needs to
202
+ * worry about the difference.
203
+ *
204
+ * See docs/architecture/MULTI_OUTLET_URL_STRATEGY.md §2.3 and
205
+ * docs/architecture/PLUGIN_HANDSHAKE_AUTOMATION.md §2.
206
+ */
207
+ /**
208
+ * Public so peer SDK surfaces (AegisMessageRuntime / AegisInAppManager /
209
+ * AegisWidgetManager) can plumb the same
210
+ * resolved workspace into their own gateway POSTs. Each manager calls
211
+ * the gateway on its own endpoint (`/v1/in-app/events`,
212
+ * `/v1/widgets/track-event`); without this,
213
+ * those events arrive at event-ingress with no workspace_id stamped
214
+ * → impressions/clicks fall back to the org's primary workspace and
215
+ * cross-outlet attribution breaks.
216
+ */
217
+ getEffectiveWorkspaceId(): string | undefined;
218
+ track(eventName: string, properties?: Record<string, any>): void;
219
+ identify(userId: string, traits?: Record<string, any>): void;
220
+ page(name?: string, properties?: Record<string, any>): void;
221
+ group(groupId: string, traits?: Record<string, any>): void;
222
+ alias(newUserId: string): void;
223
+ /**
224
+ * SPA-logical screen view. Distinct from `page()` (URL-bound) — fires
225
+ * when the user enters a logical surface like cart / checkout / drawer
226
+ * without a URL change. Gateway maps `screen` → `engagement.screen_view`.
227
+ */
228
+ screen(name: string, properties?: Record<string, any>): void;
229
+ private captureEvent;
230
+ /**
231
+ * Emit a coalesced meta-event reporting client-side rate-limit drops.
232
+ * Bypasses the limiter (see captureEvent guard).
233
+ */
234
+ private emitRateLimitMeta;
235
+ reset(): void;
236
+ /**
237
+ * Ingest the event-governance hint returned from `/v1/sdk/bootstrap`.
238
+ *
239
+ * Callers (Shopify pixel, snippet, react integration) run `bootstrap()`
240
+ * themselves and pass the resulting `eventGovernance` field here so the
241
+ * SDK can self-throttle novel event names before they hit the gateway.
242
+ *
243
+ * Passing null/undefined disables governance (Enterprise plan / outage
244
+ * fail-open). Safe to call before `init()` — the hint is stored and
245
+ * applied as soon as init completes.
246
+ */
247
+ ingestGovernanceHint(hint: EventGovernanceHint | null | undefined): void;
248
+ /**
249
+ * Drain the client-side drop counter and emit a meta-event. Called
250
+ * periodically by the queue flush path so ops dashboards see novel-name
251
+ * amplification patterns in near-real-time.
252
+ */
253
+ private emitGovernanceDropMeta;
254
+ flush(): Promise<void>;
255
+ getAnonymousId(): string | null;
256
+ getUserId(): string | null;
257
+ /**
258
+ * C1b: register the server-minted proof for the CURRENT contact (as
259
+ * returned by `getUserId()`). A host wiring `AegisMessageRuntime` calls
260
+ * this alongside `runtime.updateContactId(id, token)` so `getRewards()`
261
+ * can also present `X-Contact-Token`. Pass `undefined` to clear it (e.g.
262
+ * on logout, or when the id changes without a fresh token).
263
+ */
264
+ setContactToken(token?: string): void;
265
+ /**
266
+ * The Aegis short-link attribution captured from this visitor's landing URL
267
+ * (`aegis_code` + the link row's `aegis_campaign` / `aegis_journey` /
268
+ * `aegis_playbook` / `aegis_button`), or `{}` when they did not arrive
269
+ * through one. Hosts forward `aegis_code` with an order so the order can be
270
+ * joined to the send that brought the shopper. Never contains `utm_*`, `k`,
271
+ * `t` or `u`.
272
+ */
273
+ getLinkAttribution(): LinkAttribution;
274
+ /**
275
+ * Fetch the identified contact's REDEEMABLE rewards — coupon codes the
276
+ * storefront can auto-apply at checkout + loyalty points balance/tier.
277
+ * Mirrors `GET /api/v1/sdk/entitlements`. Returns `null` when the SDK is
278
+ * uninitialised, the contact is anonymous, the endpoint returns 204 (nothing
279
+ * to show), or on any network/HTTP error — callers degrade gracefully.
280
+ *
281
+ * Scoped to the identified contact (own grants only) and, when an outlet is
282
+ * resolvable (`getEffectiveLocationId()`), to org-wide + that outlet's grants.
283
+ */
284
+ getRewards(): Promise<RewardsResponse | null>;
285
+ getSessionId(): string | null;
286
+ /**
287
+ * B1.2 — Tenant-Pixel coexistence handoff. Returns the messageId of the
288
+ * most recent `track('<eventName>', ...)` call, or null if no event of
289
+ * that name has been tracked since SDK init.
290
+ *
291
+ * Use this from a tenant's own Meta Pixel script (e.g. via GTM) to pass
292
+ * the same event_id to `fbq('track', '<eventName>', payload, {eventID: id})`.
293
+ * Meta dedups on (pixel_id, event_name, event_id) so the browser-fired
294
+ * Pixel event and our server-side CAPI event collapse to one — preventing
295
+ * double-counting.
296
+ *
297
+ * Event names are case-sensitive ("Purchase" ≠ "purchase") — Meta's dedup
298
+ * is also case-sensitive, so be exact.
299
+ *
300
+ * See docs/integrations/META_PIXEL_COEXISTENCE.md.
301
+ */
302
+ lastEventId(eventName: string): string | null;
303
+ debug(enable?: boolean): void;
304
+ setCell(cellEndpoint: CellEndpoint): void;
305
+ getCellInfo(): {
306
+ activeCell: CellEndpoint | null;
307
+ latencies: Map<string, number>;
308
+ } | null;
309
+ setConsent(preferences: Partial<ConsentPreferences>): void;
310
+ grantConsent(category?: ConsentCategory): void;
311
+ denyConsent(category?: ConsentCategory): void;
312
+ hasConsent(category: ConsentCategory): boolean;
313
+ getConsentPreferences(): ConsentPreferences | null;
314
+ onConsentChange(callback: (preferences: ConsentPreferences) => void): () => void;
315
+ private assertInitialized;
316
+ get ecommerce(): EcommerceTracker;
317
+ get user(): UserNamespace;
318
+ destroy(): void;
319
+ }
320
+ //# sourceMappingURL=analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/core/analytics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * SDK Bootstrap
3
+ *
4
+ * Strict origin-assertion handshake against the control-plane. Called once
5
+ * at SDK init — resolves writeKey → propertyId, asserts origin, and returns
6
+ * the VAPID public key + first-party cookie id the SDK needs for the rest
7
+ * of the session.
8
+ *
9
+ * A failed bootstrap (401/403) aborts SDK init — the SDK refuses to emit
10
+ * events or request push permission against an origin it cannot prove it
11
+ * owns.
12
+ *
13
+ * See docs/architecture/SUBSCRIPTION_PROPERTY_ARCHITECTURE.md §5.
14
+ */
15
+ export interface BootstrapRequest {
16
+ writeKey: string;
17
+ currentOrigin?: string;
18
+ firstPartyCookieId?: string;
19
+ attestationToken?: string;
20
+ userAgent?: string;
21
+ }
22
+ import type { EventGovernanceHint } from '../governance';
23
+ export interface BootstrapResult {
24
+ propertyId: string;
25
+ organizationId: string;
26
+ workspaceId: string;
27
+ propertyType: 'shopify_store' | 'hosted_commerce' | 'custom_website' | 'mobile_app';
28
+ vapidPublicKey: string | null;
29
+ allowedOrigins: string[];
30
+ pushEnabled: boolean;
31
+ inAppEnabled: boolean;
32
+ transportMode: string;
33
+ firstPartyCookieId: string;
34
+ /**
35
+ * Event-governance hint for SDK-side unique-event-name cap enforcement.
36
+ * Null = Enterprise plan / CP outage / org has no cap. Safe to pass
37
+ * directly to `aegis.ingestGovernanceHint()`.
38
+ */
39
+ eventGovernance: EventGovernanceHint | null;
40
+ /**
41
+ * @deprecated since P15.1 (2026-05-26) — use `locationCodes` instead.
42
+ * Pre-2026-05-26 the path segment after the brand subdomain was a
43
+ * workspace_code; the canonical hierarchy reversal made it a
44
+ * location_code (outlet under a brand). Field name retained for
45
+ * backward compat with SDK consumers that haven't migrated; new
46
+ * consumers MUST read `locationCodes`. Server still populates BOTH
47
+ * with the same array during the deprecation window so a stale
48
+ * SDK keeps working.
49
+ */
50
+ workspaceCodes: string[];
51
+ /**
52
+ * P15.1 — outlet-code allowlist for SDK path-segment detection.
53
+ * Empty array = no outlet codes registered for this org (single-
54
+ * outlet tenant). SDK uses this set to decide whether
55
+ * `location.pathname.split('/')[1]` is a valid outlet code vs a
56
+ * generic route (`/products`, `/collections`). Pass to
57
+ * `aegis.ingestLocationCodes()` after bootstrap completes.
58
+ *
59
+ * Same array contents as `workspaceCodes` during the deprecation
60
+ * window — renaming the field gives semantic clarity (these ARE
61
+ * location codes under the new hierarchy) without breaking
62
+ * existing consumers.
63
+ */
64
+ locationCodes: string[];
65
+ }
66
+ export declare class BootstrapError extends Error {
67
+ readonly status: number;
68
+ constructor(status: number, message: string);
69
+ }
70
+ /**
71
+ * Read the first-party cookie id from document.cookie. Returns null if
72
+ * unset — caller should pass undefined so the server issues a fresh one.
73
+ */
74
+ export declare function readFirstPartyCookie(): string | null;
75
+ /**
76
+ * Persist the first-party cookie id returned by the server. Stored as a
77
+ * first-party cookie (readable by JS — it's not a secret, it's a device
78
+ * id) so that the same browser hitting a second origin on the same
79
+ * registrable domain gets the same cookie back.
80
+ */
81
+ export declare function writeFirstPartyCookie(cookieId: string): void;
82
+ /**
83
+ * Perform the bootstrap handshake.
84
+ *
85
+ * @throws BootstrapError on 4xx — the SDK should stop init and surface the
86
+ * error to the console. 5xx are retried once.
87
+ */
88
+ export declare function bootstrap(apiHost: string, req: BootstrapRequest): Promise<BootstrapResult>;
89
+ /**
90
+ * Derive a deterministic device fingerprint from the first-party cookie id
91
+ * and a few stable UA parts. This is the value sent on every push-subscribe
92
+ * call — its stability lets the backend UPSERT on (property_id, fingerprint)
93
+ * across re-subscribes and VAPID rotations.
94
+ */
95
+ export declare function deriveDeviceFingerprint(firstPartyCookieId: string): Promise<string>;
96
+ //# sourceMappingURL=bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/core/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,eAAe,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,YAAY,CAAC;IACpF,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,eAAe,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC5C;;;;;;;;;OASG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;;;;;;;;OAYG;IACH,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,qBAAa,cAAe,SAAQ,KAAK;aACX,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAI5D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAIpD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAqB5D;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,eAAe,CAAC,CAoC1B;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAAC,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBzF"}