@primestyleai/tryon 5.10.194 → 5.10.195

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,21 +1,21 @@
1
1
  "use client";
2
- import { c as l, A as c, S as h, i as u, a as m } from "./index-BiotPzcm.js";
3
- import { P as x, b as w, T as C, d as k, e as U, r as S } from "./index-BiotPzcm.js";
2
+ import { c as l, A as c, i as h, a as u, S as m } from "./index-D_9-KLXy.js";
3
+ import { P as x, b as w, T as C, d as S, e as E, r as U } from "./index-D_9-KLXy.js";
4
4
  function d() {
5
5
  const i = document.querySelector(
6
6
  'meta[property="og:image"]'
7
7
  );
8
8
  if (i?.content) return i.content;
9
- const t = document.querySelectorAll(
9
+ const e = document.querySelectorAll(
10
10
  'script[type="application/ld+json"]'
11
11
  );
12
- for (const s of t)
12
+ for (const r of e)
13
13
  try {
14
- const r = JSON.parse(s.textContent || ""), o = p(r);
14
+ const s = JSON.parse(r.textContent || ""), o = p(s);
15
15
  if (o) return o;
16
16
  } catch {
17
17
  }
18
- const e = [
18
+ const t = [
19
19
  "[data-product-image] img",
20
20
  "[data-product-image]",
21
21
  ".product-image img",
@@ -26,10 +26,10 @@ function d() {
26
26
  ".woocommerce-product-gallery img",
27
27
  ".product-media img"
28
28
  ];
29
- for (const s of e) {
30
- const r = document.querySelector(s);
31
- if (r) {
32
- const o = r.src || r.dataset.src || r.dataset.zoom;
29
+ for (const r of t) {
30
+ const s = document.querySelector(r);
31
+ if (s) {
32
+ const o = s.src || s.dataset.src || s.dataset.zoom;
33
33
  if (o) return o;
34
34
  }
35
35
  }
@@ -38,24 +38,24 @@ function d() {
38
38
  function p(i) {
39
39
  if (!i || typeof i != "object") return null;
40
40
  if (Array.isArray(i)) {
41
- for (const e of i) {
42
- const s = p(e);
43
- if (s) return s;
41
+ for (const t of i) {
42
+ const r = p(t);
43
+ if (r) return r;
44
44
  }
45
45
  return null;
46
46
  }
47
- const t = i;
48
- if (t["@type"] === "Product" || t["@type"] === "IndividualProduct") {
49
- const e = t.image;
50
- if (typeof e == "string") return e;
51
- if (Array.isArray(e) && typeof e[0] == "string") return e[0];
52
- if (e && typeof e == "object") {
53
- const s = e;
54
- if (typeof s.url == "string") return s.url;
55
- if (typeof s.contentUrl == "string") return s.contentUrl;
47
+ const e = i;
48
+ if (e["@type"] === "Product" || e["@type"] === "IndividualProduct") {
49
+ const t = e.image;
50
+ if (typeof t == "string") return t;
51
+ if (Array.isArray(t) && typeof t[0] == "string") return t[0];
52
+ if (t && typeof t == "object") {
53
+ const r = t;
54
+ if (typeof r.url == "string") return r.url;
55
+ if (typeof r.contentUrl == "string") return r.contentUrl;
56
56
  }
57
57
  }
58
- return Array.isArray(t["@graph"]) ? p(t["@graph"]) : null;
58
+ return Array.isArray(e["@graph"]) ? p(e["@graph"]) : null;
59
59
  }
60
60
  function g() {
61
61
  return `
@@ -442,7 +442,7 @@ const n = {
442
442
  };
443
443
  class b extends HTMLElement {
444
444
  constructor() {
445
- super(), this.apiClient = null, this.sseClient = null, this.sseUnsubscribe = null, this.state = "idle", this.selectedFile = null, this.previewUrl = null, this.resultImageUrl = null, this.errorMessage = null, this.currentJobId = null, this.productImageUrl = null, this.t = l(), this.buttonStyles = {}, this.modalStyles = {}, this.savedScrollY = 0, this.shadow = this.attachShadow({ mode: "open" });
445
+ super(), this.apiClient = null, this.sseClient = null, this.sseUnsubscribe = null, this.state = "idle", this.selectedFile = null, this.previewUrl = null, this.resultImageUrl = null, this.errorMessage = null, this.currentJobId = null, this.productImageUrl = null, this.productViewReportedFor = null, this.t = l(), this.buttonStyles = {}, this.modalStyles = {}, this.savedScrollY = 0, this.shadow = this.attachShadow({ mode: "open" });
446
446
  }
447
447
  static get observedAttributes() {
448
448
  return [
@@ -462,27 +462,27 @@ class b extends HTMLElement {
462
462
  disconnectedCallback() {
463
463
  this.cleanup();
464
464
  }
465
- attributeChangedCallback(t, e, s) {
466
- if ((t === "api-key" || t === "api-url") && this.initApi(), t === "locale" && (this.t = l(s || void 0)), t === "product-image" && (this.productImageUrl = s), t === "button-styles")
465
+ attributeChangedCallback(e, t, r) {
466
+ if ((e === "api-key" || e === "api-url") && this.initApi(), e === "locale" && (this.t = l(r || void 0)), e === "product-image" && (this.productImageUrl = r), e === "button-styles")
467
467
  try {
468
- this.buttonStyles = JSON.parse(s);
468
+ this.buttonStyles = JSON.parse(r);
469
469
  } catch {
470
470
  }
471
- if (t === "modal-styles")
471
+ if (e === "modal-styles")
472
472
  try {
473
- this.modalStyles = JSON.parse(s);
473
+ this.modalStyles = JSON.parse(r);
474
474
  } catch {
475
475
  }
476
476
  this.isConnected && this.render();
477
477
  }
478
478
  // ── Public API ──────────────────────────────
479
479
  /** Configure button appearance programmatically */
480
- setButtonStyles(t) {
481
- this.buttonStyles = { ...this.buttonStyles, ...t }, this.applyButtonStyles();
480
+ setButtonStyles(e) {
481
+ this.buttonStyles = { ...this.buttonStyles, ...e }, this.applyButtonStyles();
482
482
  }
483
483
  /** Configure modal appearance programmatically */
484
- setModalStyles(t) {
485
- this.modalStyles = { ...this.modalStyles, ...t }, this.applyModalStyles();
484
+ setModalStyles(e) {
485
+ this.modalStyles = { ...this.modalStyles, ...e }, this.applyModalStyles();
486
486
  }
487
487
  lockBodyScroll() {
488
488
  this.savedScrollY = window.scrollY, document.body.style.overflow = "hidden", document.body.style.position = "fixed", document.body.style.top = `-${this.savedScrollY}px`, document.body.style.left = "0", document.body.style.right = "0";
@@ -492,7 +492,7 @@ class b extends HTMLElement {
492
492
  }
493
493
  /** Open the try-on modal */
494
494
  open() {
495
- this.state = "upload", this.lockBodyScroll(), this.render(), this.emit("ps:open");
495
+ this.reportEvent("SDK_OPENED", { metadata: { component: "PrimeStyleTryonElement" } }), this.state = "upload", this.lockBodyScroll(), this.render(), this.emit("ps:open");
496
496
  }
497
497
  /** Close the try-on modal */
498
498
  close() {
@@ -500,38 +500,64 @@ class b extends HTMLElement {
500
500
  }
501
501
  /** Detect product image from the current page */
502
502
  detectProduct() {
503
- const t = d();
504
- return t && (this.productImageUrl = t, this.emit("ps:product-detected", { imageUrl: t })), t;
503
+ const e = d();
504
+ return e && (this.productImageUrl = e, this.emit("ps:product-detected", { imageUrl: e })), e;
505
505
  }
506
506
  // ── Private ─────────────────────────────────
507
507
  init() {
508
- const t = this.getAttribute("button-styles");
509
- if (t)
508
+ const e = this.getAttribute("button-styles");
509
+ if (e)
510
510
  try {
511
- this.buttonStyles = JSON.parse(t);
511
+ this.buttonStyles = JSON.parse(e);
512
512
  } catch {
513
513
  }
514
- const e = this.getAttribute("modal-styles");
515
- if (e)
514
+ const t = this.getAttribute("modal-styles");
515
+ if (t)
516
516
  try {
517
- this.modalStyles = JSON.parse(e);
517
+ this.modalStyles = JSON.parse(t);
518
518
  } catch {
519
519
  }
520
- const s = this.getAttribute("locale");
521
- s && (this.t = l(s)), this.productImageUrl = this.getAttribute("product-image") || null, this.productImageUrl || (this.productImageUrl = d(), this.productImageUrl && this.emit("ps:product-detected", { imageUrl: this.productImageUrl })), this.initApi();
520
+ const r = this.getAttribute("locale");
521
+ r && (this.t = l(r)), this.productImageUrl = this.getAttribute("product-image") || null, this.productImageUrl || (this.productImageUrl = d(), this.productImageUrl && this.emit("ps:product-detected", { imageUrl: this.productImageUrl })), this.initApi(), this.reportProductView();
522
522
  }
523
523
  initApi() {
524
- const t = this.getAttribute("api-key") || void 0, e = this.getAttribute("api-url") || void 0;
525
- this.apiClient = new c(t, e), this.sseClient = new h(this.apiClient.getStreamUrl());
524
+ const e = this.getAttribute("api-key") || void 0, t = this.getAttribute("api-url") || void 0;
525
+ this.apiClient = new c(e, t), this.sseClient = null;
526
526
  }
527
527
  cleanup() {
528
528
  this.state !== "idle" && this.unlockBodyScroll(), this.sseUnsubscribe && (this.sseUnsubscribe(), this.sseUnsubscribe = null), this.sseClient && (this.sseClient.disconnect(), this.sseClient = null), this.previewUrl && URL.revokeObjectURL(this.previewUrl);
529
529
  }
530
- emit(t, e) {
530
+ emit(e, t) {
531
531
  this.dispatchEvent(
532
- new CustomEvent(t, { bubbles: !0, composed: !0, detail: e })
532
+ new CustomEvent(e, { bubbles: !0, composed: !0, detail: t })
533
533
  );
534
534
  }
535
+ get eventProductContext() {
536
+ return {
537
+ productId: this.getAttribute("product-id") || this.productImageUrl || void 0,
538
+ productTitle: this.getAttribute("product-title") || document.title || void 0,
539
+ productUrl: typeof window < "u" ? window.location.href : void 0
540
+ };
541
+ }
542
+ reportProductView() {
543
+ const e = `${this.eventProductContext.productId || ""}|${this.eventProductContext.productUrl || ""}`;
544
+ !e.trim() || this.productViewReportedFor === e || (this.productViewReportedFor = e, this.reportEvent("PRODUCT_VIEW", { metadata: { component: "PrimeStyleTryonElement" } }));
545
+ }
546
+ reportEvent(e, t = {}) {
547
+ this.apiClient?.reportEvent({
548
+ eventType: e,
549
+ ...this.eventProductContext,
550
+ ...t
551
+ }).catch(() => {
552
+ });
553
+ }
554
+ reportClientError(e) {
555
+ this.apiClient?.reportClientError({
556
+ ...this.eventProductContext,
557
+ ...e
558
+ }).catch(() => {
559
+ });
560
+ }
535
561
  get buttonText() {
536
562
  return this.getAttribute("button-text") || this.t("Virtual Try-On");
537
563
  }
@@ -541,32 +567,32 @@ class b extends HTMLElement {
541
567
  // ── Rendering ───────────────────────────────
542
568
  render() {
543
569
  this.shadow.innerHTML = "";
544
- const t = document.createElement("style");
545
- t.textContent = g(), this.shadow.appendChild(t);
546
- const e = this.createButton();
547
- if (this.shadow.appendChild(e), this.state !== "idle") {
548
- const s = this.createModal();
549
- this.shadow.appendChild(s), requestAnimationFrame(() => s.classList.add("ps-open"));
570
+ const e = document.createElement("style");
571
+ e.textContent = g(), this.shadow.appendChild(e);
572
+ const t = this.createButton();
573
+ if (this.shadow.appendChild(t), this.state !== "idle") {
574
+ const r = this.createModal();
575
+ this.shadow.appendChild(r), requestAnimationFrame(() => r.classList.add("ps-open"));
550
576
  }
551
577
  this.applyButtonStyles(), this.applyModalStyles();
552
578
  }
553
579
  createButton() {
554
- const t = document.createElement("button");
555
- return t.className = "ps-button", t.innerHTML = `${n.camera}<span>${this.buttonText}</span>`, t.addEventListener("click", () => this.open()), t;
580
+ const e = document.createElement("button");
581
+ return e.className = "ps-button", e.innerHTML = `${n.camera}<span>${this.buttonText}</span>`, e.addEventListener("click", () => this.open()), e;
556
582
  }
557
583
  createModal() {
558
- const t = document.createElement("div");
559
- t.className = "ps-overlay", t.addEventListener("click", (a) => {
560
- a.target === t && this.close();
561
- });
562
584
  const e = document.createElement("div");
563
- e.className = "ps-modal";
564
- const s = document.createElement("div");
565
- s.className = "ps-header", s.innerHTML = `
585
+ e.className = "ps-overlay", e.addEventListener("click", (a) => {
586
+ a.target === e && this.close();
587
+ });
588
+ const t = document.createElement("div");
589
+ t.className = "ps-modal";
590
+ const r = document.createElement("div");
591
+ r.className = "ps-header", r.innerHTML = `
566
592
  <span class="ps-header-title">${this.t("Virtual Try-On")}</span>
567
593
  `;
568
- const r = document.createElement("button");
569
- r.className = "ps-close", r.innerHTML = n.x, r.addEventListener("click", () => this.close()), s.appendChild(r), e.appendChild(s);
594
+ const s = document.createElement("button");
595
+ s.className = "ps-close", s.innerHTML = n.x, s.addEventListener("click", () => this.close()), r.appendChild(s), t.appendChild(r);
570
596
  const o = document.createElement("div");
571
597
  switch (o.className = "ps-body", this.state) {
572
598
  case "upload":
@@ -582,160 +608,202 @@ class b extends HTMLElement {
582
608
  o.appendChild(this.createErrorView());
583
609
  break;
584
610
  }
585
- if (e.appendChild(o), this.showPoweredBy) {
611
+ if (t.appendChild(o), this.showPoweredBy) {
586
612
  const a = document.createElement("div");
587
- a.className = "ps-powered", a.innerHTML = `${this.t("Powered by")} <a href="https://myaifitting.com" target="_blank" rel="noopener">PrimeStyle AI</a>`, e.appendChild(a);
613
+ a.className = "ps-powered", a.innerHTML = `${this.t("Powered by")} <a href="https://myaifitting.com" target="_blank" rel="noopener">PrimeStyle AI</a>`, t.appendChild(a);
588
614
  }
589
- return t.appendChild(e), t;
615
+ return e.appendChild(t), e;
590
616
  }
591
617
  createUploadView() {
592
- const t = document.createDocumentFragment();
618
+ const e = document.createDocumentFragment();
593
619
  if (this.selectedFile && this.previewUrl) {
594
- const e = document.createElement("div");
595
- e.className = "ps-preview";
596
- const s = document.createElement("img");
597
- s.src = this.previewUrl, s.alt = this.t("Your photo"), e.appendChild(s);
598
- const r = document.createElement("button");
599
- r.className = "ps-preview-remove", r.textContent = "×", r.addEventListener("click", () => {
620
+ const t = document.createElement("div");
621
+ t.className = "ps-preview";
622
+ const r = document.createElement("img");
623
+ r.src = this.previewUrl, r.alt = this.t("Your photo"), t.appendChild(r);
624
+ const s = document.createElement("button");
625
+ s.className = "ps-preview-remove", s.textContent = "×", s.addEventListener("click", () => {
600
626
  this.resetUpload(), this.render();
601
- }), e.appendChild(r), t.appendChild(e);
627
+ }), t.appendChild(s), e.appendChild(t);
602
628
  const o = document.createElement("button");
603
- o.className = "ps-submit", o.textContent = this.t("Try It On"), o.addEventListener("click", () => this.handleSubmit()), t.appendChild(o);
629
+ o.className = "ps-submit", o.textContent = this.t("Try It On"), o.addEventListener("click", () => this.handleSubmit()), e.appendChild(o);
604
630
  } else {
605
- const e = document.createElement("div");
606
- e.className = "ps-upload-zone";
607
- const s = document.createElement("input");
608
- s.type = "file", s.accept = "image/jpeg,image/png,image/webp", s.addEventListener("change", (r) => {
609
- const o = r.target.files?.[0];
631
+ const t = document.createElement("div");
632
+ t.className = "ps-upload-zone";
633
+ const r = document.createElement("input");
634
+ r.type = "file", r.accept = "image/jpeg,image/png,image/webp", r.addEventListener("change", (s) => {
635
+ const o = s.target.files?.[0];
610
636
  o && this.handleFileSelect(o);
611
- }), e.innerHTML = `
637
+ }), t.innerHTML = `
612
638
  <svg class="ps-upload-icon" viewBox="0 0 24 24">${n.upload.replace(/<\/?svg[^>]*>/g, "")}</svg>
613
639
  <p class="ps-upload-text">${this.t("Drop your photo here or click to upload")}</p>
614
640
  <p class="ps-upload-hint">${this.t("JPEG, PNG or WebP (max 10MB)")}</p>
615
- `, e.appendChild(s), e.addEventListener("click", () => s.click()), e.addEventListener("dragover", (r) => {
616
- r.preventDefault(), e.classList.add("ps-drag-over");
617
- }), e.addEventListener("dragleave", () => {
618
- e.classList.remove("ps-drag-over");
619
- }), e.addEventListener("drop", (r) => {
620
- r.preventDefault(), e.classList.remove("ps-drag-over");
621
- const o = r.dataTransfer?.files?.[0];
641
+ `, t.appendChild(r), t.addEventListener("click", () => r.click()), t.addEventListener("dragover", (s) => {
642
+ s.preventDefault(), t.classList.add("ps-drag-over");
643
+ }), t.addEventListener("dragleave", () => {
644
+ t.classList.remove("ps-drag-over");
645
+ }), t.addEventListener("drop", (s) => {
646
+ s.preventDefault(), t.classList.remove("ps-drag-over");
647
+ const o = s.dataTransfer?.files?.[0];
622
648
  o && this.handleFileSelect(o);
623
- }), t.appendChild(e);
649
+ }), e.appendChild(t);
624
650
  }
625
- return t;
651
+ return e;
626
652
  }
627
653
  createProcessingView() {
628
- const t = document.createElement("div");
629
- return t.className = "ps-processing", t.innerHTML = `
654
+ const e = document.createElement("div");
655
+ return e.className = "ps-processing", e.innerHTML = `
630
656
  <div class="ps-spinner"></div>
631
657
  <p class="ps-processing-text">${this.t("Generating virtual try-on...")}</p>
632
658
  <p class="ps-processing-sub">${this.t("This usually takes 15-20 seconds")}</p>
633
- `, t;
659
+ `, e;
634
660
  }
635
661
  createResultView() {
636
- const t = document.createElement("div");
637
- if (t.className = "ps-result", this.resultImageUrl) {
662
+ const e = document.createElement("div");
663
+ if (e.className = "ps-result", this.resultImageUrl) {
638
664
  const o = document.createElement("img");
639
- o.src = this.resultImageUrl, o.alt = this.t("Try-on result"), t.appendChild(o);
665
+ o.src = this.resultImageUrl, o.alt = this.t("Try-on result"), e.appendChild(o);
640
666
  }
641
- const e = document.createElement("div");
642
- e.className = "ps-result-actions";
643
- const s = document.createElement("button");
644
- s.className = "ps-btn-download", s.textContent = this.t("Download"), s.addEventListener("click", () => this.handleDownload()), e.appendChild(s);
667
+ const t = document.createElement("div");
668
+ t.className = "ps-result-actions";
645
669
  const r = document.createElement("button");
646
- return r.className = "ps-btn-retry", r.textContent = this.t("Try Another"), r.addEventListener("click", () => {
670
+ r.className = "ps-btn-download", r.textContent = this.t("Download"), r.addEventListener("click", () => this.handleDownload()), t.appendChild(r);
671
+ const s = document.createElement("button");
672
+ return s.className = "ps-btn-retry", s.textContent = this.t("Try Another"), s.addEventListener("click", () => {
647
673
  this.resetUpload(), this.state = "upload", this.render();
648
- }), e.appendChild(r), t.appendChild(e), t;
674
+ }), t.appendChild(s), e.appendChild(t), e;
649
675
  }
650
676
  createErrorView() {
651
- const t = document.createElement("div");
652
- t.className = "ps-error", t.innerHTML = `
677
+ const e = document.createElement("div");
678
+ e.className = "ps-error", e.innerHTML = `
653
679
  <svg class="ps-error-icon" viewBox="0 0 24 24">${n.alert.replace(/<\/?svg[^>]*>/g, "")}</svg>
654
680
  <p class="ps-error-text">${this.errorMessage || this.t("Something went wrong")}</p>
655
681
  `;
656
- const e = document.createElement("button");
657
- return e.className = "ps-submit", e.textContent = this.t("Try Again"), e.addEventListener("click", () => {
682
+ const t = document.createElement("button");
683
+ return t.className = "ps-submit", t.textContent = this.t("Try Again"), t.addEventListener("click", () => {
658
684
  this.state = "upload", this.errorMessage = null, this.render();
659
- }), t.appendChild(e), t;
685
+ }), e.appendChild(t), e;
660
686
  }
661
687
  // ── Handlers ────────────────────────────────
662
- handleFileSelect(t) {
663
- if (!u(t)) {
664
- this.errorMessage = this.t("Please upload a JPEG, PNG, or WebP image."), this.state = "error", this.render();
688
+ handleFileSelect(e) {
689
+ if (!h(e)) {
690
+ this.errorMessage = this.t("Please upload a JPEG, PNG, or WebP image."), this.state = "error", this.reportClientError({
691
+ message: "Invalid image file type",
692
+ code: "INVALID_FILE",
693
+ component: "PrimeStyleTryonElement",
694
+ view: "upload",
695
+ severity: "low",
696
+ metadata: { fileType: e.type, fileSize: e.size }
697
+ }), this.render();
665
698
  return;
666
699
  }
667
- if (t.size > 10 * 1024 * 1024) {
668
- this.errorMessage = this.t("Image must be under 10MB."), this.state = "error", this.render();
700
+ if (e.size > 10 * 1024 * 1024) {
701
+ this.errorMessage = this.t("Image must be under 10MB."), this.state = "error", this.reportClientError({
702
+ message: "Image file too large",
703
+ code: "FILE_TOO_LARGE",
704
+ component: "PrimeStyleTryonElement",
705
+ view: "upload",
706
+ severity: "low",
707
+ metadata: { fileType: e.type, fileSize: e.size }
708
+ }), this.render();
669
709
  return;
670
710
  }
671
- this.selectedFile = t, this.previewUrl = URL.createObjectURL(t), this.emit("ps:upload", { file: t }), this.render();
711
+ this.selectedFile = e, this.previewUrl = URL.createObjectURL(e), this.reportEvent("PHOTO_UPLOADED", {
712
+ metadata: { fileType: e.type, fileSize: e.size, component: "PrimeStyleTryonElement" }
713
+ }), this.emit("ps:upload", { file: e }), this.render();
672
714
  }
673
715
  async handleSubmit() {
674
- if (!this.selectedFile || !this.apiClient || !this.sseClient) {
675
- this.errorMessage = this.t("SDK not configured. Please provide an API key."), this.state = "error", this.render();
716
+ if (!this.selectedFile || !this.apiClient) {
717
+ this.errorMessage = this.t("SDK not configured. Please provide an API key."), this.state = "error", this.reportClientError({
718
+ message: this.errorMessage,
719
+ code: this.apiClient ? "PHOTO_MISSING" : "SDK_NOT_CONFIGURED",
720
+ component: "PrimeStyleTryonElement",
721
+ view: "upload",
722
+ severity: this.apiClient ? "low" : "high"
723
+ }), this.render();
676
724
  return;
677
725
  }
678
726
  if (!this.productImageUrl) {
679
- this.errorMessage = this.t("No product image found. Please set the product-image attribute."), this.state = "error", this.render();
727
+ this.errorMessage = this.t("No product image found. Please set the product-image attribute."), this.state = "error", this.reportClientError({
728
+ message: this.errorMessage,
729
+ code: "PRODUCT_IMAGE_MISSING",
730
+ component: "PrimeStyleTryonElement",
731
+ view: "upload",
732
+ severity: "medium"
733
+ }), this.render();
680
734
  return;
681
735
  }
682
736
  this.state = "processing", this.render();
683
737
  try {
684
- const t = await m(this.selectedFile), e = await this.apiClient.submitTryOn(
685
- t,
738
+ const e = await u(this.selectedFile), t = await this.apiClient.submitTryOn(
739
+ e,
686
740
  this.productImageUrl
687
741
  );
688
- this.currentJobId = e.jobId, this.emit("ps:processing", { jobId: e.jobId }), this.sseUnsubscribe = this.sseClient.onJob(
689
- e.jobId,
690
- (s) => this.handleVtoUpdate(s)
691
- ), this.startPolling(e.jobId);
692
- } catch (t) {
693
- const e = t instanceof Error ? t.message : this.t("Failed to start try-on");
694
- this.errorMessage = e, this.state = "error", this.emit("ps:error", { message: e, code: t?.code }), this.render();
695
- }
696
- }
697
- handleVtoUpdate(t) {
698
- t.status === "completed" && t.imageUrl ? (this.state !== "result" || this.resultImageUrl?.startsWith("data:") && !t.imageUrl.startsWith("data:")) && (this.resultImageUrl = t.imageUrl, this.state = "result", this.emit("ps:complete", {
699
- jobId: t.galleryId,
700
- imageUrl: t.imageUrl
701
- }), this.render()) : t.status === "failed" && (this.errorMessage = t.error || this.t("Try-on generation failed"), this.state = "error", this.emit("ps:error", { message: this.errorMessage }), this.render());
702
- }
703
- startPolling(t) {
704
- let e = 0;
705
- const s = 60, r = setInterval(async () => {
706
- if (e++, e > s || this.state === "result" || this.state === "idle") {
707
- clearInterval(r);
742
+ this.currentJobId = t.jobId, this.emit("ps:processing", { jobId: t.jobId }), this.sseClient?.disconnect(), this.sseClient = new m(t.streamUrl || this.apiClient.getStreamUrl(t.jobId)), this.sseUnsubscribe = this.sseClient.onJob(
743
+ t.jobId,
744
+ (r) => this.handleVtoUpdate(r)
745
+ ), this.startPolling(t.jobId);
746
+ } catch (e) {
747
+ const t = e instanceof Error ? e.message : this.t("Failed to start try-on");
748
+ this.errorMessage = t, this.state = "error", this.reportClientError({
749
+ message: t,
750
+ code: e?.code || "TRYON_SUBMIT_FAILED",
751
+ stack: e instanceof Error ? e.stack : void 0,
752
+ component: "PrimeStyleTryonElement",
753
+ view: "processing",
754
+ severity: "medium"
755
+ }), this.emit("ps:error", { message: t, code: e?.code }), this.render();
756
+ }
757
+ }
758
+ handleVtoUpdate(e) {
759
+ e.status === "completed" && e.imageUrl ? (this.state !== "result" || this.resultImageUrl?.startsWith("data:") && !e.imageUrl.startsWith("data:")) && (this.resultImageUrl = e.imageUrl, this.state = "result", this.emit("ps:complete", {
760
+ jobId: e.galleryId,
761
+ imageUrl: e.imageUrl
762
+ }), this.render()) : e.status === "failed" && (this.errorMessage = e.error || this.t("Try-on generation failed"), this.state = "error", this.reportClientError({
763
+ message: this.errorMessage,
764
+ code: "TRYON_GENERATION_FAILED",
765
+ component: "PrimeStyleTryonElement",
766
+ view: "processing",
767
+ severity: "medium",
768
+ jobId: e.galleryId
769
+ }), this.emit("ps:error", { message: this.errorMessage }), this.render());
770
+ }
771
+ startPolling(e) {
772
+ let t = 0;
773
+ const r = 60, s = setInterval(async () => {
774
+ if (t++, t > r || this.state === "result" || this.state === "idle") {
775
+ clearInterval(s);
708
776
  return;
709
777
  }
710
778
  if (!this.apiClient) {
711
- clearInterval(r);
779
+ clearInterval(s);
712
780
  return;
713
781
  }
714
782
  try {
715
- const o = await this.apiClient.getStatus(t);
783
+ const o = await this.apiClient.getStatus(e);
716
784
  o.status === "completed" && o.imageUrl ? (this.state === "processing" && this.handleVtoUpdate({
717
- galleryId: t,
785
+ galleryId: e,
718
786
  status: "completed",
719
787
  imageUrl: o.imageUrl,
720
788
  error: null,
721
789
  timestamp: Date.now()
722
- }), clearInterval(r)) : o.status === "failed" && (this.state === "processing" && this.handleVtoUpdate({
723
- galleryId: t,
790
+ }), clearInterval(s)) : o.status === "failed" && (this.state === "processing" && this.handleVtoUpdate({
791
+ galleryId: e,
724
792
  status: "failed",
725
793
  imageUrl: null,
726
794
  error: o.message,
727
795
  timestamp: Date.now()
728
- }), clearInterval(r));
796
+ }), clearInterval(s));
729
797
  } catch {
730
798
  }
731
799
  }, 2e3);
732
800
  }
733
801
  handleDownload() {
734
802
  if (!this.resultImageUrl) return;
735
- const t = document.createElement("a");
736
- t.href = this.resultImageUrl, t.download = `primestyle-tryon-${Date.now()}.png`, t.target = "_blank", this.resultImageUrl.startsWith("data:") ? t.click() : fetch(this.resultImageUrl).then((e) => e.blob()).then((e) => {
737
- const s = URL.createObjectURL(e);
738
- t.href = s, t.click(), setTimeout(() => URL.revokeObjectURL(s), 100);
803
+ const e = document.createElement("a");
804
+ e.href = this.resultImageUrl, e.download = `primestyle-tryon-${Date.now()}.png`, e.target = "_blank", this.resultImageUrl.startsWith("data:") ? e.click() : fetch(this.resultImageUrl).then((t) => t.blob()).then((t) => {
805
+ const r = URL.createObjectURL(t);
806
+ e.href = r, e.click(), setTimeout(() => URL.revokeObjectURL(r), 100);
739
807
  }).catch(() => {
740
808
  window.open(this.resultImageUrl, "_blank");
741
809
  });
@@ -746,7 +814,7 @@ class b extends HTMLElement {
746
814
  // ── Custom Style Application ────────────────
747
815
  applyButtonStyles() {
748
816
  if (!this.shadow.querySelector(".ps-button")) return;
749
- const e = {
817
+ const t = {
750
818
  backgroundColor: "--ps-btn-bg",
751
819
  textColor: "--ps-btn-color",
752
820
  borderRadius: "--ps-btn-radius",
@@ -770,13 +838,13 @@ class b extends HTMLElement {
770
838
  iconColor: "--ps-btn-icon-color",
771
839
  boxShadow: "--ps-btn-shadow"
772
840
  };
773
- for (const [s, r] of Object.entries(e)) {
774
- const o = this.buttonStyles[s];
775
- o && this.style.setProperty(r, o);
841
+ for (const [r, s] of Object.entries(t)) {
842
+ const o = this.buttonStyles[r];
843
+ o && this.style.setProperty(s, o);
776
844
  }
777
845
  }
778
846
  applyModalStyles() {
779
- const t = {
847
+ const e = {
780
848
  overlayColor: "--ps-modal-overlay",
781
849
  backgroundColor: "--ps-modal-bg",
782
850
  textColor: "--ps-modal-color",
@@ -808,9 +876,9 @@ class b extends HTMLElement {
808
876
  successColor: "--ps-success-color",
809
877
  logoHeight: "--ps-logo-height"
810
878
  };
811
- for (const [e, s] of Object.entries(t)) {
812
- const r = this.modalStyles[e];
813
- r && this.style.setProperty(s, r);
879
+ for (const [t, r] of Object.entries(e)) {
880
+ const s = this.modalStyles[t];
881
+ s && this.style.setProperty(r, s);
814
882
  }
815
883
  }
816
884
  }
@@ -820,14 +888,14 @@ export {
820
888
  x as PrimeStyleError,
821
889
  b as PrimeStyleTryon,
822
890
  w as SUPPORTED_LOCALES,
823
- h as SseClient,
891
+ m as SseClient,
824
892
  C as TRANSLATION_KEYS,
825
- k as checkAgeBeforeUpload,
826
- m as compressImage,
893
+ S as checkAgeBeforeUpload,
894
+ u as compressImage,
827
895
  l as createT,
828
- U as detectLanguage,
896
+ E as detectLanguage,
829
897
  d as detectProductImage,
830
- u as isValidImageFile,
831
- S as registerLocale
898
+ h as isValidImageFile,
899
+ U as registerLocale
832
900
  };
833
901
  //# sourceMappingURL=primestyle-tryon.js.map