@active-reach/web-sdk 1.43.1 → 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.
- package/dist/aegis-push.min.js +2 -0
- package/dist/aegis-push.min.js.map +1 -0
- package/dist/aegis-sw.js +1 -0
- package/dist/aegis.min.js +2 -0
- package/dist/aegis.min.js.map +1 -0
- package/dist/analytics-C-Go3Pm5.mjs +3509 -0
- package/dist/analytics-C-Go3Pm5.mjs.map +1 -0
- package/dist/cdn.d.ts +26 -0
- package/dist/cdn.d.ts.map +1 -0
- package/dist/chat/AegisChat.d.ts +169 -0
- package/dist/chat/AegisChat.d.ts.map +1 -0
- package/dist/chat/index.d.ts +3 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/core/analytics.d.ts +320 -0
- package/dist/core/analytics.d.ts.map +1 -0
- package/dist/core/bootstrap.d.ts +96 -0
- package/dist/core/bootstrap.d.ts.map +1 -0
- package/dist/core/prefetch-bundle-client.d.ts +175 -0
- package/dist/core/prefetch-bundle-client.d.ts.map +1 -0
- package/dist/core/queue.d.ts +35 -0
- package/dist/core/queue.d.ts.map +1 -0
- package/dist/core/rate-limiter.d.ts +45 -0
- package/dist/core/rate-limiter.d.ts.map +1 -0
- package/dist/core/sdk-config-poller.d.ts +59 -0
- package/dist/core/sdk-config-poller.d.ts.map +1 -0
- package/dist/core/session.d.ts +52 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/transport.d.ts +50 -0
- package/dist/core/transport.d.ts.map +1 -0
- package/dist/core/user-namespace.d.ts +48 -0
- package/dist/core/user-namespace.d.ts.map +1 -0
- package/dist/ecommerce/index.d.ts +94 -0
- package/dist/ecommerce/index.d.ts.map +1 -0
- package/dist/ecommerce/types.d.ts +81 -0
- package/dist/ecommerce/types.d.ts.map +1 -0
- package/dist/governance/bloom-filter.d.ts +47 -0
- package/dist/governance/bloom-filter.d.ts.map +1 -0
- package/dist/governance/index.d.ts +8 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/murmur3.d.ts +43 -0
- package/dist/governance/murmur3.d.ts.map +1 -0
- package/dist/governance/name-governor.d.ts +98 -0
- package/dist/governance/name-governor.d.ts.map +1 -0
- package/dist/governance/trait-governor.d.ts +63 -0
- package/dist/governance/trait-governor.d.ts.map +1 -0
- package/dist/inapp/AegisInAppManager.d.ts +894 -0
- package/dist/inapp/AegisInAppManager.d.ts.map +1 -0
- package/dist/inapp/actions.d.ts +91 -0
- package/dist/inapp/actions.d.ts.map +1 -0
- package/dist/inapp/devicePairing.d.ts +70 -0
- package/dist/inapp/devicePairing.d.ts.map +1 -0
- package/dist/inapp/eval-throttle.d.ts +33 -0
- package/dist/inapp/eval-throttle.d.ts.map +1 -0
- package/dist/inapp/font.d.ts +16 -0
- package/dist/inapp/font.d.ts.map +1 -0
- package/dist/inapp/index.d.ts +8 -0
- package/dist/inapp/index.d.ts.map +1 -0
- package/dist/inapp/lucide-svg.d.ts +46 -0
- package/dist/inapp/lucide-svg.d.ts.map +1 -0
- package/dist/inapp/renderPreview.d.ts +40 -0
- package/dist/inapp/renderPreview.d.ts.map +1 -0
- package/dist/inapp/renderers/active-web-chat.d.ts +45 -0
- package/dist/inapp/renderers/active-web-chat.d.ts.map +1 -0
- package/dist/inapp/renderers/card-style.d.ts +31 -0
- package/dist/inapp/renderers/card-style.d.ts.map +1 -0
- package/dist/inapp/renderers/card-template.d.ts +233 -0
- package/dist/inapp/renderers/card-template.d.ts.map +1 -0
- package/dist/inapp/renderers/carousel-cards.d.ts +15 -0
- package/dist/inapp/renderers/carousel-cards.d.ts.map +1 -0
- package/dist/inapp/renderers/coachmark-tour.d.ts +24 -0
- package/dist/inapp/renderers/coachmark-tour.d.ts.map +1 -0
- package/dist/inapp/renderers/games.d.ts +27 -0
- package/dist/inapp/renderers/games.d.ts.map +1 -0
- package/dist/inapp/renderers/hero.d.ts +23 -0
- package/dist/inapp/renderers/hero.d.ts.map +1 -0
- package/dist/inapp/renderers/index.d.ts +22 -0
- package/dist/inapp/renderers/index.d.ts.map +1 -0
- package/dist/inapp/renderers/interactive-contract.d.ts +48 -0
- package/dist/inapp/renderers/interactive-contract.d.ts.map +1 -0
- package/dist/inapp/renderers/product-recommendation.d.ts +37 -0
- package/dist/inapp/renderers/product-recommendation.d.ts.map +1 -0
- package/dist/inapp/renderers/progress-bar.d.ts +38 -0
- package/dist/inapp/renderers/progress-bar.d.ts.map +1 -0
- package/dist/inapp/renderers/progress-core.d.ts +80 -0
- package/dist/inapp/renderers/progress-core.d.ts.map +1 -0
- package/dist/inapp/renderers/reviews.d.ts +38 -0
- package/dist/inapp/renderers/reviews.d.ts.map +1 -0
- package/dist/inapp/renderers/scratch-engine.d.ts +66 -0
- package/dist/inapp/renderers/scratch-engine.d.ts.map +1 -0
- package/dist/inapp/renderers/sticky-bar.d.ts +14 -0
- package/dist/inapp/renderers/sticky-bar.d.ts.map +1 -0
- package/dist/inapp/renderers/stories.d.ts +31 -0
- package/dist/inapp/renderers/stories.d.ts.map +1 -0
- package/dist/inapp/renderers/types.d.ts +152 -0
- package/dist/inapp/renderers/types.d.ts.map +1 -0
- package/dist/inapp/renderers/video.d.ts +20 -0
- package/dist/inapp/renderers/video.d.ts.map +1 -0
- package/dist/inbox/AegisInbox.d.ts +106 -0
- package/dist/inbox/AegisInbox.d.ts.map +1 -0
- package/dist/inbox/index.d.ts +3 -0
- package/dist/inbox/index.d.ts.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15478 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/react.d.ts +19 -0
- package/dist/integrations/react.d.ts.map +1 -0
- package/dist/loyalty/AegisLoyaltyManager.d.ts +120 -0
- package/dist/loyalty/AegisLoyaltyManager.d.ts.map +1 -0
- package/dist/loyalty/index.d.ts +3 -0
- package/dist/loyalty/index.d.ts.map +1 -0
- package/dist/plugins/registry.d.ts +13 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/push/AegisWebPush.d.ts +199 -0
- package/dist/push/AegisWebPush.d.ts.map +1 -0
- package/dist/push/AegisWebPush.js +542 -0
- package/dist/push/AegisWebPush.js.map +1 -0
- package/dist/push/cdn-push.d.ts +21 -0
- package/dist/push/cdn-push.d.ts.map +1 -0
- package/dist/react.js +70 -0
- package/dist/react.js.map +1 -0
- package/dist/runtime/AegisMessageRuntime.d.ts +276 -0
- package/dist/runtime/AegisMessageRuntime.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/snippet.min.js +1 -0
- package/dist/state/intent_ledger.d.ts +136 -0
- package/dist/state/intent_ledger.d.ts.map +1 -0
- package/dist/triggers/ContactScoresFetcher.d.ts +113 -0
- package/dist/triggers/ContactScoresFetcher.d.ts.map +1 -0
- package/dist/triggers/IntentRuleEvaluator.d.ts +213 -0
- package/dist/triggers/IntentRuleEvaluator.d.ts.map +1 -0
- package/dist/triggers/IntentSnapshotCollector.d.ts +83 -0
- package/dist/triggers/IntentSnapshotCollector.d.ts.map +1 -0
- package/dist/triggers/SelectorBinder.d.ts +118 -0
- package/dist/triggers/SelectorBinder.d.ts.map +1 -0
- package/dist/triggers/TriggerEngine.d.ts +296 -0
- package/dist/triggers/TriggerEngine.d.ts.map +1 -0
- package/dist/triggers/behaviouralTriggers.d.ts +44 -0
- package/dist/triggers/behaviouralTriggers.d.ts.map +1 -0
- package/dist/triggers/index.d.ts +11 -0
- package/dist/triggers/index.d.ts.map +1 -0
- package/dist/triggers/microIntentTriggers.d.ts +80 -0
- package/dist/triggers/microIntentTriggers.d.ts.map +1 -0
- package/dist/types/config.d.ts +77 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/events.d.ts +147 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/plugin.d.ts +21 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/type-safe-events.d.ts +14 -0
- package/dist/types/type-safe-events.d.ts.map +1 -0
- package/dist/utils/canonical-identity.d.ts +29 -0
- package/dist/utils/canonical-identity.d.ts.map +1 -0
- package/dist/utils/consent.d.ts +40 -0
- package/dist/utils/consent.d.ts.map +1 -0
- package/dist/utils/debounce.d.ts +3 -0
- package/dist/utils/debounce.d.ts.map +1 -0
- package/dist/utils/device.d.ts +6 -0
- package/dist/utils/device.d.ts.map +1 -0
- package/dist/utils/identity.d.ts +27 -0
- package/dist/utils/identity.d.ts.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +15 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/meta-cookies.d.ts +65 -0
- package/dist/utils/meta-cookies.d.ts.map +1 -0
- package/dist/utils/redact-url.d.ts +56 -0
- package/dist/utils/redact-url.d.ts.map +1 -0
- package/dist/utils/storage.d.ts +20 -0
- package/dist/utils/storage.d.ts.map +1 -0
- package/dist/utils/url-parser.d.ts +61 -0
- package/dist/utils/url-parser.d.ts.map +1 -0
- package/dist/utils/uuid.d.ts +4 -0
- package/dist/utils/uuid.d.ts.map +1 -0
- package/dist/utils/visitor.d.ts +43 -0
- package/dist/utils/visitor.d.ts.map +1 -0
- package/dist/widgets/AegisWidgetManager.d.ts +209 -0
- package/dist/widgets/AegisWidgetManager.d.ts.map +1 -0
- package/dist/widgets/index.d.ts +3 -0
- package/dist/widgets/index.d.ts.map +1 -0
- 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":"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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,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"}
|