@vio-live/web-sdk 0.4.2 → 0.5.1

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,4 +1,4 @@
1
- import { Vio, __decorateClass, primaryImageUrl, displayPrice, getGlobalCurrency, formatPrice } from './chunk-KMIARP6X.js';
1
+ import { Vio, __decorateClass, primaryImageUrl, displayPrice, getGlobalCurrency, formatPrice } from './chunk-7Q4MJ5NQ.js';
2
2
  import { LitElement, css, html } from 'lit';
3
3
  import { property, state, query } from 'lit/decorators.js';
4
4
 
@@ -460,6 +460,13 @@ var VioProductCarousel = class extends LitElement {
460
460
  this.fetched = null;
461
461
  this.isLoading = false;
462
462
  this.fetchError = "";
463
+ // ── Analytics (auto) ──────────────────────────────────────────────
464
+ // component_impression on the contract rule (≥50% visible ≥1s, once per
465
+ // session) + view_item_list with the rendered products. No-ops unless
466
+ // Vio.analytics.start() ran.
467
+ this.unobserveImpression = null;
468
+ this.impressed = false;
469
+ this.listTracked = false;
463
470
  }
464
471
  static {
465
472
  this.styles = css`
@@ -608,10 +615,16 @@ var VioProductCarousel = class extends LitElement {
608
615
  }
609
616
  connectedCallback() {
610
617
  super.connectedCallback();
618
+ this.observeForAnalytics();
611
619
  if (this.productRefs.trim() || this.productIds.trim()) {
612
620
  void this.autoFetch();
613
621
  }
614
622
  }
623
+ disconnectedCallback() {
624
+ this.unobserveImpression?.();
625
+ this.unobserveImpression = null;
626
+ super.disconnectedCallback();
627
+ }
615
628
  updated(changed) {
616
629
  const propChanged = changed.has("productRefs") || changed.has("productIds") || changed.has("commerceKey") || changed.has("sponsorId");
617
630
  if (propChanged && (this.productRefs.trim() || this.productIds.trim())) {
@@ -656,12 +669,61 @@ var VioProductCarousel = class extends LitElement {
656
669
  const product = lookup.get(`${sponsorId}:${productId}`);
657
670
  return product ? { product, sponsorId } : null;
658
671
  }).filter((x) => x !== null);
672
+ this.maybeTrackList();
659
673
  } catch (err) {
660
674
  this.fetchError = err instanceof Error ? err.message : String(err);
661
675
  } finally {
662
676
  this.isLoading = false;
663
677
  }
664
678
  }
679
+ observeForAnalytics() {
680
+ if (this.unobserveImpression) return;
681
+ try {
682
+ this.unobserveImpression = Vio.analytics.observeImpression(
683
+ this,
684
+ {
685
+ sponsorId: this.sponsorId > 0 ? this.sponsorId : void 0,
686
+ componentTemplateId: "product-carousel",
687
+ locationId: this.label || void 0
688
+ },
689
+ {
690
+ key: `carousel:${this.label || this.productIds || this.productRefs || "default"}`,
691
+ onImpression: () => {
692
+ this.impressed = true;
693
+ this.maybeTrackList();
694
+ }
695
+ }
696
+ );
697
+ } catch {
698
+ }
699
+ }
700
+ /** view_item_list needs BOTH the viewport dwell and loaded products —
701
+ * whichever lands last fires it (once). */
702
+ maybeTrackList() {
703
+ if (!this.impressed || this.listTracked) return;
704
+ const entries = this.fetched ?? [];
705
+ if (entries.length === 0) return;
706
+ this.listTracked = true;
707
+ try {
708
+ Vio.analytics.track("view_item_list", {
709
+ context: {
710
+ sponsorId: this.sponsorId > 0 ? this.sponsorId : void 0,
711
+ componentTemplateId: "product-carousel",
712
+ locationId: this.label || void 0
713
+ },
714
+ commerce: {
715
+ items: entries.map(({ product, sponsorId }) => ({
716
+ productId: product.id,
717
+ name: product.title,
718
+ price: Number(product.price?.amount_incl_taxes ?? product.price?.amount) || void 0
719
+ })),
720
+ currency: entries[0]?.product.price?.currency_code
721
+ },
722
+ props: this.label ? { list_name: this.label } : void 0
723
+ });
724
+ } catch {
725
+ }
726
+ }
665
727
  parseRefs(raw) {
666
728
  return raw.split(",").map((pair) => pair.trim()).filter((s) => s.length > 0).map((pair) => {
667
729
  const [sidStr, pidStr] = pair.split(":");
@@ -1313,6 +1375,31 @@ var VioProductDetail = class extends LitElement {
1313
1375
  }
1314
1376
  this.optMapCache = /* @__PURE__ */ new WeakMap();
1315
1377
  this.product = products?.[0] ?? null;
1378
+ if (this.product) {
1379
+ try {
1380
+ const price = Number(
1381
+ this.product.price?.amount_incl_taxes ?? this.product.price?.amount
1382
+ );
1383
+ Vio.analytics.track("view_item", {
1384
+ context: {
1385
+ sponsorId: this.sponsorId > 0 ? Number(this.sponsorId) : void 0,
1386
+ componentTemplateId: "product-detail"
1387
+ },
1388
+ commerce: {
1389
+ items: [
1390
+ {
1391
+ productId: this.product.id,
1392
+ name: this.product.title,
1393
+ price: Number.isFinite(price) ? price : void 0
1394
+ }
1395
+ ],
1396
+ value: Number.isFinite(price) ? price : void 0,
1397
+ currency: this.product.price?.currency_code
1398
+ }
1399
+ });
1400
+ } catch {
1401
+ }
1402
+ }
1316
1403
  if (!this.product) {
1317
1404
  this.fetchError = "Fant ikke produktet.";
1318
1405
  }
@@ -2361,6 +2448,9 @@ var VioCart = class extends LitElement {
2361
2448
  }
2362
2449
  show() {
2363
2450
  this.open = true;
2451
+ this.dispatchEvent(
2452
+ new CustomEvent("vio:open-cart", { bubbles: true, composed: true })
2453
+ );
2364
2454
  void this.loadAvailablePaymentMethods();
2365
2455
  }
2366
2456
  /** Which payment buttons to render — backend-configured per sponsor.
@@ -4384,5 +4474,5 @@ function registerVioElements() {
4384
4474
  }
4385
4475
 
4386
4476
  export { VioCart, VioCheckout, VioProduct, VioProductCarousel, VioProductDetail, VioTokens, applyVioTheme, registerVioElements };
4387
- //# sourceMappingURL=chunk-D6IA4ZWL.js.map
4388
- //# sourceMappingURL=chunk-D6IA4ZWL.js.map
4477
+ //# sourceMappingURL=chunk-LRXVUOEG.js.map
4478
+ //# sourceMappingURL=chunk-LRXVUOEG.js.map