@fayz-ai/storefront 0.77.5 → 0.79.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.
@@ -1 +1 @@
1
- {"version":3,"file":"StorefrontAnalytics.d.ts","sourceRoot":"","sources":["../../src/analytics/StorefrontAnalytics.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAClE,OAAO,EAAE,YAAY,EAA+B,MAAM,sBAAsB,CAAA;AAIhF,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAA;AAE5D,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAIlF;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC;UAIrE,OAAO,GAAG,SAAS;UAAQ,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;cAAY,MAAM;IAQpG;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;IAAE,MAAM,EAAE,wBAAwB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,QAoDvG"}
1
+ {"version":3,"file":"StorefrontAnalytics.d.ts","sourceRoot":"","sources":["../../src/analytics/StorefrontAnalytics.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAClE,OAAO,EAAE,YAAY,EAA+B,MAAM,sBAAsB,CAAA;AAKhF,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAA;AAE5D,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAIlF;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC;UAIrE,OAAO,GAAG,SAAS;UAAQ,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;cAAY,MAAM;IAQpG;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;IAAE,MAAM,EAAE,wBAAwB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,QAmEvG"}
@@ -23,6 +23,8 @@ export declare function onStorefrontEvent(listener: Listener): () => void;
23
23
  * an event property.
24
24
  */
25
25
  export declare function identifyStorefrontBuyer(email: string): void;
26
+ /** Hear the buyer's e-mail (now, if already known, and on every change). */
27
+ export declare function onStorefrontBuyer(listener: Identifier): () => void;
26
28
  export declare function setStorefrontIdentifier(fn: Identifier | null): void;
27
29
  /** When this event was last reported on this page (0 = never). */
28
30
  export declare function lastStorefrontEventAt(name: StorefrontEventName): number;
@@ -1 +1 @@
1
- {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../../src/analytics/bus.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,mBAAmB,GAC3B,gBAAgB,GAChB,uBAAuB,GACvB,2BAA2B,GAC3B,aAAa,GACb,gBAAgB,GAChB,kBAAkB,GAClB,sBAAsB,GACtB,2BAA2B,GAC3B,gBAAgB,GAChB,oBAAoB,GACpB,eAAe,CAAA;AAEnB,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;AAEpG,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAA;IACzB,UAAU,EAAE,yBAAyB,CAAA;IACrC,EAAE,EAAE,MAAM,CAAA;CACX;AAED,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;AAChD,KAAK,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;AASzC,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,EAAE,UAAU,GAAE,yBAA8B,GAAG,IAAI,CAY3G;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,IAAI,CAUhE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK3D;AAED,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAMnE;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAEvE;AAED,mDAAmD;AACnD,wBAAgB,qBAAqB,IAAI,IAAI,CAM5C"}
1
+ {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../../src/analytics/bus.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,mBAAmB,GAC3B,gBAAgB,GAChB,uBAAuB,GACvB,2BAA2B,GAC3B,aAAa,GACb,gBAAgB,GAChB,kBAAkB,GAClB,sBAAsB,GACtB,2BAA2B,GAC3B,gBAAgB,GAChB,oBAAoB,GACpB,eAAe,CAAA;AAEnB,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;AAEpG,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAA;IACzB,UAAU,EAAE,yBAAyB,CAAA;IACrC,EAAE,EAAE,MAAM,CAAA;CACX;AAED,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;AAChD,KAAK,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;AAazC,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,EAAE,UAAU,GAAE,yBAA8B,GAAG,IAAI,CAY3G;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,IAAI,CAUhE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAS3D;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,IAAI,CAMlE;AAED,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAMnE;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAEvE;AAED,mDAAmD;AACnD,wBAAgB,qBAAqB,IAAI,IAAI,CAQ5C"}
@@ -1,5 +1,6 @@
1
- export { trackStorefront, onStorefrontEvent, identifyStorefrontBuyer, type StorefrontEvent, type StorefrontEventName, type StorefrontEventProperties, } from './bus';
1
+ export { trackStorefront, onStorefrontEvent, identifyStorefrontBuyer, onStorefrontBuyer, type StorefrontEvent, type StorefrontEventName, type StorefrontEventProperties, } from './bus';
2
2
  export { storeBuyerId } from './identity';
3
3
  export { startStorefrontPostHog, type StorefrontAnalyticsConfig, type StorefrontPostHogConfig } from './posthog';
4
+ export { startStorefrontMetaPixel, metaEventFor, type StorefrontMetaPixelConfig, type MetaEvent } from './meta-pixel';
4
5
  export { StorefrontAnalytics, isOrderingPath, cartChanges } from './StorefrontAnalytics';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,GAC/B,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,sBAAsB,EAAE,KAAK,yBAAyB,EAAE,KAAK,uBAAuB,EAAE,MAAM,WAAW,CAAA;AAChH,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,GAC/B,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,sBAAsB,EAAE,KAAK,yBAAyB,EAAE,KAAK,uBAAuB,EAAE,MAAM,WAAW,CAAA;AAChH,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAE,KAAK,yBAAyB,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AACrH,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA"}
@@ -0,0 +1,52 @@
1
+ import { type StorefrontEvent } from './bus';
2
+ /**
3
+ * The store's Meta Pixel as one more listener on the storefront's own events.
4
+ *
5
+ * Components never call Meta: they report to the bus (product viewed, added to
6
+ * cart, checkout started, payment chosen, order placed) and this maps each one
7
+ * to the standard event Meta's ads optimise for. The pixel id is the store's —
8
+ * Loja › Configurações › Loja › Rastreamento (shop 0148), or `analytics.metaPixel`
9
+ * in code.
10
+ *
11
+ * Purchase carries the order id as its `eventID`, so a server-side Conversions
12
+ * API sending the same order later is deduplicated by Meta, not counted twice.
13
+ */
14
+ export interface StorefrontMetaPixelConfig {
15
+ /** Digits only, as Meta shows it in the Events Manager. */
16
+ pixelId: string;
17
+ }
18
+ type Fbq = ((...args: unknown[]) => void) & {
19
+ callMethod?: (...args: unknown[]) => void;
20
+ queue: unknown[];
21
+ push: unknown;
22
+ loaded: boolean;
23
+ version: string;
24
+ };
25
+ declare global {
26
+ interface Window {
27
+ fbq?: Fbq;
28
+ _fbq?: Fbq;
29
+ }
30
+ }
31
+ export declare const META_PIXEL_ID: RegExp;
32
+ export interface MetaEvent {
33
+ name: 'ViewContent' | 'AddToCart' | 'InitiateCheckout' | 'AddPaymentInfo' | 'Purchase';
34
+ params: Record<string, unknown>;
35
+ /** Meta's dedup key; set on Purchase (the order id). */
36
+ eventId?: string;
37
+ }
38
+ /** A storefront event in Meta's words, or null when Meta has no standard event for it. */
39
+ export declare function metaEventFor(event: StorefrontEvent, currency: string): MetaEvent | null;
40
+ /**
41
+ * Loads the pixel once per page (browser only) and starts reporting. Calling it
42
+ * again with the same id is a no-op; with another id, the old listener stops.
43
+ */
44
+ export declare function startStorefrontMetaPixel(config: StorefrontMetaPixelConfig, context: {
45
+ currency: string;
46
+ }): void;
47
+ /** A page view for the single-page navigation (the base code only reports the first load). */
48
+ export declare function trackMetaPageView(): void;
49
+ /** Test seam. */
50
+ export declare function resetStorefrontMetaPixel(): void;
51
+ export {};
52
+ //# sourceMappingURL=meta-pixel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta-pixel.d.ts","sourceRoot":"","sources":["../../src/analytics/meta-pixel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,eAAe,EAAE,MAAM,OAAO,CAAA;AAElF;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,yBAAyB;IACxC,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,KAAK,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,GAAG;IAC1C,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IACzC,KAAK,EAAE,OAAO,EAAE,CAAA;IAChB,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,GAAG,CAAC,EAAE,GAAG,CAAA;QACT,IAAI,CAAC,EAAE,GAAG,CAAA;KACX;CACF;AAED,eAAO,MAAM,aAAa,QAAmB,CAAA;AAE7C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,aAAa,GAAG,WAAW,GAAG,kBAAkB,GAAG,gBAAgB,GAAG,UAAU,CAAA;IACtF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAKD,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAyCvF;AAuCD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,yBAAyB,EAAE,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqB/G;AAED,8FAA8F;AAC9F,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAED,iBAAiB;AACjB,wBAAgB,wBAAwB,IAAI,IAAI,CAG/C"}
@@ -12,6 +12,12 @@ export interface StorefrontPostHogConfig {
12
12
  }
13
13
  export interface StorefrontAnalyticsConfig {
14
14
  posthog?: StorefrontPostHogConfig;
15
+ /**
16
+ * The store's Meta Pixel. Usually left out: the id the merchant saves in
17
+ * Loja › Configurações › Loja › Rastreamento (shop 0148) is used. Set it here
18
+ * only to pin one in code.
19
+ */
20
+ metaPixel?: import('./meta-pixel').StorefrontMetaPixelConfig;
15
21
  }
16
22
  interface StartContext {
17
23
  storeName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"posthog.d.ts","sourceRoot":"","sources":["../../src/analytics/posthog.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,uBAAuB;IACtC,8EAA8E;IAC9E,GAAG,EAAE,MAAM,CAAA;IACX,sFAAsF;IACtF,OAAO,EAAE,MAAM,CAAA;IACf,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,uBAAuB,CAAA;CAClC;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;CACrB;AAID;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,uBAAuB,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAkCnH"}
1
+ {"version":3,"file":"posthog.d.ts","sourceRoot":"","sources":["../../src/analytics/posthog.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,uBAAuB;IACtC,8EAA8E;IAC9E,GAAG,EAAE,MAAM,CAAA;IACX,sFAAsF;IACtF,OAAO,EAAE,MAAM,CAAA;IACf,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,uBAAuB,CAAA;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,cAAc,EAAE,yBAAyB,CAAA;CAC7D;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;CACrB;AAID;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,uBAAuB,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAkCnH"}
@@ -35,16 +35,16 @@ export interface LinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorEle
35
35
  * explicit targets are still handed to the browser.
36
36
  */
37
37
  export declare function Link({ to, children, onClick, target, ...rest }: LinkProps): React.DetailedReactHTMLElement<{
38
- prefix?: string | undefined | undefined;
39
- style?: React.CSSProperties | undefined;
40
38
  slot?: string | undefined | undefined;
39
+ style?: React.CSSProperties | undefined;
41
40
  title?: string | undefined | undefined;
41
+ prefix?: string | undefined | undefined;
42
+ referrerPolicy?: React.HTMLAttributeReferrerPolicy | undefined;
43
+ type?: string | undefined | undefined;
42
44
  download?: any;
43
45
  hrefLang?: string | undefined | undefined;
44
46
  media?: string | undefined | undefined;
45
47
  ping?: string | undefined | undefined;
46
- type?: string | undefined | undefined;
47
- referrerPolicy?: React.HTMLAttributeReferrerPolicy | undefined;
48
48
  defaultChecked?: boolean | undefined | undefined;
49
49
  defaultValue?: string | number | readonly string[] | undefined;
50
50
  suppressContentEditableWarning?: boolean | undefined | undefined;
@@ -457,6 +457,8 @@ var listeners = /* @__PURE__ */ new Set();
457
457
  var pending = [];
458
458
  var identifier = null;
459
459
  var pendingEmail = null;
460
+ var buyerListeners = /* @__PURE__ */ new Set();
461
+ var lastEmail = null;
460
462
  var lastAt = /* @__PURE__ */ new Map();
461
463
  function trackStorefront(name, properties = {}) {
462
464
  if (typeof window === "undefined") return;
@@ -495,6 +497,25 @@ function identifyStorefrontBuyer(email) {
495
497
  if (!clean.includes("@")) return;
496
498
  if (identifier) identifier(clean);
497
499
  else pendingEmail = clean;
500
+ lastEmail = clean;
501
+ for (const listener of buyerListeners) {
502
+ try {
503
+ listener(clean);
504
+ } catch {
505
+ }
506
+ }
507
+ }
508
+ function onStorefrontBuyer(listener) {
509
+ buyerListeners.add(listener);
510
+ if (lastEmail) {
511
+ try {
512
+ listener(lastEmail);
513
+ } catch {
514
+ }
515
+ }
516
+ return () => {
517
+ buyerListeners.delete(listener);
518
+ };
498
519
  }
499
520
  function setStorefrontIdentifier(fn) {
500
521
  identifier = fn;
@@ -557,6 +578,109 @@ function startStorefrontPostHog(config, context) {
557
578
  });
558
579
  return started;
559
580
  }
581
+
582
+ // src/analytics/meta-pixel.ts
583
+ var META_PIXEL_ID = /^[0-9]{10,20}$/;
584
+ var num = (v) => typeof v === "number" && Number.isFinite(v) ? v : void 0;
585
+ var str = (v) => typeof v === "string" && v ? v : void 0;
586
+ function metaEventFor(event, currency) {
587
+ const p = event.properties;
588
+ switch (event.name) {
589
+ case "product_viewed": {
590
+ const id = str(p.product_id);
591
+ if (!id) return null;
592
+ return {
593
+ name: "ViewContent",
594
+ params: { content_ids: [id], content_name: str(p.product_name), content_type: "product", value: num(p.price), currency }
595
+ };
596
+ }
597
+ case "product_added_to_cart": {
598
+ const id = str(p.product_id);
599
+ if (!id) return null;
600
+ const quantity = num(p.quantity) ?? 1;
601
+ const price = num(p.price);
602
+ return {
603
+ name: "AddToCart",
604
+ params: {
605
+ content_ids: [id],
606
+ content_name: str(p.product_name),
607
+ content_type: "product",
608
+ contents: [{ id, quantity, item_price: price }],
609
+ value: price === void 0 ? void 0 : Math.round(price * quantity * 100) / 100,
610
+ currency
611
+ }
612
+ };
613
+ }
614
+ case "checkout_started":
615
+ return { name: "InitiateCheckout", params: { num_items: num(p.cart_count), value: num(p.cart_subtotal), currency } };
616
+ case "checkout_payment_selected":
617
+ return { name: "AddPaymentInfo", params: { payment_method: str(p.payment_method), currency } };
618
+ case "checkout_completed": {
619
+ const orderId = str(p.order_id);
620
+ const value = num(p.total);
621
+ if (!orderId || value === void 0) return null;
622
+ return { name: "Purchase", params: { value, currency, order_id: orderId }, eventId: orderId };
623
+ }
624
+ default:
625
+ return null;
626
+ }
627
+ }
628
+ var strip = (params) => Object.fromEntries(Object.entries(params).filter(([, v]) => v !== void 0 && v !== null));
629
+ function installFbq() {
630
+ if (window.fbq) return window.fbq;
631
+ const fbq = function(...args) {
632
+ if (fbq.callMethod) fbq.callMethod(...args);
633
+ else fbq.queue.push(args);
634
+ };
635
+ fbq.push = fbq;
636
+ fbq.loaded = true;
637
+ fbq.version = "2.0";
638
+ fbq.queue = [];
639
+ window.fbq = fbq;
640
+ if (!window._fbq) window._fbq = fbq;
641
+ const script = document.createElement("script");
642
+ script.async = true;
643
+ script.src = "https://connect.facebook.net/en_US/fbevents.js";
644
+ document.head.appendChild(script);
645
+ return fbq;
646
+ }
647
+ var PURCHASES_KEY = "fayz.meta.purchases";
648
+ function purchaseSeen(orderId) {
649
+ try {
650
+ const seen = JSON.parse(sessionStorage.getItem(PURCHASES_KEY) ?? "[]");
651
+ if (seen.includes(orderId)) return true;
652
+ sessionStorage.setItem(PURCHASES_KEY, JSON.stringify([...seen.slice(-19), orderId]));
653
+ } catch {
654
+ }
655
+ return false;
656
+ }
657
+ var started2 = null;
658
+ function startStorefrontMetaPixel(config, context) {
659
+ if (typeof window === "undefined") return;
660
+ const pixelId = config.pixelId.trim();
661
+ if (!META_PIXEL_ID.test(pixelId)) return;
662
+ if (started2?.pixelId === pixelId) return;
663
+ started2?.stop();
664
+ const fbq = installFbq();
665
+ fbq("init", pixelId);
666
+ const offEvents = onStorefrontEvent((event) => {
667
+ const meta = metaEventFor(event, context.currency);
668
+ if (!meta) return;
669
+ if (meta.name === "Purchase" && meta.eventId && purchaseSeen(meta.eventId)) return;
670
+ fbq("trackSingle", pixelId, meta.name, strip(meta.params), meta.eventId ? { eventID: meta.eventId } : void 0);
671
+ });
672
+ const offBuyer = onStorefrontBuyer((email) => fbq("init", pixelId, { em: email }));
673
+ started2 = { pixelId, stop: () => {
674
+ offEvents();
675
+ offBuyer();
676
+ } };
677
+ }
678
+ function trackMetaPageView() {
679
+ if (typeof window === "undefined" || !started2) return;
680
+ window.fbq?.("trackSingle", started2.pixelId, "PageView");
681
+ }
682
+
683
+ // src/analytics/StorefrontAnalytics.tsx
560
684
  function isOrderingPath(path, menuPath) {
561
685
  const p = path.split(/[?#]/)[0] || "/";
562
686
  if (menuPath && menuPath !== "/" && (p === menuPath || p.startsWith(`${menuPath}/`))) return true;
@@ -577,6 +701,9 @@ function cartChanges(prev, next) {
577
701
  }
578
702
  function StorefrontAnalytics({ config, path }) {
579
703
  const posthog = config.analytics?.posthog;
704
+ const pixelId = config.analytics?.metaPixel?.pixelId ?? config.policy?.metaPixelId ?? null;
705
+ const metaPixel = pixelId && META_PIXEL_ID.test(pixelId) ? pixelId : null;
706
+ const reporting = Boolean(posthog || metaPixel);
580
707
  const menuPath = config.delivery?.menuPath;
581
708
  const previous = React39.useRef(null);
582
709
  React39.useEffect(() => {
@@ -584,7 +711,14 @@ function StorefrontAnalytics({ config, path }) {
584
711
  startStorefrontPostHog(posthog, { storeName: config.name, commerceMode: config.commerceMode });
585
712
  }, [posthog, config.name, config.commerceMode]);
586
713
  React39.useEffect(() => {
587
- if (!posthog) return;
714
+ if (!metaPixel) return;
715
+ startStorefrontMetaPixel({ pixelId: metaPixel }, { currency: config.currency ?? "BRL" });
716
+ }, [metaPixel, config.currency]);
717
+ React39.useEffect(() => {
718
+ if (metaPixel) trackMetaPageView();
719
+ }, [metaPixel, path]);
720
+ React39.useEffect(() => {
721
+ if (!reporting) return;
588
722
  let ready = useCartStore.persist?.hasHydrated?.() ?? true;
589
723
  const unhydrated = useCartStore.persist?.onFinishHydration?.(() => {
590
724
  ready = true;
@@ -613,9 +747,9 @@ function StorefrontAnalytics({ config, path }) {
613
747
  unsubscribe();
614
748
  unhydrated?.();
615
749
  };
616
- }, [posthog]);
750
+ }, [reporting]);
617
751
  React39.useEffect(() => {
618
- if (!posthog) return;
752
+ if (!reporting) return;
619
753
  const from = previous.current;
620
754
  previous.current = path;
621
755
  if (!from || from === path) return;
@@ -623,7 +757,7 @@ function StorefrontAnalytics({ config, path }) {
623
757
  const cart = useCartStore.getState();
624
758
  trackStorefront("delivery_exit", { from, to: path, cart_count: selectCount(cart), cart_subtotal: selectSubtotal(cart) });
625
759
  }
626
- }, [posthog, path, menuPath]);
760
+ }, [reporting, path, menuPath]);
627
761
  return null;
628
762
  }
629
763
  var useSessionStore = create()(
@@ -4551,8 +4685,8 @@ function ProductSpecs({ product }) {
4551
4685
  if (product.weight != null) rows.push(["Peso", `${product.weight} ${product.weightUnit}`]);
4552
4686
  for (const [key, value] of Object.entries(product.metadata ?? {})) {
4553
4687
  if (isInternalKey(key, extraExcluded)) continue;
4554
- const str = scalarToString(value);
4555
- if (str) rows.push([humanize(key, extraLabels), str]);
4688
+ const str2 = scalarToString(value);
4689
+ if (str2) rows.push([humanize(key, extraLabels), str2]);
4556
4690
  }
4557
4691
  if (rows.length === 0) return null;
4558
4692
  return /* @__PURE__ */ jsxs("section", { className: "mt-14", children: [
@@ -9834,7 +9968,14 @@ function CheckoutPage() {
9834
9968
  useEffect(() => {
9835
9969
  if (reportedStart.current) return;
9836
9970
  reportedStart.current = true;
9837
- if (!resume) trackStorefront("checkout_started", { cart_count: cart.lines.reduce((n, l) => n + l.quantity, 0) });
9971
+ if (!resume) {
9972
+ trackStorefront("checkout_started", {
9973
+ cart_count: cart.lines.reduce((n, l) => n + l.quantity, 0),
9974
+ // What the cart is worth when the checkout opens: the value an ad
9975
+ // platform optimises InitiateCheckout for.
9976
+ cart_subtotal: Math.round(cart.lines.reduce((sum, l) => sum + l.unitPrice * l.quantity, 0) * 100) / 100
9977
+ });
9978
+ }
9838
9979
  }, []);
9839
9980
  const reportedStep = React39__default.useRef(null);
9840
9981
  useEffect(() => {
@@ -15026,5 +15167,5 @@ ${formatErrors(report.errors)}`;
15026
15167
  }
15027
15168
 
15028
15169
  export { AddressForm, AddressSheet, AddressStrip, BEFORE_PLACE_ORDER_VALVE, BLOCK_STRUCTURAL_KEYS, BUYER_COUNTRY_COOKIE, BenefitsRow, BlockDataError, CART_LINE_ANNOTATION_POINT, CATALOG_BODY_BLOCK, CHECKOUT_FIELD_POINT, CartDrawer, CatalogPage, CategoryShowcase, CheckoutPage, ClosedStoreDialog, CollectionCta, CollectionHero, ContentPage, CountdownBand, CountrySelect, DeliverToPicker, EmailConfirmationRequiredError, EntityListBlock, FaqSection, FiltersPanel, FormBlock, HeroSection, ImageTiles, ItemSheet, Link, MESSAGES, ManifestoBlock, MediaCarousel, MenuItemRow, MenuPage, MenuToolbar, MotifStrip, MyPurchasesPage, NewsletterBand, ORDER_METADATA_POINT, OrderConfirmationPage, OrderTrackingTimeline, PAGE_DATA_SCRIPT_ID, PLACEHOLDER_ASPECTS, PRODUCT_BODY_BLOCK, PRODUCT_CARD_BADGE_POINT, PageDataScope, PaymentTerms, Price, ProductCard, ProductDetailPage, ProductEnquiryForm, ProductGallery, ProductGrid, ProductOptionSelector, ProductRail, ProductReviews, ProductSlider, ProductSpecs, ProductSpotlight, PromoBanner, QuantityInput, Reveal, STOREFRONT_COMPONENT_KEYS, STOREFRONT_PAGE_KINDS, STOREFRONT_SLOTS, STORE_BACKEND_PROVIDERS, STORE_COMMERCE_MODES, STORE_DOCUMENT_KIND, STORE_PAYMENT_METHOD_KINDS, STORE_PAYMENT_MODES, STORE_ROUTE_CHROMES, STORE_ROUTE_KINDS, STORE_SECTIONS, STORE_SECTION_NAMES, ScheduleSheet, SealsBand, SearchOverlay, ServiceHoursModal, Slot, SmoothImage, StepsSection, StoreCover, StorefrontAnalytics, StorefrontConfigHost, StorefrontConfigProvider, StorefrontFooter, StorefrontHeader, StorefrontPage, StorefrontRouterProvider, StorefrontShell, StorefrontThemeStyle, StoryQuote, THEME_SCALE_FIELDS, THEME_SCALE_VAR_PREFIX, TID, Testimonials, TierCards, applyDeliveryPolicy, applyStoreSettings, bannerPlaceholder, blockInstanceId, buildEnquiryFromForm, checkPageBlocks, collectDataNeeds, collectOrderMetadata, contentPagePath, createStorefront, createStorefrontApp, currentStaticRenderPass, defaultPageBlocks, entityListBlockMeta, establishCustomerSession, exportStore, formatMoney, formatProductOptionSelection, getCartLineAnnotations, getCheckoutFieldContributions, getCustomerAuthAdapter, getProductCardBadges, getProductOptionGroups, hydrateStoreDocument, hydratedEntriesFor, identifyStorefrontBuyer, initStorefrontRuntime, isJsonValue, isKnownPath, isNestedBlockRef, isPublicPath, isRecord, listSlots, marketForCountry, marketUnitPrice, matchContentPage, matchPath, matchesFacets, mergeCollectionFacet, mergePageTheme, navigateTo, nextMilestone, normalizeLanguage, normalizeProductOptionSelection, onStorefrontEvent, orderGalleryImages, overrideComponent, overrideProps, pageSeo, pageThemeSelector, pickProductCardImage, placeStorefrontOrder, prefersReducedMotion, primaryImageUrl, productCardComponentContract, productJsonLd, productOptionSelectionKey, productPlaceholder, productSeo, readHydratedPageData, registerStorefrontBlocks, registerStorefrontEntities, registerStorefrontExtensionPoints, registerStorefrontLoaders, resetPageDiagnostics, resetProductOptionsDeprecationWarnings, resetStorefrontExtensionPoints, resolveAuthAdapter, resolveConfig, resolveDataParams, resolveOverride, resolvePageData, resolvePageDataNeed, resolvePaymentTerms, resolveStorefrontProvider, resolveStorefrontRoute, resolveVariantForSelection, roundCents, routePathParams, runBeforePlaceOrderValve, sectionToJsonSchema, sectionsToBlocks, selectCount, selectDiscountTotal, selectIsOpen, selectRequiresShipping, selectShipping, selectShowsHours, selectSubtotal, selectTotal, selectionPrice, serializePageData, shellRouterAdapter, signInByEmail, signOutCustomer, signUpCustomer, slugifyStoreName, startStorefrontPostHog, storeBuyerId, storefrontComponentContracts, storefrontPaths, themeToCss, toBlockNodes, toFacetMap, trackStorefront, translate, useBlockData, useBuyerCountry, useBuyerStore, useCartStore, useCatalogStore, useCategories, useDeliveryStore, useDiscountValidator, useEnquiry, useHashPath, useInView, useLoader, useMarketProduct, useMarketStore, useMyOrders, useNavigate, usePopOnChange, useProduct, useProducts, useRoutePath, useRouterAdapter, useScrollToTopOnNavigate, useScrolled, useServiceStore, useSessionStore, useSlotContext, useStorefrontActions, useStorefrontConfig, useStorefrontConfigOptional, useStorefrontHead, useStorefrontPage, useStorefrontPageOptional, useT, usedSlots, validateStore, withFacet, withMarketPrice, withStaticRenderPass };
15029
- //# sourceMappingURL=chunk-3XECLBVJ.js.map
15030
- //# sourceMappingURL=chunk-3XECLBVJ.js.map
15170
+ //# sourceMappingURL=chunk-3C4WJIOI.js.map
15171
+ //# sourceMappingURL=chunk-3C4WJIOI.js.map