@active-reach/web-sdk 1.13.0 → 1.14.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.
- package/dist/aegis.min.js +1 -1
- package/dist/aegis.min.js.map +1 -1
- package/dist/{analytics-Mh4H4ekQ.mjs → analytics-DGt-CSgi.mjs} +158 -7
- package/dist/analytics-DGt-CSgi.mjs.map +1 -0
- package/dist/core/analytics.d.ts +81 -0
- package/dist/core/analytics.d.ts.map +1 -1
- package/dist/core/bootstrap.d.ts +9 -0
- package/dist/core/bootstrap.d.ts.map +1 -1
- package/dist/ecommerce/index.d.ts +7 -2
- package/dist/ecommerce/index.d.ts.map +1 -1
- package/dist/ecommerce/types.d.ts +4 -0
- package/dist/ecommerce/types.d.ts.map +1 -1
- package/dist/inapp/AegisInAppManager.d.ts +11 -0
- package/dist/inapp/AegisInAppManager.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -6
- package/dist/index.js.map +1 -1
- package/dist/placements/AegisPlacementManager.d.ts +9 -0
- package/dist/placements/AegisPlacementManager.d.ts.map +1 -1
- package/dist/react.js +1 -1
- package/dist/runtime/AegisMessageRuntime.d.ts.map +1 -1
- package/dist/widgets/AegisWidgetManager.d.ts +9 -0
- package/dist/widgets/AegisWidgetManager.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/analytics-Mh4H4ekQ.mjs.map +0 -1
|
@@ -1764,6 +1764,24 @@ class EcommerceTracker {
|
|
|
1764
1764
|
variant_id: wishlist.product.variant_id
|
|
1765
1765
|
});
|
|
1766
1766
|
}
|
|
1767
|
+
// -- Back-in-stock waitlist --
|
|
1768
|
+
//
|
|
1769
|
+
// Server-side substrate: contact_events row keyed on
|
|
1770
|
+
// (organization_id, contact_id, event_name='product_waitlisted',
|
|
1771
|
+
// event_properties['product_id']). Resolved by
|
|
1772
|
+
// product_event_trigger_service._get_waitlisted_contacts and fanned out via
|
|
1773
|
+
// catalog.back_in_stock journey trigger when stock_event_handler_worker
|
|
1774
|
+
// detects the SKU flipping back into stock.
|
|
1775
|
+
productWaitlisted(waitlist) {
|
|
1776
|
+
this.aegis.track("product_waitlisted", {
|
|
1777
|
+
product_id: waitlist.product.product_id,
|
|
1778
|
+
sku: waitlist.product.sku ?? waitlist.product.product_id,
|
|
1779
|
+
variant_id: waitlist.product.variant_id,
|
|
1780
|
+
name: waitlist.product.name,
|
|
1781
|
+
price: waitlist.product.price,
|
|
1782
|
+
channels: waitlist.channels
|
|
1783
|
+
});
|
|
1784
|
+
}
|
|
1767
1785
|
// -- Promotions --
|
|
1768
1786
|
promotionViewed(promo) {
|
|
1769
1787
|
this.aegis.track("promotion_viewed", { ...promo });
|
|
@@ -2362,6 +2380,8 @@ class Aegis {
|
|
|
2362
2380
|
this._originalPushState = null;
|
|
2363
2381
|
this._originalReplaceState = null;
|
|
2364
2382
|
this._lastEventIds = /* @__PURE__ */ new Map();
|
|
2383
|
+
this._workspaceCodes = /* @__PURE__ */ new Set();
|
|
2384
|
+
this._runtimeWorkspace = null;
|
|
2365
2385
|
}
|
|
2366
2386
|
async init(writeKey, config) {
|
|
2367
2387
|
if (this.initPromise) {
|
|
@@ -2543,6 +2563,137 @@ class Aegis {
|
|
|
2543
2563
|
removePlugin(name) {
|
|
2544
2564
|
this.plugins.unregister(name);
|
|
2545
2565
|
}
|
|
2566
|
+
/**
|
|
2567
|
+
* Plugin-handshake P1 — ingest the workspace_code allowlist from the
|
|
2568
|
+
* bootstrap response. Pass `result.workspaceCodes` from `bootstrap()`
|
|
2569
|
+
* here so the SDK can do path-segment workspace detection on
|
|
2570
|
+
* customer-facing pages like `/south/rewards`, `/ghatkopar/feedback`.
|
|
2571
|
+
*
|
|
2572
|
+
* Empty array is the right answer for single-outlet tenants — SDK
|
|
2573
|
+
* will skip the path cascade and fall through to query param /
|
|
2574
|
+
* setWorkspace() / gateway origin lookup.
|
|
2575
|
+
*
|
|
2576
|
+
* Safe to call before init() — the set is consulted at event-fire time.
|
|
2577
|
+
*/
|
|
2578
|
+
ingestWorkspaceCodes(codes) {
|
|
2579
|
+
this._workspaceCodes = new Set(
|
|
2580
|
+
(codes ?? []).filter((c) => typeof c === "string" && c.length > 0)
|
|
2581
|
+
);
|
|
2582
|
+
logger.debug("Workspace codes ingested", { count: this._workspaceCodes.size });
|
|
2583
|
+
}
|
|
2584
|
+
/**
|
|
2585
|
+
* Plugin-handshake P1 (Track E) — explicitly set the workspace for
|
|
2586
|
+
* subsequent events. Used by:
|
|
2587
|
+
* - SPAs where workspace context changes via in-app routing
|
|
2588
|
+
* - Mobile / RN apps that have no URL
|
|
2589
|
+
* - Custom integrations that resolve workspace from their own state
|
|
2590
|
+
*
|
|
2591
|
+
* Pass null to clear (or call clearWorkspace()).
|
|
2592
|
+
*
|
|
2593
|
+
* Persisted to sessionStorage so SPA reloads / page transitions on the
|
|
2594
|
+
* same outlet inherit it without re-calling.
|
|
2595
|
+
*/
|
|
2596
|
+
setWorkspace(codeOrId) {
|
|
2597
|
+
this._runtimeWorkspace = codeOrId;
|
|
2598
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
2599
|
+
try {
|
|
2600
|
+
if (codeOrId) {
|
|
2601
|
+
window.sessionStorage.setItem("aegis_runtime_ws", codeOrId);
|
|
2602
|
+
} else {
|
|
2603
|
+
window.sessionStorage.removeItem("aegis_runtime_ws");
|
|
2604
|
+
}
|
|
2605
|
+
} catch {
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2608
|
+
logger.debug("Runtime workspace set", { value: codeOrId });
|
|
2609
|
+
}
|
|
2610
|
+
/** Symmetric helper to clear the runtime workspace. */
|
|
2611
|
+
clearWorkspace() {
|
|
2612
|
+
this.setWorkspace(null);
|
|
2613
|
+
}
|
|
2614
|
+
/**
|
|
2615
|
+
* Inspect the URL's first path segment and return it if it's in the
|
|
2616
|
+
* org's workspace_code allowlist. Skips well-known non-workspace prefixes
|
|
2617
|
+
* (e.g. `b` for bill short codes; `s` is the storefront app slug).
|
|
2618
|
+
*
|
|
2619
|
+
* Returns undefined when:
|
|
2620
|
+
* - window is undefined (SSR / Node)
|
|
2621
|
+
* - path is empty / root
|
|
2622
|
+
* - first segment isn't in `_workspaceCodes` (e.g. /products, /cart)
|
|
2623
|
+
*
|
|
2624
|
+
* The returned value is a workspace CODE (slug like "south"), not a
|
|
2625
|
+
* UUID. The gateway normalizes code → UUID server-side via
|
|
2626
|
+
* workspace_subaccounts lookup with Redis cache.
|
|
2627
|
+
*/
|
|
2628
|
+
getPathWorkspaceCode() {
|
|
2629
|
+
if (typeof window === "undefined") return void 0;
|
|
2630
|
+
if (this._workspaceCodes.size === 0) return void 0;
|
|
2631
|
+
try {
|
|
2632
|
+
const segments = window.location.pathname.split("/").filter(Boolean);
|
|
2633
|
+
if (segments.length === 0) return void 0;
|
|
2634
|
+
const first = segments[0].toLowerCase();
|
|
2635
|
+
return this._workspaceCodes.has(first) ? first : void 0;
|
|
2636
|
+
} catch {
|
|
2637
|
+
return void 0;
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
/**
|
|
2641
|
+
* Resolve the effective `workspace_id` for the next event.
|
|
2642
|
+
*
|
|
2643
|
+
* Cascade (highest precedence first):
|
|
2644
|
+
* 1. `this.config.workspace_id` — explicit operator config (headless
|
|
2645
|
+
* SDK usage, server-rendered apps, native shells).
|
|
2646
|
+
* 2. `?ws=` query param on the current URL — the P3 storefront URL
|
|
2647
|
+
* contract. The outlet picker writes this via `router.replace`.
|
|
2648
|
+
* 3. URL path segment (P1 Track A) — `/south/rewards` → "south" when
|
|
2649
|
+
* "south" is in the org's workspace_code allowlist.
|
|
2650
|
+
* 4. `aegis.setWorkspace()` runtime override (P1 Track E) — SPAs +
|
|
2651
|
+
* mobile + custom integrations.
|
|
2652
|
+
* 5. sessionStorage `aegis_runtime_ws` — persists setWorkspace across
|
|
2653
|
+
* reloads/SPA route changes.
|
|
2654
|
+
* 6. `undefined` — gateway falls back to `resolveByOrigin` lookup
|
|
2655
|
+
* against the property's allowed_origins.
|
|
2656
|
+
*
|
|
2657
|
+
* The returned value can be EITHER a UUID (from config / ?ws=) or a
|
|
2658
|
+
* workspace CODE slug (from path / setWorkspace). The gateway
|
|
2659
|
+
* normalizes slug → UUID server-side; analytics layer never needs to
|
|
2660
|
+
* worry about the difference.
|
|
2661
|
+
*
|
|
2662
|
+
* See docs/architecture/MULTI_OUTLET_URL_STRATEGY.md §2.3 and
|
|
2663
|
+
* docs/architecture/PLUGIN_HANDSHAKE_AUTOMATION.md §2.
|
|
2664
|
+
*/
|
|
2665
|
+
/**
|
|
2666
|
+
* Public so peer SDK surfaces (AegisMessageRuntime / AegisInAppManager /
|
|
2667
|
+
* AegisPlacementManager / AegisWidgetManager) can plumb the same
|
|
2668
|
+
* resolved workspace into their own gateway POSTs. Each manager calls
|
|
2669
|
+
* the gateway on its own endpoint (`/v1/in_app/events`,
|
|
2670
|
+
* `/v1/placements/track`, `/v1/widgets/track-event`); without this,
|
|
2671
|
+
* those events arrive at event-ingress with no workspace_id stamped
|
|
2672
|
+
* → impressions/clicks fall back to the org's primary workspace and
|
|
2673
|
+
* cross-outlet attribution breaks.
|
|
2674
|
+
*/
|
|
2675
|
+
getEffectiveWorkspaceId() {
|
|
2676
|
+
var _a;
|
|
2677
|
+
const configured = (_a = this.config) == null ? void 0 : _a.workspace_id;
|
|
2678
|
+
if (configured) return configured;
|
|
2679
|
+
if (typeof window === "undefined") return void 0;
|
|
2680
|
+
try {
|
|
2681
|
+
const ws = new URLSearchParams(window.location.search).get("ws");
|
|
2682
|
+
if (ws && ws.length > 0) return ws;
|
|
2683
|
+
} catch {
|
|
2684
|
+
}
|
|
2685
|
+
const pathWs = this.getPathWorkspaceCode();
|
|
2686
|
+
if (pathWs) return pathWs;
|
|
2687
|
+
if (this._runtimeWorkspace) return this._runtimeWorkspace;
|
|
2688
|
+
try {
|
|
2689
|
+
if (window.sessionStorage) {
|
|
2690
|
+
const cached = window.sessionStorage.getItem("aegis_runtime_ws");
|
|
2691
|
+
if (cached && cached.length > 0) return cached;
|
|
2692
|
+
}
|
|
2693
|
+
} catch {
|
|
2694
|
+
}
|
|
2695
|
+
return void 0;
|
|
2696
|
+
}
|
|
2546
2697
|
track(eventName, properties) {
|
|
2547
2698
|
if (!this.assertInitialized()) return;
|
|
2548
2699
|
const messageId = generateMessageId();
|
|
@@ -2555,7 +2706,7 @@ class Aegis {
|
|
|
2555
2706
|
anonymousId: this.identity.getAnonymousId(),
|
|
2556
2707
|
userId: this.identity.getUserId() || void 0,
|
|
2557
2708
|
sessionId: this.session.getSessionId(),
|
|
2558
|
-
workspace_id: this.
|
|
2709
|
+
workspace_id: this.getEffectiveWorkspaceId(),
|
|
2559
2710
|
context: buildContext(this.config, this.session)
|
|
2560
2711
|
};
|
|
2561
2712
|
this._lastEventIds.set(eventName, messageId);
|
|
@@ -2563,7 +2714,7 @@ class Aegis {
|
|
|
2563
2714
|
}
|
|
2564
2715
|
identify(userId, traits) {
|
|
2565
2716
|
if (!this.assertInitialized()) return;
|
|
2566
|
-
const wsForGovernor = this.
|
|
2717
|
+
const wsForGovernor = this.getEffectiveWorkspaceId() || null;
|
|
2567
2718
|
const { sanitized: governedTraits } = this.traitGovernor.process(traits, wsForGovernor);
|
|
2568
2719
|
this.identity.setUserId(userId, governedTraits);
|
|
2569
2720
|
const event = {
|
|
@@ -2574,7 +2725,7 @@ class Aegis {
|
|
|
2574
2725
|
anonymousId: this.identity.getAnonymousId(),
|
|
2575
2726
|
userId,
|
|
2576
2727
|
sessionId: this.session.getSessionId(),
|
|
2577
|
-
workspace_id: this.
|
|
2728
|
+
workspace_id: this.getEffectiveWorkspaceId(),
|
|
2578
2729
|
context: buildContext(this.config, this.session)
|
|
2579
2730
|
};
|
|
2580
2731
|
this.captureEvent(event);
|
|
@@ -2590,14 +2741,14 @@ class Aegis {
|
|
|
2590
2741
|
anonymousId: this.identity.getAnonymousId(),
|
|
2591
2742
|
userId: this.identity.getUserId() || void 0,
|
|
2592
2743
|
sessionId: this.session.getSessionId(),
|
|
2593
|
-
workspace_id: this.
|
|
2744
|
+
workspace_id: this.getEffectiveWorkspaceId(),
|
|
2594
2745
|
context: buildContext(this.config, this.session)
|
|
2595
2746
|
};
|
|
2596
2747
|
this.captureEvent(event);
|
|
2597
2748
|
}
|
|
2598
2749
|
group(groupId, traits) {
|
|
2599
2750
|
if (!this.assertInitialized()) return;
|
|
2600
|
-
const wsForGovernor = this.
|
|
2751
|
+
const wsForGovernor = this.getEffectiveWorkspaceId() || null;
|
|
2601
2752
|
const { sanitized: governedTraits } = this.traitGovernor.process(traits, wsForGovernor);
|
|
2602
2753
|
const event = {
|
|
2603
2754
|
type: "group",
|
|
@@ -2647,7 +2798,7 @@ class Aegis {
|
|
|
2647
2798
|
anonymousId: this.identity.getAnonymousId(),
|
|
2648
2799
|
userId: this.identity.getUserId() || void 0,
|
|
2649
2800
|
sessionId: this.session.getSessionId(),
|
|
2650
|
-
workspace_id: this.
|
|
2801
|
+
workspace_id: this.getEffectiveWorkspaceId(),
|
|
2651
2802
|
context: buildContext(this.config, this.session)
|
|
2652
2803
|
};
|
|
2653
2804
|
this.captureEvent(event);
|
|
@@ -2959,4 +3110,4 @@ export {
|
|
|
2959
3110
|
logger as l,
|
|
2960
3111
|
murmurhash3_x86_32 as m
|
|
2961
3112
|
};
|
|
2962
|
-
//# sourceMappingURL=analytics-
|
|
3113
|
+
//# sourceMappingURL=analytics-DGt-CSgi.mjs.map
|