@active-reach/web-sdk 1.43.0 → 1.43.2

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 +169 -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 +15478 -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
@@ -0,0 +1,81 @@
1
+ /**
2
+ * E-Commerce event types following the Active Reach Intelligence spec.
3
+ * Compatible with Segment/GA4 e-commerce event schemas.
4
+ */
5
+ export interface EcommerceProduct {
6
+ product_id: string;
7
+ sku?: string;
8
+ name: string;
9
+ price: number;
10
+ quantity?: number;
11
+ currency?: string;
12
+ category?: string;
13
+ brand?: string;
14
+ variant_id?: string;
15
+ variant_label?: string;
16
+ image_url?: string;
17
+ url?: string;
18
+ position?: number;
19
+ }
20
+ export interface EcommerceCart {
21
+ cart_id?: string;
22
+ value: number;
23
+ currency?: string;
24
+ products: EcommerceProduct[];
25
+ }
26
+ export interface EcommerceCheckout {
27
+ checkout_id?: string;
28
+ value: number;
29
+ currency?: string;
30
+ products: EcommerceProduct[];
31
+ coupon?: string;
32
+ shipping?: number;
33
+ tax?: number;
34
+ }
35
+ export interface EcommerceOrder {
36
+ order_id: string;
37
+ value: number;
38
+ revenue?: number;
39
+ currency?: string;
40
+ products: EcommerceProduct[];
41
+ coupon?: string;
42
+ shipping?: number;
43
+ tax?: number;
44
+ discount?: number;
45
+ payment_method?: string;
46
+ }
47
+ export interface EcommerceCoupon {
48
+ coupon_id?: string;
49
+ coupon_code: string;
50
+ discount_value?: number;
51
+ discount_type?: 'percentage' | 'fixed';
52
+ order_id?: string;
53
+ cart_id?: string;
54
+ }
55
+ export interface EcommerceSearch {
56
+ query: string;
57
+ results_count?: number;
58
+ filters?: Record<string, string | string[]>;
59
+ }
60
+ export interface EcommerceProductList {
61
+ list_id?: string;
62
+ list_name?: string;
63
+ products: EcommerceProduct[];
64
+ category?: string;
65
+ }
66
+ export interface EcommerceWishlist {
67
+ wishlist_id?: string;
68
+ wishlist_name?: string;
69
+ product: EcommerceProduct;
70
+ }
71
+ export interface EcommerceWaitlist {
72
+ product: EcommerceProduct;
73
+ channels?: Array<'whatsapp' | 'sms' | 'email' | 'push'>;
74
+ }
75
+ export interface EcommercePromotion {
76
+ promotion_id?: string;
77
+ name: string;
78
+ creative?: string;
79
+ position?: string;
80
+ }
81
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ecommerce/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
@@ -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,8 @@
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
+ export { TraitGovernor } from './trait-governor';
7
+ export type { TraitVerdict, TraitDrop, TraitResult } from './trait-governor';
8
+ //# 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;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,kBAAkB,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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * TraitGovernor — client-side guards for trait writes (P10.5).
3
+ *
4
+ * Runs the same 5 ingestion guards client-side that the cell-plane backend
5
+ * runs at the trait-write chokepoint (`record_attribute_keys`), so the SDK
6
+ * can warn developers about problematic keys/values BEFORE network send.
7
+ *
8
+ * Why two chokepoints:
9
+ * - **Backend** (`record_attribute_keys` → DLQ): authoritative; rejects
10
+ * payloads that bypass the SDK (direct HTTP, CSV import, integration
11
+ * workers). Operators see rejections via /Validation tab.
12
+ * - **SDK** (this file): developer-facing; warns in console.warn at dev
13
+ * time so the issue is caught BEFORE the bad data hits production. We
14
+ * normalize what we can (key casing, value truncation, date format)
15
+ * and warn-then-drop what we can't (reserved prefixes).
16
+ *
17
+ * "First-3 per verdict per session" — we warn at most 3 times for each
18
+ * verdict per `(workspace_id, verdict)` key in any given page load. After
19
+ * that, silent — the developer got the message; further warnings would
20
+ * just spam the console and obscure other issues.
21
+ *
22
+ * Canonical contract: the verdict codes here MUST match
23
+ * `data_governance.ingestion_guards.GuardResult.verdict` codes + the
24
+ * `ingestion_dlq.verdict` DB CHECK + the FE `IngestionDLQVerdict` union.
25
+ * Real-env smoke asserts BE ↔ DB drift; TS narrowing catches FE drift;
26
+ * this file completes the four-surface drift protection.
27
+ */
28
+ export type TraitVerdict = 'bad_key_format' | 'value_too_long' | 'bad_date_format' | 'name_too_long' | 'reserved_prefix';
29
+ export interface TraitDrop {
30
+ /** Original key as the developer wrote it. */
31
+ originalKey: string;
32
+ /** What the guard decided. */
33
+ verdict: TraitVerdict;
34
+ /** Human-readable reason — same text we'd log to ingestion_dlq.reason. */
35
+ reason: string;
36
+ }
37
+ export interface TraitResult {
38
+ /**
39
+ * Sanitized traits to actually send. Reserved-prefix keys are absent;
40
+ * camelCase keys are rewritten to snake_case; long values truncated;
41
+ * ISO dates → epoch ms.
42
+ */
43
+ sanitized: Record<string, unknown>;
44
+ /** Keys that were dropped or modified (one row per change). */
45
+ drops: TraitDrop[];
46
+ }
47
+ export declare class TraitGovernor {
48
+ /** Cap warnings at 3 per (workspace_id, verdict) per session. */
49
+ private static readonly WARN_CAP;
50
+ /** workspace_id || '__no_workspace__' → verdict → count. */
51
+ private warnCounts;
52
+ /**
53
+ * Apply all guards to a traits object. Returns the sanitized payload
54
+ * to send + a list of drops/modifications.
55
+ *
56
+ * Pass `workspace_id` so warning rate-limits scope per workspace; an
57
+ * agency user switching workspaces won't have their warning budget
58
+ * consumed cross-workspace.
59
+ */
60
+ process(traits: Record<string, unknown> | null | undefined, workspace_id?: string | null): TraitResult;
61
+ private maybeWarn;
62
+ }
63
+ //# sourceMappingURL=trait-governor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trait-governor.d.ts","sourceRoot":"","sources":["../../src/governance/trait-governor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,MAAM,YAAY,GACpB,gBAAgB,GAChB,gBAAgB,GAChB,iBAAiB,GACjB,eAAe,GACf,iBAAiB,CAAC;AAEtB,MAAM,WAAW,SAAS;IACxB,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,OAAO,EAAE,YAAY,CAAC;IACtB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,+DAA+D;IAC/D,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AA+FD,qBAAa,aAAa;IACxB,iEAAiE;IACjE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAK;IACrC,4DAA4D;IAC5D,OAAO,CAAC,UAAU,CAAqD;IAEvE;;;;;;;OAOG;IACH,OAAO,CACL,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAClD,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAC3B,WAAW;IA+Fd,OAAO,CAAC,SAAS;CAgBlB"}