@replohq/sdk 2.0.0 → 2.1.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.
@@ -8,6 +8,7 @@ import { NorthbeamSink } from "./sinks/northbeam-sink";
8
8
  import { PinterestSink } from "./sinks/pinterest-sink";
9
9
  import { RedditSink } from "./sinks/reddit-sink";
10
10
  import { ReploSink } from "./sinks/replo-sink";
11
+ import { SegmentSink } from "./sinks/segment-sink";
11
12
  import { SnapchatSink } from "./sinks/snapchat-sink";
12
13
  import { TikTokSink } from "./sinks/tiktok-sink";
13
14
  import { WindowSink } from "./sinks/window-sink";
@@ -21,11 +22,13 @@ const PROVIDER_SINK_FACTORIES = {
21
22
  Pinterest: () => new PinterestSink(),
22
23
  Reddit: () => new RedditSink(),
23
24
  Northbeam: () => new NorthbeamSink(),
24
- Converge: () => new ConvergeSink()
25
+ Converge: () => new ConvergeSink(),
26
+ Segment: () => new SegmentSink()
25
27
  };
26
28
  const SNIPPET_PROVIDER_SINK_FACTORIES = {
27
29
  [snippetScriptId("Elevar")]: () => new ElevarSink()
28
30
  };
31
+ const SHOPIFY_FUNNEL_GATE_EXEMPT_PROVIDERS = /* @__PURE__ */ new Set(["Segment"]);
29
32
  function findSinkFactory(script) {
30
33
  if (script.type === "X") {
31
34
  return () => {
@@ -66,9 +69,8 @@ function getAnalyticsSinks({
66
69
  requiredConsent: script.requiredConsent
67
70
  })) {
68
71
  const sink = factory();
69
- sinks.push(
70
- shopifyOwnsCheckout ? gateShopifyOwnedFunnelEvents(sink) : sink
71
- );
72
+ const gated = shopifyOwnsCheckout && !SHOPIFY_FUNNEL_GATE_EXEMPT_PROVIDERS.has(script.type);
73
+ sinks.push(gated ? gateShopifyOwnedFunnelEvents(sink) : sink);
72
74
  addedProviders.add(providerKey);
73
75
  }
74
76
  }
@@ -0,0 +1,86 @@
1
+ import type { AnalyticsProductLine, CartLineData, CartViewedData, CheckoutStartedData, CollectionViewedData, PurchasePayload } from "../analytics-sink";
2
+ export declare function mapSegmentProduct(line: AnalyticsProductLine, currency: string | undefined): {
3
+ name?: string | undefined;
4
+ variant?: string | undefined;
5
+ variant_id?: string | undefined;
6
+ sku?: string | undefined;
7
+ price?: number | undefined;
8
+ quantity?: number | undefined;
9
+ currency?: string | undefined;
10
+ product_id: string;
11
+ };
12
+ export declare function mapSegmentCartLine(line: CartLineData): {
13
+ name?: string | undefined;
14
+ variant?: string | undefined;
15
+ variant_id?: string | undefined;
16
+ sku?: string | undefined;
17
+ price?: number | undefined;
18
+ quantity?: number | undefined;
19
+ currency?: string | undefined;
20
+ product_id: string;
21
+ };
22
+ export declare function mapSegmentCartViewed(data: CartViewedData): {
23
+ currency?: string | undefined;
24
+ value: number;
25
+ products: {
26
+ name?: string | undefined;
27
+ variant?: string | undefined;
28
+ variant_id?: string | undefined;
29
+ sku?: string | undefined;
30
+ price?: number | undefined;
31
+ quantity?: number | undefined;
32
+ currency?: string | undefined;
33
+ product_id: string;
34
+ }[];
35
+ };
36
+ export declare function mapSegmentCheckoutStarted(data: CheckoutStartedData): {
37
+ currency?: string | undefined;
38
+ value: number;
39
+ total: number;
40
+ revenue: number;
41
+ products: {
42
+ name?: string | undefined;
43
+ variant?: string | undefined;
44
+ variant_id?: string | undefined;
45
+ sku?: string | undefined;
46
+ price?: number | undefined;
47
+ quantity?: number | undefined;
48
+ currency?: string | undefined;
49
+ product_id: string;
50
+ }[];
51
+ };
52
+ export declare function mapSegmentProductList(data: CollectionViewedData): {
53
+ category?: string | undefined;
54
+ list_id: string;
55
+ products: {
56
+ name?: string | undefined;
57
+ variant?: string | undefined;
58
+ variant_id?: string | undefined;
59
+ sku?: string | undefined;
60
+ price?: number | undefined;
61
+ quantity?: number | undefined;
62
+ currency?: string | undefined;
63
+ product_id: string;
64
+ }[];
65
+ };
66
+ export declare function mapSegmentOrder({ amount, currency, data }: PurchasePayload): {
67
+ tax?: number | undefined;
68
+ shipping?: number | undefined;
69
+ order_id?: string | undefined;
70
+ discount?: number | undefined;
71
+ coupon?: string | undefined;
72
+ value: number;
73
+ total: number;
74
+ revenue: number;
75
+ currency: string;
76
+ products: {
77
+ name?: string | undefined;
78
+ variant?: string | undefined;
79
+ variant_id?: string | undefined;
80
+ sku?: string | undefined;
81
+ price?: number | undefined;
82
+ quantity?: number | undefined;
83
+ currency?: string | undefined;
84
+ product_id: string;
85
+ }[];
86
+ };
@@ -0,0 +1,71 @@
1
+ import { filterUndefined } from "../../_vendor/replo-utils/lib/object.mjs";
2
+ import { legacyResourceId } from "../utils/analytics-products";
3
+ function mapSegmentProduct(line, currency) {
4
+ return {
5
+ product_id: legacyResourceId(line.productId),
6
+ ...filterUndefined({
7
+ name: line.productTitle,
8
+ variant: line.variantTitle || void 0,
9
+ variant_id: line.variantId ? legacyResourceId(line.variantId) : void 0,
10
+ sku: line.variantSku || void 0,
11
+ price: line.price,
12
+ quantity: line.quantity,
13
+ currency: line.currency ?? currency
14
+ })
15
+ };
16
+ }
17
+ function mapProducts(lines, currency) {
18
+ return lines.map((line) => mapSegmentProduct(line, currency));
19
+ }
20
+ function mapSegmentCartLine(line) {
21
+ return mapSegmentProduct(line, void 0);
22
+ }
23
+ function mapSegmentCartViewed(data) {
24
+ return {
25
+ value: data.subtotal,
26
+ products: mapProducts(data.lineItems, data.currency),
27
+ ...filterUndefined({ currency: data.currency })
28
+ };
29
+ }
30
+ function mapSegmentCheckoutStarted(data) {
31
+ return {
32
+ value: data.total,
33
+ total: data.total,
34
+ revenue: data.subtotal,
35
+ products: mapProducts(data.lineItems, data.currency),
36
+ ...filterUndefined({ currency: data.currency })
37
+ };
38
+ }
39
+ function mapSegmentProductList(data) {
40
+ return {
41
+ list_id: legacyResourceId(data.collectionId),
42
+ products: mapProducts(data.products, data.currency),
43
+ ...filterUndefined({ category: data.collectionTitle })
44
+ };
45
+ }
46
+ function mapSegmentOrder({ amount, currency, data }) {
47
+ const tax = data.totalTax ?? 0;
48
+ const shipping = data.totalShipping ?? 0;
49
+ return {
50
+ value: amount,
51
+ total: amount,
52
+ revenue: Math.round((amount - tax - shipping) * 100) / 100,
53
+ currency,
54
+ products: mapProducts(data.lineItems ?? [], currency),
55
+ ...filterUndefined({
56
+ tax: data.totalTax,
57
+ shipping: data.totalShipping,
58
+ order_id: data.orderId,
59
+ discount: data.totalDiscount,
60
+ coupon: data.discountCodes?.join(",")
61
+ })
62
+ };
63
+ }
64
+ export {
65
+ mapSegmentCartLine,
66
+ mapSegmentCartViewed,
67
+ mapSegmentCheckoutStarted,
68
+ mapSegmentOrder,
69
+ mapSegmentProduct,
70
+ mapSegmentProductList
71
+ };
@@ -0,0 +1,23 @@
1
+ import type { AnalyticsSink, CartLineEventPayload, CartViewedPayload, CheckoutStartedPayload, ClickPayload, CollectionViewedPayload, CustomEventPayload, LegacyCheckoutStartedPayload, ProductViewedPayload, PurchasePayload } from "../analytics-sink";
2
+ import type { PageMetadata } from "../utils/navigation-tracker";
3
+ /**
4
+ * Sends Replo's analytics events to Segment as V2 E-Commerce spec `track`
5
+ * events, so a tracking plan written against the spec ("Product Added",
6
+ * "Order Completed") is met without page-level code. The consent-gated
7
+ * snippet sends the landing pageview; this sink adds a `page` call for each
8
+ * in-site navigation.
9
+ */
10
+ export declare class SegmentSink implements AnalyticsSink {
11
+ private send;
12
+ private track;
13
+ customEvent({ event, properties }: CustomEventPayload): Promise<void>;
14
+ pageView(metadata?: PageMetadata): Promise<void>;
15
+ purchase(payload: PurchasePayload): Promise<void>;
16
+ click({ data }: ClickPayload): Promise<void>;
17
+ productViewed({ data }: ProductViewedPayload): Promise<void>;
18
+ addToCart({ data }: CartLineEventPayload): Promise<void>;
19
+ removeFromCart({ data }: CartLineEventPayload): Promise<void>;
20
+ viewCart({ data }: CartViewedPayload): Promise<void>;
21
+ startCheckout(payload: CheckoutStartedPayload | LegacyCheckoutStartedPayload): Promise<void>;
22
+ viewCollection({ data }: CollectionViewedPayload): Promise<void>;
23
+ }
@@ -0,0 +1,84 @@
1
+ import { toCheckoutStartedData } from "../legacy-checkout";
2
+ import { createAnalyticsQueue } from "../utils/analytics-utils";
3
+ import {
4
+ mapSegmentCartLine,
5
+ mapSegmentCartViewed,
6
+ mapSegmentCheckoutStarted,
7
+ mapSegmentOrder,
8
+ mapSegmentProduct,
9
+ mapSegmentProductList
10
+ } from "./segment-event-mapper";
11
+ function findSegment() {
12
+ if (typeof window === "undefined") {
13
+ return null;
14
+ }
15
+ return window.analytics ?? null;
16
+ }
17
+ class SegmentSink {
18
+ send = createAnalyticsQueue({
19
+ isReady: () => Boolean(findSegment()),
20
+ send: (call) => {
21
+ const analytics = findSegment();
22
+ if (call.method === "page") {
23
+ analytics?.page(call.properties);
24
+ } else {
25
+ analytics?.track(call.event, call.properties);
26
+ }
27
+ },
28
+ queueName: "Segment"
29
+ });
30
+ track(event, properties) {
31
+ this.send({ method: "track", event, properties });
32
+ }
33
+ async customEvent({ event, properties }) {
34
+ this.track(event, properties ?? {});
35
+ }
36
+ async pageView(metadata) {
37
+ if (metadata?.navigationType === "initial") {
38
+ return;
39
+ }
40
+ if (!metadata) {
41
+ this.send({ method: "page", properties: {} });
42
+ return;
43
+ }
44
+ this.send({
45
+ method: "page",
46
+ properties: {
47
+ url: metadata.url,
48
+ path: new URL(metadata.url, window.location.origin).pathname,
49
+ title: metadata.title,
50
+ referrer: metadata.referrer
51
+ }
52
+ });
53
+ }
54
+ async purchase(payload) {
55
+ this.track("Order Completed", mapSegmentOrder(payload));
56
+ }
57
+ async click({ data }) {
58
+ this.track("Element Clicked", data);
59
+ }
60
+ async productViewed({ data }) {
61
+ this.track("Product Viewed", mapSegmentProduct(data, data.currency));
62
+ }
63
+ async addToCart({ data }) {
64
+ this.track("Product Added", mapSegmentCartLine(data));
65
+ }
66
+ async removeFromCart({ data }) {
67
+ this.track("Product Removed", mapSegmentCartLine(data));
68
+ }
69
+ async viewCart({ data }) {
70
+ this.track("Cart Viewed", mapSegmentCartViewed(data));
71
+ }
72
+ async startCheckout(payload) {
73
+ this.track(
74
+ "Checkout Started",
75
+ mapSegmentCheckoutStarted(toCheckoutStartedData(payload.data))
76
+ );
77
+ }
78
+ async viewCollection({ data }) {
79
+ this.track("Product List Viewed", mapSegmentProductList(data));
80
+ }
81
+ }
82
+ export {
83
+ SegmentSink
84
+ };
@@ -1,7 +1,7 @@
1
1
  export const BUILD_METADATA = {
2
2
  "packageName": "@replohq/sdk",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "branch": "HEAD",
5
- "commit": "17bbe81f0395ba343461c4ec1df4662e1ede00bd",
6
- "builtAt": "2026-10-19T23:10:20.892Z"
5
+ "commit": "fd5e2e68393795f73c76f04e5fbccad127d8ee31",
6
+ "builtAt": "2026-10-20T14:39:29.462Z"
7
7
  };
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@replohq/sdk",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "reploBuild": {
5
5
  "packageName": "@replohq/sdk",
6
- "version": "2.0.0",
6
+ "version": "2.1.0",
7
7
  "branch": "HEAD",
8
- "commit": "17bbe81f0395ba343461c4ec1df4662e1ede00bd",
9
- "builtAt": "2026-10-19T23:10:20.892Z"
8
+ "commit": "fd5e2e68393795f73c76f04e5fbccad127d8ee31",
9
+ "builtAt": "2026-10-20T14:39:29.462Z"
10
10
  },
11
11
  "description": "Replo SDK — cart, analytics, and data loaders for agent-built Next.js sites.",
12
12
  "license": "SEE LICENSE IN LICENSE",