@active-reach/web-sdk 1.3.1 → 1.5.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 (51) hide show
  1. package/dist/aegis.min.js +1 -1
  2. package/dist/aegis.min.js.map +1 -1
  3. package/dist/{analytics-B0JfoAJs.mjs → analytics-C00PJUSy.mjs} +269 -2
  4. package/dist/analytics-C00PJUSy.mjs.map +1 -0
  5. package/dist/cdn.d.ts +7 -0
  6. package/dist/cdn.d.ts.map +1 -1
  7. package/dist/core/analytics.d.ts +20 -0
  8. package/dist/core/analytics.d.ts.map +1 -1
  9. package/dist/core/bootstrap.d.ts +71 -0
  10. package/dist/core/bootstrap.d.ts.map +1 -0
  11. package/dist/core/prefetch-bundle-client.d.ts +150 -0
  12. package/dist/core/prefetch-bundle-client.d.ts.map +1 -0
  13. package/dist/governance/bloom-filter.d.ts +47 -0
  14. package/dist/governance/bloom-filter.d.ts.map +1 -0
  15. package/dist/governance/index.d.ts +6 -0
  16. package/dist/governance/index.d.ts.map +1 -0
  17. package/dist/governance/murmur3.d.ts +43 -0
  18. package/dist/governance/murmur3.d.ts.map +1 -0
  19. package/dist/governance/name-governor.d.ts +98 -0
  20. package/dist/governance/name-governor.d.ts.map +1 -0
  21. package/dist/inapp/AegisInAppManager.d.ts +28 -1
  22. package/dist/inapp/AegisInAppManager.d.ts.map +1 -1
  23. package/dist/inapp/renderers/carousel-cards.d.ts +15 -0
  24. package/dist/inapp/renderers/carousel-cards.d.ts.map +1 -0
  25. package/dist/inapp/renderers/coachmark-tour.d.ts +24 -0
  26. package/dist/inapp/renderers/coachmark-tour.d.ts.map +1 -0
  27. package/dist/inapp/renderers/index.d.ts +12 -0
  28. package/dist/inapp/renderers/index.d.ts.map +1 -0
  29. package/dist/inapp/renderers/product-recommendation.d.ts +23 -0
  30. package/dist/inapp/renderers/product-recommendation.d.ts.map +1 -0
  31. package/dist/inapp/renderers/progress-bar.d.ts +24 -0
  32. package/dist/inapp/renderers/progress-bar.d.ts.map +1 -0
  33. package/dist/inapp/renderers/sticky-bar.d.ts +14 -0
  34. package/dist/inapp/renderers/sticky-bar.d.ts.map +1 -0
  35. package/dist/inapp/renderers/types.d.ts +27 -0
  36. package/dist/inapp/renderers/types.d.ts.map +1 -0
  37. package/dist/inbox/AegisInbox.d.ts +103 -0
  38. package/dist/inbox/AegisInbox.d.ts.map +1 -0
  39. package/dist/inbox/index.d.ts +3 -0
  40. package/dist/inbox/index.d.ts.map +1 -0
  41. package/dist/index.d.ts +8 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +1396 -10
  44. package/dist/index.js.map +1 -1
  45. package/dist/push/AegisWebPush.d.ts +17 -2
  46. package/dist/push/AegisWebPush.d.ts.map +1 -1
  47. package/dist/push/AegisWebPush.js +95 -29
  48. package/dist/push/AegisWebPush.js.map +1 -1
  49. package/dist/react.js +1 -1
  50. package/package.json +1 -1
  51. package/dist/analytics-B0JfoAJs.mjs.map +0 -1
@@ -0,0 +1,150 @@
1
+ /**
2
+ * PrefetchBundleClient — unified init-time resolver for in-app state.
3
+ *
4
+ * Fetches /v1/sdk/prefetch-bundle at SDK init and on a 5-minute ETag
5
+ * refresh cadence. The bundle payload carries:
6
+ * • `campaigns[]` — eligible, property-scoped, A/B-assigned campaigns
7
+ * armed for this contact. EVERY in-app type is in
8
+ * here (modal, banner, spin_wheel, carousel_cards,
9
+ * sticky_bar, progress_bar, coachmark_tour, etc.).
10
+ * • `inbox` — first page + unread count for the notification
11
+ * drawer; lets AegisInbox hydrate without a second
12
+ * round-trip.
13
+ * • `etag` — content-hashed, stable when state is unchanged;
14
+ * 304 responses cost ~50ms and consume no body.
15
+ * • `invalidation_topic` — SSE channel name the cell-plane publishes
16
+ * to when a playbook arms a campaign mid-session.
17
+ * The SDK does NOT open SSE on that topic today —
18
+ * we rely on the 5-minute poll + an explicit
19
+ * `refresh()` hook that app code (AegisInAppManager,
20
+ * AegisInbox) call on relevant user actions.
21
+ *
22
+ * This is the cornerstone of the preload-first contract from
23
+ * docs/architecture/IN_APP_MESSAGES_EXPANSION_PLAN.md §1. The render
24
+ * path must NEVER hit the network at trigger time — the bundle is
25
+ * populated at init, and everything renders from memory.
26
+ */
27
+ export interface PrefetchBundleCampaign {
28
+ id: string;
29
+ type: string;
30
+ sub_type?: string;
31
+ title: string;
32
+ body: string;
33
+ image_url?: string;
34
+ action_url?: string;
35
+ button_text?: string;
36
+ background_color?: string;
37
+ text_color?: string;
38
+ priority: number;
39
+ expires_at?: string | null;
40
+ frequency?: {
41
+ max_impressions?: number;
42
+ max_impressions_per_day?: number;
43
+ cooldown_seconds?: number;
44
+ };
45
+ interactive_config?: Record<string, unknown>;
46
+ client_trigger?: {
47
+ type: string;
48
+ config?: Record<string, unknown>;
49
+ };
50
+ assigned_variant_id?: string;
51
+ inbox_enabled?: boolean;
52
+ }
53
+ export interface PrefetchBundleInboxEntry {
54
+ id: string;
55
+ source: string;
56
+ campaign_id: string | null;
57
+ title: string;
58
+ body: string;
59
+ media_url: string | null;
60
+ cta_url: string | null;
61
+ metadata: Record<string, unknown> | null;
62
+ read: boolean;
63
+ read_at: string | null;
64
+ created_at: string | null;
65
+ expires_at: string | null;
66
+ }
67
+ export interface PrefetchBundleInbox {
68
+ unread_count: number;
69
+ page: PrefetchBundleInboxEntry[];
70
+ cursor: string | null;
71
+ }
72
+ export interface PrefetchBundle {
73
+ etag: string;
74
+ generated_at: string;
75
+ ttl_seconds: number;
76
+ invalidation_topic: string;
77
+ campaigns: PrefetchBundleCampaign[];
78
+ inbox: PrefetchBundleInbox;
79
+ }
80
+ export interface PrefetchBundleContext {
81
+ device_type?: string;
82
+ page_url?: string;
83
+ geo?: string;
84
+ is_new_user?: boolean;
85
+ }
86
+ export interface PrefetchBundleClientOptions {
87
+ apiHost: string;
88
+ writeKey: string;
89
+ organizationId?: string;
90
+ contactId?: string;
91
+ userId?: string;
92
+ propertyId?: string;
93
+ /** Cached AB assignments from localStorage, base64-json. */
94
+ abAssignments?: Record<string, string>;
95
+ /** Polling cadence; defaults to the bundle's own `ttl_seconds` (300s). */
96
+ pollIntervalMs?: number;
97
+ /** Factory for client context — re-evaluated on each fetch so device/page
98
+ * state stays fresh without forcing callers to re-instantiate the client. */
99
+ contextProvider?: () => PrefetchBundleContext;
100
+ }
101
+ export type PrefetchBundleListener = (bundle: PrefetchBundle) => void;
102
+ export declare class PrefetchBundleClient {
103
+ private apiHost;
104
+ private writeKey;
105
+ private organizationId?;
106
+ private contactId?;
107
+ private userId?;
108
+ private propertyId?;
109
+ private abAssignments;
110
+ private pollIntervalMs;
111
+ private contextProvider;
112
+ private currentETag;
113
+ private currentBundle;
114
+ private pollTimer;
115
+ private listeners;
116
+ private inflightRefetch;
117
+ constructor(options: PrefetchBundleClientOptions);
118
+ /**
119
+ * Initial fetch + start the background ETag poll. Resolves to the bundle
120
+ * (or `null` if the first fetch failed — callers should fall back to an
121
+ * empty campaign list, not abort SDK init).
122
+ */
123
+ start(): Promise<PrefetchBundle | null>;
124
+ stop(): void;
125
+ getBundle(): PrefetchBundle | null;
126
+ getCampaigns(): PrefetchBundleCampaign[];
127
+ getInbox(): PrefetchBundleInbox;
128
+ /** Force a refresh (dedupes concurrent calls). Exposed so inbox mutations
129
+ * and campaign-activation SSE messages can trigger a refetch on demand. */
130
+ refresh(): Promise<PrefetchBundle | null>;
131
+ /** Subscribe to bundle changes (emits on first fetch + on any content
132
+ * change — ETag 304 does NOT fire the listener). Returns an unsubscribe. */
133
+ onChange(listener: PrefetchBundleListener): () => void;
134
+ /**
135
+ * Update the identity tuple — called by AegisInAppManager when the host
136
+ * app resolves a contactId post-init (e.g., after login). Triggers an
137
+ * immediate refresh since the eligible campaigns + inbox will differ.
138
+ */
139
+ updateIdentity(partial: {
140
+ contactId?: string;
141
+ userId?: string;
142
+ organizationId?: string;
143
+ propertyId?: string;
144
+ }): void;
145
+ /** Update cached AB assignments. Called by downstream renderers after
146
+ * they display a variant. Persisted to localStorage by higher layers. */
147
+ setAbAssignments(assignments: Record<string, string>): void;
148
+ private fetch;
149
+ }
150
+ //# sourceMappingURL=prefetch-bundle-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefetch-bundle-client.d.ts","sourceRoot":"","sources":["../../src/core/prefetch-bundle-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Bloom filter — wire-compatible with the Python builder in
3
+ * apps/control-plane/app/services/event_governance_bloom.py
4
+ *
5
+ * This SDK-side variant is QUERY-ONLY. The filter is built server-side
6
+ * from the org's registered event-name set, base64-encoded, and shipped
7
+ * to the browser on `/v1/sdk/bootstrap`. The SDK reads it once, uses it
8
+ * to gate `track()` calls, and discards it on the next bootstrap.
9
+ *
10
+ * Wire format:
11
+ * • `m` bits of storage, represented as m/8 bytes, base64-encoded.
12
+ * • Bit `i` is at byte `i >> 3`, bitmask `1 << (i & 7)` — LSB-first.
13
+ * • `m` MUST be a power of two — allows `idx & (m-1)` modulo.
14
+ * • `k` hash functions synthesized via Kirsch-Mitzenmacher from two
15
+ * MurmurHash3 x86-32 hashes with seeds (seedA, seedB):
16
+ * h_i(x) = (h1(x) + i * h2(x)) mod m
17
+ * • Input strings are UTF-8 encoded (handled inside murmurhash3_x86_32).
18
+ */
19
+ export interface BloomFilterParams {
20
+ /** Bits in the filter (must be power of 2). */
21
+ m: number;
22
+ /** Number of hash functions (Kirsch-Mitzenmacher synthesized). */
23
+ k: number;
24
+ /** Seed for the first MurmurHash3 call. */
25
+ seedA: number;
26
+ /** Seed for the second MurmurHash3 call. */
27
+ seedB: number;
28
+ }
29
+ export declare class BloomFilter {
30
+ private readonly params;
31
+ private readonly buf;
32
+ private readonly mask;
33
+ constructor(buf: Uint8Array, params: BloomFilterParams);
34
+ /** Build from the wire format (base64 bytes + explicit params). */
35
+ static fromBase64(bloomB64: string, params: BloomFilterParams): BloomFilter;
36
+ /**
37
+ * Returns true if `name` is probably in the set — possibly with the
38
+ * filter's configured false-positive rate. FALSE is always authoritative.
39
+ *
40
+ * FP here means: SDK thinks a name is already registered when it isn't.
41
+ * That costs one wasted server round-trip (gateway does the exact check
42
+ * and catches it) — strictly safer than a false-negative, which could
43
+ * leak a novel name past the SDK.
44
+ */
45
+ has(name: string): boolean;
46
+ }
47
+ //# sourceMappingURL=bloom-filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bloom-filter.d.ts","sourceRoot":"","sources":["../../src/governance/bloom-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAuBH,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,CAAC,EAAE,MAAM,CAAC;IACV,kEAAkE;IAClE,CAAC,EAAE,MAAM,CAAC;IACV,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,WAAW;IAIO,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHpD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAElB,GAAG,EAAE,UAAU,EAAmB,MAAM,EAAE,iBAAiB;IAavE,mEAAmE;IACnE,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,WAAW;IAK3E;;;;;;;;OAQG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAe3B"}
@@ -0,0 +1,6 @@
1
+ export { murmurhash3_x86_32, murmurhash3_bytes } from './murmur3';
2
+ export { BloomFilter } from './bloom-filter';
3
+ export type { BloomFilterParams } from './bloom-filter';
4
+ export { NameGovernor } from './name-governor';
5
+ export type { EventGovernanceHint, DropReport } from './name-governor';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/governance/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * MurmurHash3 x86-32 — deterministic, byte-identical with Python `mmh3.hash`.
3
+ *
4
+ * We hand-roll rather than pull a dep because (a) our bundle-budget is
5
+ * aggressive for storefront first-paint, and (b) this is the authoritative
6
+ * cross-language hash for the event-governance bloom filter — any behavior
7
+ * drift between Python and JS produces silent FP-rate spikes in prod.
8
+ *
9
+ * Contract:
10
+ * • Input is a JS string. It is UTF-8 encoded via TextEncoder before hashing.
11
+ * • Output is an unsigned 32-bit integer (0 .. 2^32-1).
12
+ * • Matches `mmh3.hash(s.encode('utf-8'), seed=seed, signed=False)` in
13
+ * Python exactly — verified by libs/shared-types/bloom-test-vectors.json
14
+ * in CI.
15
+ *
16
+ * Reference: Austin Appleby, MurmurHash3 (public domain).
17
+ * https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp
18
+ *
19
+ * Implementation notes:
20
+ * • All arithmetic on 32-bit ints. JS does bitwise ops on 32-bit ints natively;
21
+ * `Math.imul` gives us correct 32-bit multiplication without overflow.
22
+ * • We use `>>> 0` to coerce to unsigned after every step that could produce
23
+ * a negative or >32-bit value.
24
+ * • UTF-8 encoding matters — a naive `charCodeAt` loop would mis-hash any
25
+ * string with non-ASCII characters (e.g. emoji, accented chars) and the
26
+ * Python side would disagree. We always encode via TextEncoder first.
27
+ */
28
+ /**
29
+ * Compute MurmurHash3 x86-32 of a UTF-8 encoded string.
30
+ *
31
+ * @param input The string to hash.
32
+ * @param seed 32-bit unsigned seed.
33
+ * @returns Unsigned 32-bit integer hash.
34
+ */
35
+ export declare function murmurhash3_x86_32(input: string, seed?: number): number;
36
+ /**
37
+ * Compute MurmurHash3 x86-32 over a byte buffer directly.
38
+ *
39
+ * Exposed for callers that already have UTF-8 bytes and want to skip the
40
+ * encode step (e.g., internal bloom-hash paths).
41
+ */
42
+ export declare function murmurhash3_bytes(bytes: Uint8Array, seed?: number): number;
43
+ //# sourceMappingURL=murmur3.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"murmur3.d.ts","sourceRoot":"","sources":["../../src/governance/murmur3.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,MAAU,GAAG,MAAM,CAI1E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE,MAAU,GAAG,MAAM,CA+C7E"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * NameGovernor — client-side event-name cap enforcement.
3
+ *
4
+ * The governor consumes an `EventGovernanceHint` from the bootstrap response
5
+ * and decides whether to let a `track()` call proceed to the network or drop
6
+ * it locally.
7
+ *
8
+ * Why this exists:
9
+ * Without it, a page that calls `track('new_btn_' + Date.now())` in a
10
+ * render loop would (a) pass the local rate-limiter if within burst, (b)
11
+ * force the gateway to ask control-plane for a verdict on every unique
12
+ * name, and (c) amplify the CP `/event-governance/check` load quadratically
13
+ * in the number of tabs firing the same bug. The bloom filter gives the
14
+ * SDK enough information to drop novel names locally once the org hits
15
+ * its cap, collapsing the amplification to zero.
16
+ *
17
+ * Design constraints:
18
+ * • FAIL-OPEN — missing hint (Enterprise org, Redis outage) lets every
19
+ * name through. The gateway is still the authoritative cap.
20
+ * • FALSE-POSITIVE-SAFE — if the bloom says "known" for a name that isn't
21
+ * actually registered, we send to gateway and the gateway's exact check
22
+ * catches it. FPs cost one round trip, not a cap bypass.
23
+ * • LOCAL-MEMO — a novel name that has already charged `remainingNewNames`
24
+ * in this tab must NOT charge again on subsequent calls within the same
25
+ * hint TTL. Without this, `track('new_btn_click')` fired 50 times would
26
+ * drain 50 from the counter and block every OTHER legitimate novel name.
27
+ * See `localNovelNames`.
28
+ *
29
+ * See docs/architecture/RFC_2026_04_SDK_GOVERNANCE_HINTS.md §3.3.
30
+ */
31
+ /** Shape of the hint delivered by `/v1/sdk/bootstrap`. */
32
+ export interface EventGovernanceHint {
33
+ bloom_algo: string;
34
+ seed_a: number;
35
+ seed_b: number;
36
+ k: number;
37
+ m: number;
38
+ bloom_b64: string;
39
+ remaining_new_names: number | null;
40
+ /**
41
+ * When true, the server is in its 7-day soft-cap grace window: it accepts
42
+ * novel event names past the cap. SDK must NOT drop locally in this mode —
43
+ * doing so would enforce harder than the server. See
44
+ * apps/control-plane/app/schemas/event_governance_hint.py for the canonical
45
+ * contract.
46
+ */
47
+ grace_active?: boolean;
48
+ ttl_seconds: number;
49
+ }
50
+ export interface DropReport {
51
+ /** Map of event_name → count of local drops since last drain. */
52
+ events: Record<string, number>;
53
+ /** Total events dropped across all names (sum of values). */
54
+ total: number;
55
+ /** When the report window started (ms since epoch). */
56
+ since: number;
57
+ }
58
+ export declare class NameGovernor {
59
+ private bloom;
60
+ private remainingNewNames;
61
+ private graceActive;
62
+ /**
63
+ * Names this SDK instance has seen AS NOVEL and already charged against
64
+ * `remainingNewNames`. Reset on every `ingestHint()` so we don't leak
65
+ * accounting across hint refreshes.
66
+ */
67
+ private localNovelNames;
68
+ /** Coalesced telemetry — flushed to the transport via drainDropReport(). */
69
+ private droppedSinceLastReport;
70
+ private reportWindowStart;
71
+ private hasWarnedThisSession;
72
+ /**
73
+ * Ingest a freshly-bootstrapped hint. Call on every successful bootstrap.
74
+ * Passing `null` disables governance (fail-open).
75
+ */
76
+ ingestHint(hint: EventGovernanceHint | null): void;
77
+ /**
78
+ * Decide whether a `track()` call should proceed.
79
+ *
80
+ * Returns true = send to network (rate-limiter still runs after).
81
+ * Returns false = drop locally; caller should return early.
82
+ */
83
+ shouldSend(eventName: string): boolean;
84
+ /**
85
+ * Snapshot + reset the dropped-names counter. Called by the telemetry
86
+ * beacon on batch flush so the gateway gets visibility into client-side
87
+ * drops for ops dashboards.
88
+ */
89
+ drainDropReport(): DropReport | null;
90
+ /** @internal */
91
+ _debugState(): {
92
+ hasBloom: boolean;
93
+ remaining: number;
94
+ localNovel: number;
95
+ graceActive: boolean;
96
+ };
97
+ }
98
+ //# sourceMappingURL=name-governor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"name-governor.d.ts","sourceRoot":"","sources":["../../src/governance/name-governor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;CACf;AAeD,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,WAAW,CAAkB;IAErC;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAA0B;IAEjD,4EAA4E;IAC5E,OAAO,CAAC,sBAAsB,CAAkC;IAChE,OAAO,CAAC,iBAAiB,CAAsB;IAC/C,OAAO,CAAC,oBAAoB,CAAS;IAErC;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,GAAG,IAAI;IA4BlD;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAqCtC;;;;OAIG;IACH,eAAe,IAAI,UAAU,GAAG,IAAI;IAkBpC,gBAAgB;IAChB,WAAW,IAAI;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,OAAO,CAAC;KACtB;CAQF"}
@@ -21,7 +21,7 @@
21
21
  */
22
22
  export interface InAppCampaign {
23
23
  id: string;
24
- type: 'modal' | 'banner' | 'tooltip' | 'full_screen' | 'half_interstitial' | 'alert' | 'pip';
24
+ type: 'modal' | 'banner' | 'tooltip' | 'full_screen' | 'half_interstitial' | 'alert' | 'pip' | 'carousel_cards' | 'sticky_bar' | 'progress_bar' | 'coachmark_tour' | 'product_recommendation';
25
25
  sub_type?: string;
26
26
  title: string;
27
27
  body: string;
@@ -51,6 +51,7 @@ export interface AegisInAppConfig {
51
51
  userId?: string;
52
52
  contactId?: string;
53
53
  organizationId?: string;
54
+ propertyId?: string;
54
55
  debugMode?: boolean;
55
56
  enableSSE?: boolean;
56
57
  }
@@ -60,6 +61,7 @@ export declare class AegisInAppManager {
60
61
  private userId?;
61
62
  private contactId?;
62
63
  private organizationId?;
64
+ private propertyId?;
63
65
  private debugMode;
64
66
  private enableSSE;
65
67
  private campaigns;
@@ -82,7 +84,32 @@ export declare class AegisInAppManager {
82
84
  private processABAssignments;
83
85
  private getVariantId;
84
86
  private tryDisplayNextCampaign;
87
+ /**
88
+ * Evaluate the currently armed campaigns against a client-side event
89
+ * and render any that match their `client_trigger`.
90
+ *
91
+ * Called by the host app (e.g., the EcommerceTracker on product_viewed),
92
+ * or by future TriggerEngine bridges. Safe to call repeatedly for the
93
+ * same event — dedup happens via `displayedCampaigns`.
94
+ *
95
+ * Supported trigger types (align with the cell-plane server-side
96
+ * `display_rules.trigger_type`):
97
+ * - `custom_event` : fire when eventName matches config.event
98
+ * - `product_match` : fire on `product_viewed` when eventData.product_id
99
+ * matches config.product_id (string or string[])
100
+ * - `delay` : client-side setTimeout — evaluated at armeng
101
+ * time (kicked off from `displayCampaign`), not here.
102
+ */
103
+ onClientEvent(eventName: string, eventData?: Record<string, unknown>): void;
104
+ private matchesClientTrigger;
85
105
  private displayCampaign;
106
+ /**
107
+ * Build the shared context passed into the preload-first renderers.
108
+ * Matches the interface in `./renderers/types.ts`. Kept as a private
109
+ * method (rather than inlined at each call-site) so future renderer
110
+ * additions stay consistent and easy to audit.
111
+ */
112
+ private buildRenderContext;
86
113
  /**
87
114
  * Renders interactive sub-type campaigns (spin wheel, NPS, quiz, etc.)
88
115
  * using DOM-safe rendering. These sub-types use the campaign's
@@ -1 +1 @@
1
- {"version":3,"file":"AegisInAppManager.d.ts","sourceRoot":"","sources":["../../src/inapp/AegisInAppManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AegisInAppManager.d.ts","sourceRoot":"","sources":["../../src/inapp/AegisInAppManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * CarouselCards renderer — a swipeable / autoplaying sequence of product
3
+ * cards. Used for post-purchase upsells, cross-sell, and "recently viewed"
4
+ * surfaces. The entire card list is pre-bundled — no network call on
5
+ * trigger; slide advance is pure client state.
6
+ *
7
+ * Data shape (interactive_config, populated at campaign create time and
8
+ * validated server-side):
9
+ * cards: Array<{ image_url?, title, body?, cta_text?, cta_url? }>
10
+ * autoplay_ms?: number // 0 = manual advance only
11
+ * loop?: boolean // wrap to card 0 on last-next
12
+ */
13
+ import type { RenderContext } from './types';
14
+ export declare function renderCarouselCards(ctx: RenderContext): void;
15
+ //# sourceMappingURL=carousel-cards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carousel-cards.d.ts","sourceRoot":"","sources":["../../../src/inapp/renderers/carousel-cards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAY7C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CA4L5D"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * CoachmarkTour renderer — a guided, multi-step walkthrough anchored to
3
+ * DOM elements via CSS selectors. One tooltip appears at a time with
4
+ * next/back navigation; completion + skip are persisted per contact via
5
+ * localStorage under the `resume_key`, so an abandoned tour resumes on
6
+ * the next visit instead of restarting or re-bothering the user.
7
+ *
8
+ * interactive_config:
9
+ * steps: Array<{
10
+ * anchor_web?: string, // CSS selector for THIS platform
11
+ * anchor_android?: string, // ignored on web
12
+ * anchor_ios?: string, // ignored on web
13
+ * title: string,
14
+ * body: string,
15
+ * placement?: 'top' | 'bottom' | 'left' | 'right',
16
+ * cta_text?: string,
17
+ * }>
18
+ * resume_key: string,
19
+ * allow_skip?: boolean,
20
+ * show_progress_dots?: boolean,
21
+ */
22
+ import type { RenderContext } from './types';
23
+ export declare function renderCoachmarkTour(ctx: RenderContext): void;
24
+ //# sourceMappingURL=coachmark-tour.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coachmark-tour.d.ts","sourceRoot":"","sources":["../../../src/inapp/renderers/coachmark-tour.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AA6C7C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CA0M5D"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Barrel for the 5 preload-first renderers. These are pure DOM-mutation
3
+ * functions that operate on a shared `RenderContext` — they never do
4
+ * network I/O at render time, consistent with the preload-first contract.
5
+ */
6
+ export type { RenderContext, Renderer } from './types';
7
+ export { renderCarouselCards } from './carousel-cards';
8
+ export { renderStickyBar } from './sticky-bar';
9
+ export { renderProgressBar } from './progress-bar';
10
+ export { renderCoachmarkTour } from './coachmark-tour';
11
+ export { renderProductRecommendation } from './product-recommendation';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/inapp/renderers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * ProductRecommendation renderer — personalized product grid/row rendered
3
+ * from `interactive_config.cards[]` that the cell-plane populated at
4
+ * bundle-assembly time. The SDK never calls a product-API at render
5
+ * time — the preload contract is that the recommended products are
6
+ * already in the bundle.
7
+ *
8
+ * The layout is narrower than the generic carousel because product recs
9
+ * should feel like a first-class product grid, not a marketing slider.
10
+ * Three layouts: grid (2-col / 3-col responsive), row (horizontal-scroll),
11
+ * carousel (same as carousel_cards but different framing copy).
12
+ *
13
+ * interactive_config:
14
+ * rec_source?: 'viewed' | 'abandoned' | 'cross_sell' | 'trending' | 'personalized'
15
+ * (metadata only — the actual product list is in `cards[]`)
16
+ * rec_count?: number (display hint; rendering is driven by cards.length)
17
+ * rec_layout?: 'grid' | 'row' | 'carousel' default 'grid'
18
+ * rec_cta_text?: string default 'Shop now'
19
+ * cards: Array<{ image_url?, title?, body?, cta_url?, metadata? }>
20
+ */
21
+ import type { RenderContext } from './types';
22
+ export declare function renderProductRecommendation(ctx: RenderContext): void;
23
+ //# sourceMappingURL=product-recommendation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-recommendation.d.ts","sourceRoot":"","sources":["../../../src/inapp/renderers/product-recommendation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAa7C,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAyKpE"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * ProgressBar renderer — a persistent bar that shows the user's progress
3
+ * toward a reward threshold (free shipping, loyalty tier, referral bonus).
4
+ *
5
+ * Two sources of the current value:
6
+ * 'client' — cheap: read from window.Shopify / WooCommerce / Magento
7
+ * cart globals. Untrusted; fine for visual-only hints.
8
+ * 'sse' — trusted: cell-plane pushes current_value via SSE to the
9
+ * already-shipped realtime server. For cart-gated rewards
10
+ * (must agree with server-side checkout guard), prefer SSE.
11
+ *
12
+ * For Phase 1 we implement CLIENT mode end-to-end. SSE mode reads
13
+ * `window.__aegisProgressSSE[campaign.id]` if populated by a parent app
14
+ * — higher-level integration (the SSE bridge) can push values there.
15
+ *
16
+ * interactive_config:
17
+ * progress_goal_type: 'cart_total' | 'items_in_cart' | 'loyalty_points' | 'referrals'
18
+ * progress_threshold: number
19
+ * progress_reward_text?: string
20
+ * progress_source?: 'client' | 'sse' default 'client'
21
+ */
22
+ import type { RenderContext } from './types';
23
+ export declare function renderProgressBar(ctx: RenderContext): void;
24
+ //# sourceMappingURL=progress-bar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-bar.d.ts","sourceRoot":"","sources":["../../../src/inapp/renderers/progress-bar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAI7C,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAgJ1D"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * StickyBar renderer — a pinned notification strip at the top or bottom
3
+ * of the viewport. Used for free-shipping hints, flash-sale banners,
4
+ * cart-reminder strips. Dismissible, optionally auto-hiding.
5
+ *
6
+ * interactive_config:
7
+ * sticky_position: 'top' | 'bottom' (required)
8
+ * sticky_bg_color?: string
9
+ * sticky_dismissible?: boolean default true
10
+ * sticky_auto_hide_ms?: number 0 = never
11
+ */
12
+ import type { RenderContext } from './types';
13
+ export declare function renderStickyBar(ctx: RenderContext): void;
14
+ //# sourceMappingURL=sticky-bar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sticky-bar.d.ts","sourceRoot":"","sources":["../../../src/inapp/renderers/sticky-bar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAO7C,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CA2GxD"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Preload-first renderer types — the 5 display types added in Phase 0
3
+ * of the In-App Messages Expansion Plan (carousel_cards, sticky_bar,
4
+ * progress_bar, coachmark_tour, product_recommendation).
5
+ *
6
+ * Each renderer is a pure function over a `RenderContext` so that the
7
+ * main `AegisInAppManager` class does not grow unbounded. Render paths
8
+ * never do network I/O — everything they need is already in the
9
+ * campaign payload from the prefetch bundle.
10
+ */
11
+ import type { InAppCampaign } from '../AegisInAppManager';
12
+ export interface RenderContext {
13
+ campaign: InAppCampaign;
14
+ /** Track impression/click/dismiss via navigator.sendBeacon-capable writer. */
15
+ trackEvent: (campaignId: string, eventType: 'impression' | 'clicked' | 'dismissed') => void;
16
+ /** Null-safe URL hardener — rejects javascript:/data: */
17
+ sanitizeUrl: (url: string) => string | null;
18
+ /** Only accept #hex / rgb() / rgba() / named tokens — everything else returns the default. */
19
+ sanitizeColor: (color: string) => string;
20
+ /** Debug logger — forwarded to the manager's logger. */
21
+ log: (msg: string, level?: 'log' | 'warn' | 'error') => void;
22
+ /** Lazily inject the shared keyframes. */
23
+ addAnimationStyles: () => void;
24
+ }
25
+ /** Renderer signature — side-effectful DOM mutation, no return. */
26
+ export type Renderer = (ctx: RenderContext) => void;
27
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/inapp/renderers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,aAAa,CAAC;IACxB,8EAA8E;IAC9E,UAAU,EAAE,CACV,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,YAAY,GAAG,SAAS,GAAG,WAAW,KAC9C,IAAI,CAAC;IACV,yDAAyD;IACzD,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC5C,8FAA8F;IAC9F,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,wDAAwD;IACxD,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,KAAK,IAAI,CAAC;IAC7D,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,IAAI,CAAC;CAChC;AAED,mEAAmE;AACnE,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC"}