@vio-live/web-sdk 0.9.1 → 0.11.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/{chunk-WKJRYYNI.js → chunk-U2QG4IVJ.js} +306 -20
- package/dist/chunk-U2QG4IVJ.js.map +1 -0
- package/dist/{chunk-PRMVVF5C.js → chunk-XU5LGUBU.js} +4 -3
- package/dist/chunk-XU5LGUBU.js.map +1 -0
- package/dist/core/index.d.ts +74 -2
- package/dist/core/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/react/index.js +3 -3
- package/dist/ui/index.js +3 -3
- package/package.json +2 -2
- package/dist/chunk-PRMVVF5C.js.map +0 -1
- package/dist/chunk-WKJRYYNI.js.map +0 -1
|
@@ -1805,6 +1805,23 @@ var CartManager = class extends EventTarget {
|
|
|
1805
1805
|
const targetItemId = item.cartItemId;
|
|
1806
1806
|
if (quantity <= 0) {
|
|
1807
1807
|
cart.items = cart.items.filter((i) => i !== item);
|
|
1808
|
+
if (typeof document !== "undefined") {
|
|
1809
|
+
document.dispatchEvent(
|
|
1810
|
+
new CustomEvent("vio:removed-from-cart", {
|
|
1811
|
+
bubbles: true,
|
|
1812
|
+
detail: {
|
|
1813
|
+
productId: item.productId,
|
|
1814
|
+
variantId: item.variantId,
|
|
1815
|
+
name: item.name,
|
|
1816
|
+
brand: item.brand,
|
|
1817
|
+
price: item.unitPrice,
|
|
1818
|
+
quantity: item.quantity,
|
|
1819
|
+
currency: item.currency,
|
|
1820
|
+
sponsorId
|
|
1821
|
+
}
|
|
1822
|
+
})
|
|
1823
|
+
);
|
|
1824
|
+
}
|
|
1808
1825
|
} else {
|
|
1809
1826
|
item.quantity = quantity;
|
|
1810
1827
|
}
|
|
@@ -2554,10 +2571,33 @@ function renderKustomSnippet(container, htmlSnippet) {
|
|
|
2554
2571
|
}
|
|
2555
2572
|
|
|
2556
2573
|
// src/core/checkout/payments/qliro.ts
|
|
2574
|
+
function readVioTheme() {
|
|
2575
|
+
if (typeof globalThis === "undefined") return void 0;
|
|
2576
|
+
const doc = globalThis.document;
|
|
2577
|
+
const getComputed = globalThis.getComputedStyle;
|
|
2578
|
+
if (!doc?.documentElement || typeof getComputed !== "function") return void 0;
|
|
2579
|
+
let style;
|
|
2580
|
+
try {
|
|
2581
|
+
style = getComputed(doc.documentElement);
|
|
2582
|
+
} catch {
|
|
2583
|
+
return void 0;
|
|
2584
|
+
}
|
|
2585
|
+
const read = (name) => {
|
|
2586
|
+
const value = style?.getPropertyValue?.(name)?.trim();
|
|
2587
|
+
return value || void 0;
|
|
2588
|
+
};
|
|
2589
|
+
const theme = {
|
|
2590
|
+
accent: read("--vio-color-accent"),
|
|
2591
|
+
surface: read("--vio-color-surface"),
|
|
2592
|
+
radiusMd: read("--vio-radius-md"),
|
|
2593
|
+
radiusLg: read("--vio-radius-lg")
|
|
2594
|
+
};
|
|
2595
|
+
return Object.values(theme).some(Boolean) ? theme : void 0;
|
|
2596
|
+
}
|
|
2557
2597
|
var CREATE_PAYMENT_QLIRO_MUTATION = `
|
|
2558
|
-
mutation CreatePaymentQliro($checkoutId: String!, $countryCode: String!, $href: String!, $email: String) {
|
|
2598
|
+
mutation CreatePaymentQliro($checkoutId: String!, $countryCode: String!, $href: String!, $email: String, $theme: QliroThemeInput) {
|
|
2559
2599
|
Payment {
|
|
2560
|
-
CreatePaymentQliro(checkout_id: $checkoutId, country_code: $countryCode, href: $href, email: $email) {
|
|
2600
|
+
CreatePaymentQliro(checkout_id: $checkoutId, country_code: $countryCode, href: $href, email: $email, theme: $theme) {
|
|
2561
2601
|
order_id
|
|
2562
2602
|
status
|
|
2563
2603
|
html_snippet
|
|
@@ -2591,6 +2631,139 @@ async function getQliroOrder(checkoutId, options) {
|
|
|
2591
2631
|
return json?.data?.Payment?.GetQliroOrder ?? null;
|
|
2592
2632
|
}
|
|
2593
2633
|
|
|
2634
|
+
// src/core/checkout/payments/qliro-sync.ts
|
|
2635
|
+
var SYNC_PAYMENT_QLIRO_MUTATION = `
|
|
2636
|
+
mutation SyncPaymentQliro($checkoutId: String!) {
|
|
2637
|
+
Payment {
|
|
2638
|
+
SyncPaymentQliro(checkout_id: $checkoutId) {
|
|
2639
|
+
order_id
|
|
2640
|
+
update_version
|
|
2641
|
+
total_price
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
`;
|
|
2646
|
+
async function syncPaymentQliro(checkoutId, options) {
|
|
2647
|
+
const json = await executeCartGraphQL(SYNC_PAYMENT_QLIRO_MUTATION, { checkoutId }, options);
|
|
2648
|
+
return json?.data?.Payment?.SyncPaymentQliro ?? null;
|
|
2649
|
+
}
|
|
2650
|
+
var DEFAULT_UNLOCK_TIMEOUT_MS = 15e3;
|
|
2651
|
+
function installQliroListeners(options) {
|
|
2652
|
+
const { checkoutId, queryOptions, onEvent } = options;
|
|
2653
|
+
const unlockTimeoutMs = options.unlockTimeoutMs ?? DEFAULT_UNLOCK_TIMEOUT_MS;
|
|
2654
|
+
const win = globalThis;
|
|
2655
|
+
let q1 = null;
|
|
2656
|
+
let destroyed = false;
|
|
2657
|
+
let pending = null;
|
|
2658
|
+
const emit = (event) => {
|
|
2659
|
+
try {
|
|
2660
|
+
onEvent?.(event);
|
|
2661
|
+
} catch {
|
|
2662
|
+
}
|
|
2663
|
+
};
|
|
2664
|
+
const settle = () => {
|
|
2665
|
+
if (!pending) return;
|
|
2666
|
+
clearTimeout(pending.timer);
|
|
2667
|
+
const { resolve } = pending;
|
|
2668
|
+
pending = null;
|
|
2669
|
+
try {
|
|
2670
|
+
q1?.unlock();
|
|
2671
|
+
} catch {
|
|
2672
|
+
}
|
|
2673
|
+
resolve();
|
|
2674
|
+
};
|
|
2675
|
+
const acknowledges = (echo, version) => {
|
|
2676
|
+
if (version === null) return false;
|
|
2677
|
+
return !echo || echo === version;
|
|
2678
|
+
};
|
|
2679
|
+
const settleIfAcknowledged = () => {
|
|
2680
|
+
if (!pending) return;
|
|
2681
|
+
if (pending.echoes.some((echo) => acknowledges(echo, pending.version))) {
|
|
2682
|
+
settle();
|
|
2683
|
+
}
|
|
2684
|
+
};
|
|
2685
|
+
const previousQ1Ready = win.q1Ready;
|
|
2686
|
+
win.q1Ready = (instance) => {
|
|
2687
|
+
try {
|
|
2688
|
+
previousQ1Ready?.(instance);
|
|
2689
|
+
} catch {
|
|
2690
|
+
}
|
|
2691
|
+
if (destroyed) return;
|
|
2692
|
+
q1 = instance;
|
|
2693
|
+
instance.onCheckoutLoaded(() => emit({ type: "loaded" }));
|
|
2694
|
+
instance.onOrderUpdated((order) => {
|
|
2695
|
+
if (!pending) return;
|
|
2696
|
+
const echoed = order?.merchantUpdateVersion ?? order?.MerchantUpdateVersion ?? null;
|
|
2697
|
+
pending.echoes.push(echoed);
|
|
2698
|
+
settleIfAcknowledged();
|
|
2699
|
+
});
|
|
2700
|
+
instance.onShippingMethodChanged(
|
|
2701
|
+
(shipping) => emit({ type: "shipping-changed", shipping })
|
|
2702
|
+
);
|
|
2703
|
+
instance.onShippingPriceChanged(
|
|
2704
|
+
(price, totalPrice) => emit({ type: "shipping-price-changed", price, totalPrice })
|
|
2705
|
+
);
|
|
2706
|
+
instance.onCustomerInfoChanged(
|
|
2707
|
+
(customer) => emit({ type: "customer-changed", customer })
|
|
2708
|
+
);
|
|
2709
|
+
instance.onPaymentMethodChanged(
|
|
2710
|
+
(paymentMethod) => emit({ type: "payment-method-changed", paymentMethod })
|
|
2711
|
+
);
|
|
2712
|
+
instance.onPaymentDeclined(
|
|
2713
|
+
(reason, message) => emit({ type: "payment-declined", reason, message })
|
|
2714
|
+
);
|
|
2715
|
+
instance.onSessionExpired(() => {
|
|
2716
|
+
emit({ type: "session-expired" });
|
|
2717
|
+
void controller.sync();
|
|
2718
|
+
});
|
|
2719
|
+
};
|
|
2720
|
+
const controller = {
|
|
2721
|
+
async sync() {
|
|
2722
|
+
if (destroyed) return null;
|
|
2723
|
+
if (pending) settle();
|
|
2724
|
+
try {
|
|
2725
|
+
q1?.lock();
|
|
2726
|
+
} catch {
|
|
2727
|
+
}
|
|
2728
|
+
const settled = new Promise((resolve) => {
|
|
2729
|
+
pending = {
|
|
2730
|
+
version: null,
|
|
2731
|
+
echoes: [],
|
|
2732
|
+
resolve,
|
|
2733
|
+
timer: setTimeout(settle, unlockTimeoutMs)
|
|
2734
|
+
};
|
|
2735
|
+
});
|
|
2736
|
+
let result = null;
|
|
2737
|
+
try {
|
|
2738
|
+
result = await syncPaymentQliro(checkoutId, queryOptions);
|
|
2739
|
+
} catch (error) {
|
|
2740
|
+
emit({ type: "sync-failed", error });
|
|
2741
|
+
settle();
|
|
2742
|
+
await settled;
|
|
2743
|
+
return null;
|
|
2744
|
+
}
|
|
2745
|
+
if (destroyed || !result?.update_version || !q1) {
|
|
2746
|
+
settle();
|
|
2747
|
+
await settled;
|
|
2748
|
+
return result;
|
|
2749
|
+
}
|
|
2750
|
+
if (pending) {
|
|
2751
|
+
pending.version = result.update_version;
|
|
2752
|
+
settleIfAcknowledged();
|
|
2753
|
+
}
|
|
2754
|
+
await settled;
|
|
2755
|
+
return result;
|
|
2756
|
+
},
|
|
2757
|
+
destroy() {
|
|
2758
|
+
destroyed = true;
|
|
2759
|
+
settle();
|
|
2760
|
+
if (win.q1Ready) win.q1Ready = previousQ1Ready;
|
|
2761
|
+
q1 = null;
|
|
2762
|
+
}
|
|
2763
|
+
};
|
|
2764
|
+
return controller;
|
|
2765
|
+
}
|
|
2766
|
+
|
|
2594
2767
|
// src/core/checkout/payments/walley.ts
|
|
2595
2768
|
var CREATE_PAYMENT_WALLEY_MUTATION = `
|
|
2596
2769
|
mutation CreatePaymentWalley($checkoutId: String!, $countryCode: String!, $href: String!, $email: String) {
|
|
@@ -2866,6 +3039,8 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
2866
3039
|
this.applePayPublishableKey = null;
|
|
2867
3040
|
this.applePayConnectedAccount = null;
|
|
2868
3041
|
this.klarnaAvailableCache = null;
|
|
3042
|
+
/** Live q1 listeners while a Qliro widget is mounted. */
|
|
3043
|
+
this.qliroController = null;
|
|
2869
3044
|
this.klarnaOrderInFlight = false;
|
|
2870
3045
|
/** Last backend shippings fetched (per-supplier), for UI reuse. */
|
|
2871
3046
|
this.lastFetchedShippings = [];
|
|
@@ -3275,16 +3450,56 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
3275
3450
|
checkoutId,
|
|
3276
3451
|
countryCode: getGlobalCountryCode(),
|
|
3277
3452
|
href,
|
|
3278
|
-
email: this.state?.address?.email || void 0
|
|
3453
|
+
email: this.state?.address?.email || void 0,
|
|
3454
|
+
// Qliro cannot be restyled once rendered, so the host page's theme has
|
|
3455
|
+
// to travel with the order.
|
|
3456
|
+
theme: readVioTheme()
|
|
3279
3457
|
},
|
|
3280
3458
|
opts
|
|
3281
3459
|
);
|
|
3282
3460
|
if (!order?.html_snippet) {
|
|
3283
3461
|
throw new Error("Qliro order creation failed: missing html_snippet");
|
|
3284
3462
|
}
|
|
3463
|
+
this.qliroController?.destroy();
|
|
3464
|
+
this.qliroController = installQliroListeners({
|
|
3465
|
+
checkoutId,
|
|
3466
|
+
queryOptions: opts,
|
|
3467
|
+
onEvent: (event) => this.onQliroEvent(event)
|
|
3468
|
+
});
|
|
3285
3469
|
renderKustomSnippet(container, order.html_snippet);
|
|
3286
3470
|
return order;
|
|
3287
3471
|
}
|
|
3472
|
+
/**
|
|
3473
|
+
* Everything the customer does inside the Qliro iframe, re-published as a
|
|
3474
|
+
* DOM event so a host page can follow a checkout it cannot see into.
|
|
3475
|
+
*/
|
|
3476
|
+
onQliroEvent(event) {
|
|
3477
|
+
this.dispatchEvent(
|
|
3478
|
+
new CustomEvent("qliro-event", {
|
|
3479
|
+
detail: event,
|
|
3480
|
+
bubbles: true,
|
|
3481
|
+
composed: true
|
|
3482
|
+
})
|
|
3483
|
+
);
|
|
3484
|
+
if (event.type === "shipping-changed" || event.type === "shipping-price-changed") {
|
|
3485
|
+
this.emit();
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
/**
|
|
3489
|
+
* Push the current cart onto the open Qliro order.
|
|
3490
|
+
*
|
|
3491
|
+
* Call it after changing the cart while the widget is open: it holds
|
|
3492
|
+
* `q1.lock()` across the round trip and unlocks once Qliro confirms it is
|
|
3493
|
+
* showing the new version. A no-op when no Qliro widget is mounted.
|
|
3494
|
+
*/
|
|
3495
|
+
async syncQliroOrder() {
|
|
3496
|
+
return await this.qliroController?.sync() ?? null;
|
|
3497
|
+
}
|
|
3498
|
+
/** Drop the Qliro listeners and release any lock still held. */
|
|
3499
|
+
destroyQliroListeners() {
|
|
3500
|
+
this.qliroController?.destroy();
|
|
3501
|
+
this.qliroController = null;
|
|
3502
|
+
}
|
|
3288
3503
|
/** Re-read the Qliro order owned by a checkout — the confirmation trip. */
|
|
3289
3504
|
async getQliroOrder(checkoutId, sponsorId) {
|
|
3290
3505
|
const opts = await getCartGraphQLOptions(sponsorId ?? this.state?.sponsorId);
|
|
@@ -4154,7 +4369,7 @@ function toSmallestUnit(amount, currency) {
|
|
|
4154
4369
|
}
|
|
4155
4370
|
|
|
4156
4371
|
// src/core/version.ts
|
|
4157
|
-
var SDK_VERSION = "0.
|
|
4372
|
+
var SDK_VERSION = "0.11.0";
|
|
4158
4373
|
|
|
4159
4374
|
// src/core/analytics/analytics-manager.ts
|
|
4160
4375
|
var SESSION_TTL_MS = 30 * 60 * 1e3;
|
|
@@ -4176,6 +4391,9 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
4176
4391
|
this.retryAttempt = 0;
|
|
4177
4392
|
this.retryNotBefore = 0;
|
|
4178
4393
|
this.sessionId = null;
|
|
4394
|
+
this.requireConsent = false;
|
|
4395
|
+
this.consentGranted = false;
|
|
4396
|
+
this.anonIdCache = null;
|
|
4179
4397
|
/** Set via start({ sessionId }) — the host owns the session, we follow. */
|
|
4180
4398
|
this.externalSessionId = null;
|
|
4181
4399
|
this.sessionStartedAt = 0;
|
|
@@ -4191,7 +4409,29 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
4191
4409
|
* Install listeners + begin flushing. Explicit on purpose (no module
|
|
4192
4410
|
* side-effects). Safe to call twice (second call only updates options).
|
|
4193
4411
|
*/
|
|
4412
|
+
/**
|
|
4413
|
+
* Consentimiento (ePrivacy/GDPR). Por defecto el SDK asume que el host ya
|
|
4414
|
+
* lo gestionó — su CMP decide si nos carga. Con `requireConsent: true`
|
|
4415
|
+
* arranca en modo **cookieless**: mide la visita con ids efímeros en
|
|
4416
|
+
* memoria y NO escribe nada en localStorage hasta que el host llame
|
|
4417
|
+
* `setConsent(true)`. Retirarlo borra lo persistido.
|
|
4418
|
+
*/
|
|
4419
|
+
setConsent(granted) {
|
|
4420
|
+
this.consentGranted = granted;
|
|
4421
|
+
if (granted) {
|
|
4422
|
+
if (this.anonIdCache) safeStorageSet(ANON_KEY, this.anonIdCache);
|
|
4423
|
+
if (this.sessionId) this.persistSession();
|
|
4424
|
+
return;
|
|
4425
|
+
}
|
|
4426
|
+
safeStorageRemove(ANON_KEY);
|
|
4427
|
+
safeStorageRemove(SESSION_KEY);
|
|
4428
|
+
}
|
|
4429
|
+
/** ¿Podemos escribir en el dispositivo? */
|
|
4430
|
+
get canPersist() {
|
|
4431
|
+
return !this.requireConsent || this.consentGranted;
|
|
4432
|
+
}
|
|
4194
4433
|
start(options = {}) {
|
|
4434
|
+
this.requireConsent = options.requireConsent === true;
|
|
4195
4435
|
this.options = {
|
|
4196
4436
|
host: options.host ?? this.options.host,
|
|
4197
4437
|
collector: options.collector ?? this.options.collector,
|
|
@@ -4341,6 +4581,7 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
4341
4581
|
content_id: ctx.contentId,
|
|
4342
4582
|
// Deletion-proof reporting: sources have no trash bin — the title
|
|
4343
4583
|
// snapshotted at event time keeps reports legible if content dies.
|
|
4584
|
+
error_code: ctx.errorCode,
|
|
4344
4585
|
content_title: ctx.contentTitle ?? (typeof document !== "undefined" && document.title ? document.title.slice(0, 255) : void 0),
|
|
4345
4586
|
variant: ctx.variant
|
|
4346
4587
|
});
|
|
@@ -4376,18 +4617,35 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
4376
4617
|
...opts.props ? { props: opts.props } : {}
|
|
4377
4618
|
};
|
|
4378
4619
|
}
|
|
4620
|
+
/** Guarda la sesión solo si podemos escribir en el dispositivo. */
|
|
4621
|
+
persistSession(now = Date.now()) {
|
|
4622
|
+
if (!this.canPersist || !this.sessionId) return;
|
|
4623
|
+
safeStorageSet(
|
|
4624
|
+
SESSION_KEY,
|
|
4625
|
+
JSON.stringify({
|
|
4626
|
+
id: this.sessionId,
|
|
4627
|
+
ts: now,
|
|
4628
|
+
startedAt: this.sessionStartedAt ?? now
|
|
4629
|
+
})
|
|
4630
|
+
);
|
|
4631
|
+
}
|
|
4379
4632
|
anonId() {
|
|
4380
|
-
|
|
4381
|
-
|
|
4633
|
+
if (this.anonIdCache) return this.anonIdCache;
|
|
4634
|
+
const stored = this.canPersist ? safeStorageGet(ANON_KEY) : null;
|
|
4635
|
+
if (stored) {
|
|
4636
|
+
this.anonIdCache = stored;
|
|
4637
|
+
return stored;
|
|
4638
|
+
}
|
|
4382
4639
|
const id = `a-${uuid()}`;
|
|
4383
|
-
safeStorageSet(ANON_KEY, id);
|
|
4384
|
-
|
|
4640
|
+
if (this.canPersist) safeStorageSet(ANON_KEY, id);
|
|
4641
|
+
this.anonIdCache = (this.canPersist ? safeStorageGet(ANON_KEY) : null) ?? id;
|
|
4642
|
+
return this.anonIdCache;
|
|
4385
4643
|
}
|
|
4386
4644
|
/** Rolling session: renewed by activity, rotated after 30 min idle. */
|
|
4387
4645
|
ensureSession() {
|
|
4388
4646
|
const now = Date.now();
|
|
4389
4647
|
if (!this.sessionId) {
|
|
4390
|
-
const stored = safeStorageGet(SESSION_KEY);
|
|
4648
|
+
const stored = this.canPersist ? safeStorageGet(SESSION_KEY) : null;
|
|
4391
4649
|
if (stored) {
|
|
4392
4650
|
try {
|
|
4393
4651
|
const parsed = JSON.parse(stored);
|
|
@@ -4399,7 +4657,7 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
4399
4657
|
}
|
|
4400
4658
|
}
|
|
4401
4659
|
} else {
|
|
4402
|
-
const stored = safeStorageGet(SESSION_KEY);
|
|
4660
|
+
const stored = this.canPersist ? safeStorageGet(SESSION_KEY) : null;
|
|
4403
4661
|
if (stored) {
|
|
4404
4662
|
try {
|
|
4405
4663
|
if (now - JSON.parse(stored).ts >= SESSION_TTL_MS) {
|
|
@@ -4421,16 +4679,10 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
4421
4679
|
this.sessionId = `s-${uuid()}`;
|
|
4422
4680
|
this.sessionStartedAt = now;
|
|
4423
4681
|
this.impressedComponents.clear();
|
|
4424
|
-
|
|
4425
|
-
SESSION_KEY,
|
|
4426
|
-
JSON.stringify({ id: this.sessionId, ts: now, startedAt: now })
|
|
4427
|
-
);
|
|
4682
|
+
this.persistSession(now);
|
|
4428
4683
|
this.track("session_start");
|
|
4429
4684
|
} else {
|
|
4430
|
-
|
|
4431
|
-
SESSION_KEY,
|
|
4432
|
-
JSON.stringify({ id: this.sessionId, ts: now, startedAt: this.sessionStartedAt })
|
|
4433
|
-
);
|
|
4685
|
+
this.persistSession(now);
|
|
4434
4686
|
}
|
|
4435
4687
|
}
|
|
4436
4688
|
trackSessionEnd() {
|
|
@@ -4495,6 +4747,34 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
4495
4747
|
}
|
|
4496
4748
|
});
|
|
4497
4749
|
});
|
|
4750
|
+
on("vio:removed-from-cart", (ev) => {
|
|
4751
|
+
const d = ev.detail ?? {};
|
|
4752
|
+
if (d.productId === void 0) return;
|
|
4753
|
+
this.track("remove_from_cart", {
|
|
4754
|
+
context: { sponsorId: d.sponsorId },
|
|
4755
|
+
commerce: {
|
|
4756
|
+
items: [
|
|
4757
|
+
{
|
|
4758
|
+
productId: d.productId,
|
|
4759
|
+
variantId: d.variantId,
|
|
4760
|
+
name: d.name,
|
|
4761
|
+
brand: d.brand,
|
|
4762
|
+
price: d.price,
|
|
4763
|
+
quantity: d.quantity
|
|
4764
|
+
}
|
|
4765
|
+
],
|
|
4766
|
+
value: (d.price ?? 0) * (d.quantity ?? 1),
|
|
4767
|
+
currency: d.currency
|
|
4768
|
+
}
|
|
4769
|
+
});
|
|
4770
|
+
});
|
|
4771
|
+
on("vio:cart-error", (ev) => {
|
|
4772
|
+
const d = ev.detail ?? {};
|
|
4773
|
+
this.track("sdk_error", {
|
|
4774
|
+
context: { errorCode: "cart_error" },
|
|
4775
|
+
props: d.message ? { message: String(d.message).slice(0, 500) } : void 0
|
|
4776
|
+
});
|
|
4777
|
+
});
|
|
4498
4778
|
on("vio:product-click", (ev) => {
|
|
4499
4779
|
const d = ev.detail ?? {};
|
|
4500
4780
|
if (d.productId === void 0) return;
|
|
@@ -4595,6 +4875,12 @@ function safeStorageGet(key) {
|
|
|
4595
4875
|
return null;
|
|
4596
4876
|
}
|
|
4597
4877
|
}
|
|
4878
|
+
function safeStorageRemove(key) {
|
|
4879
|
+
try {
|
|
4880
|
+
window.localStorage.removeItem(key);
|
|
4881
|
+
} catch {
|
|
4882
|
+
}
|
|
4883
|
+
}
|
|
4598
4884
|
function safeStorageSet(key, value) {
|
|
4599
4885
|
try {
|
|
4600
4886
|
window.localStorage.setItem(key, value);
|
|
@@ -4780,5 +5066,5 @@ var _vioGlobal = globalThis;
|
|
|
4780
5066
|
var Vio = _vioGlobal.__VIO_FACADE__ ?? (_vioGlobal.__VIO_FACADE__ = new VioFacade());
|
|
4781
5067
|
|
|
4782
5068
|
export { ADD_ITEM_MUTATION, AnalyticsManager, CREATE_CART_MUTATION, CREATE_CHECKOUT_MUTATION, CREATE_PAYMENT_STRIPE_MUTATION, CREATE_PAYMENT_VIPPS_MUTATION, CartManager, CheckoutManager, CommerceClient, Configuration, DELETE_ITEM_MUTATION, GET_AVAILABLE_PAYMENT_METHODS_QUERY, GET_CART_QUERY, GET_CHECKOUT_QUERY, GET_LINE_ITEMS_BY_SUPPLIER_QUERY, GET_VIPPS_STATUS_QUERY, SDK_VERSION, UPDATE_CHECKOUT_MUTATION, UPDATE_ITEM_MUTATION, UPDATE_SHIPPINGS_BY_SUPPLIER_MUTATION, Vio, VioApi, VioApiError, __decorateClass, addItem, checkApplePayAvailability, createCart, createCheckout, createCommerceClient, createPaymentStripe, createPaymentVipps, createVioApi, deleteItem, displayPrice, executeCartGraphQL, formatPrice, getAvailablePaymentMethods, getCart, getCartGraphQLOptions, getCheckout, getCustomerSessionId, getGlobalCurrency, getLineItemsBySupplier, getVippsStatus, primaryImageUrl, showApplePaySheet, updateCheckout, updateItem, updateShippingsBySupplier };
|
|
4783
|
-
//# sourceMappingURL=chunk-
|
|
4784
|
-
//# sourceMappingURL=chunk-
|
|
5069
|
+
//# sourceMappingURL=chunk-U2QG4IVJ.js.map
|
|
5070
|
+
//# sourceMappingURL=chunk-U2QG4IVJ.js.map
|