@vitraun/webar 0.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.
- package/README.md +154 -0
- package/dist/events.min.js +1 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.min.js +1 -0
- package/dist/react.d.ts +17 -0
- package/dist/react.min.js +1 -0
- package/dist/widget-runtime.min.js +1 -0
- package/dist/widget.min.js +1 -0
- package/package.json +70 -0
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# @vitraun/webar
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@vitraun/webar)
|
|
4
|
+
[](https://www.npmjs.com/package/@vitraun/webar)
|
|
5
|
+
[](https://github.com/clagils/tryon-new-version/actions)
|
|
6
|
+
[](https://codecov.io/gh/clagils/tryon-new-version)
|
|
7
|
+
[](https://bundlephobia.com/package/@vitraun/webar)
|
|
8
|
+
[](https://www.npmjs.com/package/@vitraun/webar)
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
10
|
+
|
|
11
|
+
Web Component package for Vitraun Virtual Try-On (`<vitraun-vto>`), distributed as npm + CDN bundle.
|
|
12
|
+
|
|
13
|
+
## Install (npm)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm i @vitraun/webar
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import '@vitraun/webar'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<vitraun-vto
|
|
25
|
+
merchant-id="MRCT-KEY-000001"
|
|
26
|
+
env="prod"
|
|
27
|
+
lang="pt-BR"
|
|
28
|
+
platform="web"
|
|
29
|
+
isolated-sku="8028997081552"
|
|
30
|
+
apply-skus="SKU001,SKU002"
|
|
31
|
+
></vitraun-vto>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Required attributes: **`merchant-id`**, **`env`**. The **`env`** value selects Vitraun hosts: `https://api.{env}.vitraun.com/v1/tryon/init` and `https://app.{env}.vitraun.com/{lang}/virtual-tryon` for the iframe.
|
|
35
|
+
|
|
36
|
+
The **widget script** itself should be loaded from your **CDN** (or from npm/unpkg/jsDelivr during development), not from the Try-On Next.js app.
|
|
37
|
+
|
|
38
|
+
Optional attribute **`debug`**: when `true`, the widget logs diagnostic messages to the browser console (`[vitraun-vto]` prefix).
|
|
39
|
+
|
|
40
|
+
## Events and logs helpers
|
|
41
|
+
|
|
42
|
+
The package exports helpers to capture widget events consistently:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import {
|
|
46
|
+
VITRAUN_VTO_DEFAULT_EVENT_TYPES,
|
|
47
|
+
subscribeVitraunVTOEvents,
|
|
48
|
+
} from '@vitraun/webar'
|
|
49
|
+
|
|
50
|
+
const dispose = subscribeVitraunVTOEvents(containerElement, (entry) => {
|
|
51
|
+
console.log(entry.type, entry.timestamp, entry.detail)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
// later:
|
|
55
|
+
dispose()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
By default it listens to: `addToCart`, `removeFromCart`, `redirectToCart`, and `analysisFinished`.
|
|
59
|
+
You can opt in to `statusChange` and `vtoUsage` using options, or pass a custom `eventTypes` list.
|
|
60
|
+
|
|
61
|
+
For React consumers, the package also provides a hook:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { useVitraunVTOEventLogs } from '@vitraun/webar/react'
|
|
65
|
+
|
|
66
|
+
const { events, clearEvents } = useVitraunVTOEventLogs(containerRef.current)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## jsDelivr (npm mirror)
|
|
70
|
+
|
|
71
|
+
After publishing **`@vitraun/webar-cdn`** (workspace `vto-npm/cdn`, built from this package’s `dist/`), use [jsDelivr](https://www.jsdelivr.com/) URLs such as `https://cdn.jsdelivr.net/npm/@vitraun/webar-cdn@<version>/widget.min.js` — see [`../cdn/README.md`](../cdn/README.md).
|
|
72
|
+
|
|
73
|
+
## CDN and npm (same package, two browser bundles)
|
|
74
|
+
|
|
75
|
+
**`npm publish`** ships **`dist/widget.min.js`** and **`dist/events.min.js`** inside `@vitraun/webar`. **`npm run deploy:cdn`** uploads **only those two files** to the versioned prefix (`@vitraun/webar@<version>/`), matching what retailers get from the tarball.
|
|
76
|
+
|
|
77
|
+
| File | Role |
|
|
78
|
+
|------|------|
|
|
79
|
+
| **`widget.min.js`** | IIFE — `<script src="...">`; registers `<vitraun-vto>`. |
|
|
80
|
+
| **`events.min.js`** | ESM — optional; `import` behind `type="module"` for `subscribeVitraunVTOEvents` and constants (re-exported from `@vitraun/core`). |
|
|
81
|
+
|
|
82
|
+
**`widget-runtime.min.js`** stays in the **npm** package for `import '@vitraun/webar'` (dynamic import from `dist/index.min.js`). It is **not** uploaded by the default CDN script so shops on CDN only deal with these two assets.
|
|
83
|
+
|
|
84
|
+
## Use via CDN (HTML puro)
|
|
85
|
+
|
|
86
|
+
After each release, publish both assets (S3 + CloudFront, R2, etc.). This repo ships an **AWS S3** helper (AWS CLI):
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npm run build
|
|
90
|
+
export VITRAUN_CDN_UPLOAD=1
|
|
91
|
+
export VITRAUN_CDN_S3_BUCKET=your-bucket-name
|
|
92
|
+
npm run deploy:cdn
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
See `config/cdn-upload.env.example` for all variables (optional root prefix, dry-run, region).
|
|
96
|
+
|
|
97
|
+
**Minimum (widget only):**
|
|
98
|
+
|
|
99
|
+
```html
|
|
100
|
+
<script src="https://cdn.example.com/@vitraun/webar@0.1.0/widget.min.js"></script>
|
|
101
|
+
<vitraun-vto
|
|
102
|
+
merchant-id="vtrn-mch-key-..."
|
|
103
|
+
env="prod"
|
|
104
|
+
lang="en-US"
|
|
105
|
+
platform="web"
|
|
106
|
+
></vitraun-vto>
|
|
107
|
+
<script>
|
|
108
|
+
document.querySelector('vitraun-vto')?.open()
|
|
109
|
+
</script>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**With event helpers (second file, ESM):**
|
|
113
|
+
|
|
114
|
+
```html
|
|
115
|
+
<script src="https://cdn.example.com/@vitraun/webar@0.1.0/widget.min.js"></script>
|
|
116
|
+
<script type="module">
|
|
117
|
+
import { subscribeVitraunVTOEvents } from 'https://cdn.example.com/@vitraun/webar@0.1.0/events.min.js'
|
|
118
|
+
const el = document.querySelector('vitraun-vto')
|
|
119
|
+
const stop = subscribeVitraunVTOEvents(el, (entry) => {
|
|
120
|
+
console.log(entry.type, entry.detail)
|
|
121
|
+
})
|
|
122
|
+
</script>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Build outputs (`dist/`)
|
|
126
|
+
|
|
127
|
+
After `npm run build`, `dist/` contains **only** the integration bundles (JS + types):
|
|
128
|
+
|
|
129
|
+
- `dist/index.min.js` (ESM npm entry)
|
|
130
|
+
- `dist/index.d.ts` (types)
|
|
131
|
+
- `dist/events.min.js`, `dist/react.min.js`, `dist/react.d.ts`
|
|
132
|
+
- `dist/widget-runtime.min.js` (ESM runtime loaded by npm entry)
|
|
133
|
+
- `dist/widget.min.js` (IIFE for script tag)
|
|
134
|
+
|
|
135
|
+
MediaPipe/WASM and the `.task` model are **not** placed under `webar/dist`. They are downloaded into the Try-On app (`vto-front`) via `scripts/vendor-webar-engine-assets.mjs` into `public/webar-assets/` (iframe origin). **Requires network access** on `npm install` / `prebuild` in `vto-front`.
|
|
136
|
+
|
|
137
|
+
## What gets published to npm
|
|
138
|
+
|
|
139
|
+
The **npm tarball** lists `package.json` → `files`. For **browser** integration without a bundler, the same two CDN artifacts are **`dist/widget.min.js`** and **`dist/events.min.js`** (same version prefix on S3 after `deploy:cdn`). **`widget-runtime.min.js`** backs the ESM entry `import '@vitraun/webar'`. Heavy engine assets are served from the hosted Try-On app.
|
|
140
|
+
|
|
141
|
+
## Monorepo layout
|
|
142
|
+
|
|
143
|
+
This package lives under `vto-npm/webar` and depends on **`@vitraun/core`** for shared event contracts. See the repo root `vto-npm/README.md` for workspace layout.
|
|
144
|
+
|
|
145
|
+
The canonical widget source file lives at `vto-npm/core/src/widget.js` (resolved at build time via `webar/constants/widget-source-path.js`).
|
|
146
|
+
|
|
147
|
+
Public API compatibility is documented in `docs/public-api-contract.md` (repo root).
|
|
148
|
+
|
|
149
|
+
Architecture and embed flow (iframe, `postMessage`, `virtual-tryon-embed-init`, heartbeat): [`../docs/webar-widget-iframe-flow.md`](../docs/webar-widget-iframe-flow.md) (pt-BR).
|
|
150
|
+
|
|
151
|
+
## Versioning
|
|
152
|
+
|
|
153
|
+
- `@vitraun/webar` follows semver for its public exports and hook signatures.
|
|
154
|
+
- `@vitraun/core` ships shared contracts; coordinate major bumps when event payloads change.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var i=["addToCart","removeFromCart","redirectToCart","analysisFinished"],u=["statusChange","vtoUsage"],T=t=>Array.isArray(t)?t:[],o=(t={})=>{let r=T(t.eventTypes).filter(e=>typeof e=="string"&&e.trim());if(r.length>0)return[...new Set(r)];let s=t.includeStatusChange===!0,a=t.includeVtoUsage===!0,n=[...i];return s&&n.push("statusChange"),a&&n.push("vtoUsage"),[...new Set(n)]},E=t=>{let r=t;return{type:t.type,detail:r.detail,timestamp:new Date().toISOString(),nativeEvent:t}},c=(t,r,s={})=>{if(!t||typeof t.addEventListener!="function")return()=>{};if(typeof r!="function")return()=>{};let a=o(s);if(a.length===0)return()=>{};let n=e=>{r(E(e))};return a.forEach(e=>{t.addEventListener(e,n)}),()=>{a.forEach(e=>{t.removeEventListener(e,n)})}};export{i as VITRAUN_VTO_DEFAULT_EVENT_TYPES,u as VITRAUN_VTO_EXTRA_EVENT_TYPES,E as createVitraunEventLogEntry,c as subscribeVitraunVTOEvents};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { DetailedHTMLProps, HTMLAttributes } from 'react'
|
|
2
|
+
|
|
3
|
+
export type VitraunVTOElement = HTMLElement & {
|
|
4
|
+
open: () => Promise<void>
|
|
5
|
+
close: () => Promise<void>
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type VitraunVTOEventType =
|
|
9
|
+
| 'addToCart'
|
|
10
|
+
| 'removeFromCart'
|
|
11
|
+
| 'redirectToCart'
|
|
12
|
+
| 'analysisFinished'
|
|
13
|
+
| 'statusChange'
|
|
14
|
+
| 'vtoUsage'
|
|
15
|
+
|
|
16
|
+
export type VitraunVTOEventLogEntry = {
|
|
17
|
+
type: string
|
|
18
|
+
detail: unknown
|
|
19
|
+
timestamp: string
|
|
20
|
+
nativeEvent: Event
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type SubscribeVitraunVTOEventsOptions = {
|
|
24
|
+
eventTypes?: string[]
|
|
25
|
+
includeStatusChange?: boolean
|
|
26
|
+
includeVtoUsage?: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const VITRAUN_VTO_DEFAULT_EVENT_TYPES: readonly VitraunVTOEventType[]
|
|
30
|
+
export const VITRAUN_VTO_EXTRA_EVENT_TYPES: readonly VitraunVTOEventType[]
|
|
31
|
+
export const createVitraunEventLogEntry: (
|
|
32
|
+
event: Event,
|
|
33
|
+
) => VitraunVTOEventLogEntry
|
|
34
|
+
export const subscribeVitraunVTOEvents: (
|
|
35
|
+
target: EventTarget | null | undefined,
|
|
36
|
+
onEvent: (entry: VitraunVTOEventLogEntry) => void,
|
|
37
|
+
options?: SubscribeVitraunVTOEventsOptions,
|
|
38
|
+
) => () => void
|
|
39
|
+
|
|
40
|
+
/** Public attributes of `<vitraun-vto>` (widget runtime v5+). */
|
|
41
|
+
export interface VitraunVTOAttributes {
|
|
42
|
+
'merchant-id'?: string
|
|
43
|
+
/** Host segment for Vitraun URLs, e.g. `prod` → `https://app.prod.vitraun.com/...` */
|
|
44
|
+
env?: string
|
|
45
|
+
lang?: string
|
|
46
|
+
'isolated-sku'?: string
|
|
47
|
+
'apply-skus'?: string
|
|
48
|
+
flow?: 'checkout' | 'catalog'
|
|
49
|
+
'basket-opens-in'?: 'event' | 'blank' | 'self'
|
|
50
|
+
'checkout-opens-in'?: 'event' | 'blank' | 'self'
|
|
51
|
+
'use-simple-page'?: string
|
|
52
|
+
'show-details'?: string
|
|
53
|
+
'show-product-price'?: string
|
|
54
|
+
'price-from'?: string
|
|
55
|
+
'price-to'?: string
|
|
56
|
+
'currency-symbol'?: string
|
|
57
|
+
'container-min-height'?: string
|
|
58
|
+
'app-id'?: string
|
|
59
|
+
platform?: string
|
|
60
|
+
'bundle-id'?: string
|
|
61
|
+
'package-name'?: string
|
|
62
|
+
'app-version'?: string
|
|
63
|
+
'attestation-token'?: string
|
|
64
|
+
debug?: string
|
|
65
|
+
'is-simulation-mode'?: string
|
|
66
|
+
'simulation-inline-config'?: string
|
|
67
|
+
'init-timeout-ms'?: string
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
declare module 'react/jsx-runtime' {
|
|
71
|
+
namespace JSX {
|
|
72
|
+
interface IntrinsicElements {
|
|
73
|
+
'vitraun-vto': DetailedHTMLProps<
|
|
74
|
+
HTMLAttributes<HTMLElement> & VitraunVTOAttributes,
|
|
75
|
+
HTMLElement
|
|
76
|
+
>
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var a=["addToCart","removeFromCart","redirectToCart","analysisFinished"],T=["statusChange","vtoUsage"],u=e=>Array.isArray(e)?e:[],V=(e={})=>{let n=u(e.eventTypes).filter(t=>typeof t=="string"&&t.trim());if(n.length>0)return[...new Set(n)];let i=e.includeStatusChange===!0,s=e.includeVtoUsage===!0,r=[...a];return i&&r.push("statusChange"),s&&r.push("vtoUsage"),[...new Set(r)]},E=e=>{let n=e;return{type:e.type,detail:n.detail,timestamp:new Date().toISOString(),nativeEvent:e}},o=(e,n,i={})=>{if(!e||typeof e.addEventListener!="function")return()=>{};if(typeof n!="function")return()=>{};let s=V(i);if(s.length===0)return()=>{};let r=t=>{n(E(t))};return s.forEach(t=>{e.addEventListener(t,r)}),()=>{s.forEach(t=>{e.removeEventListener(t,r)})}};var c=typeof window<"u"&&typeof HTMLElement<"u"&&typeof customElements<"u";c&&import("./widget-runtime.min.js");export{a as VITRAUN_VTO_DEFAULT_EVENT_TYPES,T as VITRAUN_VTO_EXTRA_EVENT_TYPES,E as createVitraunEventLogEntry,o as subscribeVitraunVTOEvents};
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { VitraunVTOEventLogEntry } from './index'
|
|
2
|
+
|
|
3
|
+
export type UseVitraunVTOEventLogsOptions = {
|
|
4
|
+
eventTypes?: string[]
|
|
5
|
+
includeStatusChange?: boolean
|
|
6
|
+
includeVtoUsage?: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type VitraunVTOLogEntry = Omit<VitraunVTOEventLogEntry, 'nativeEvent'>
|
|
10
|
+
|
|
11
|
+
export const useVitraunVTOEventLogs: (
|
|
12
|
+
target: EventTarget | null | undefined,
|
|
13
|
+
options?: UseVitraunVTOEventLogsOptions,
|
|
14
|
+
) => {
|
|
15
|
+
events: VitraunVTOLogEntry[]
|
|
16
|
+
clearEvents: () => void
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useEffect as d,useState as o}from"react";var E=["addToCart","removeFromCart","redirectToCart","analysisFinished"];var V=e=>Array.isArray(e)?e:[],y=(e={})=>{let t=V(e.eventTypes).filter(r=>typeof r=="string"&&r.trim());if(t.length>0)return[...new Set(t)];let a=e.includeStatusChange===!0,n=e.includeVtoUsage===!0,s=[...E];return a&&s.push("statusChange"),n&&s.push("vtoUsage"),[...new Set(s)]},c=e=>{let t=e;return{type:e.type,detail:t.detail,timestamp:new Date().toISOString(),nativeEvent:e}},u=(e,t,a={})=>{if(!e||typeof e.addEventListener!="function")return()=>{};if(typeof t!="function")return()=>{};let n=y(a);if(n.length===0)return()=>{};let s=r=>{t(c(r))};return n.forEach(r=>{e.addEventListener(r,s)}),()=>{n.forEach(r=>{e.removeEventListener(r,s)})}};var f=e=>({type:e.type,detail:e.detail,timestamp:e.timestamp}),S=(e,t={})=>{let[a,n]=o([]),[s,r]=o(0);return d(()=>{if(!e)return;let i=u(e,T=>{n(v=>[...v,f(T)])},t);return()=>{i()}},[e,s,t.includeStatusChange,t.includeVtoUsage,Array.isArray(t.eventTypes)?t.eventTypes.join("|"):""]),{events:a,clearEvents:()=>{n([]),r(i=>i+1)}}};export{S as useVitraunVTOEventLogs};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){"use strict";var v="VITRAUN_CONFIG",f="vtrn-vto-session",I=18e5,d=1e4,c="en-US";function r(n,t,e){var i=n.getAttribute(t);return i!=null&&i!==""?i:e}function h(n,t){if(n==null||n==="")return t;var e=String(n).toLowerCase();return e==="true"||e==="1"||e==="yes"}function m(n){if(n==null||n==="")return null;var t=parseFloat(String(n));return Number.isFinite(t)?t:null}function b(n){return!n||typeof n!="string"?[]:n.split(",").map(function(t){return t.trim()}).filter(Boolean)}function w(n,t){var e=r(n,t,"");if(!e||typeof e!="string")return null;try{return JSON.parse(e)}catch{return null}}function S(n){try{return JSON.parse(n)}catch{return null}}function p(){return typeof window>"u"||!window.location||!window.location.origin?null:window.location.origin}function _(){return typeof window>"u"||!window.location||!window.location.href?null:window.location.href}function k(n){if(!n||typeof n!="string")return null;try{return new URL(n).origin}catch{return null}}function T(n){var t=String(n||"").trim().toLowerCase();if(!t)throw new Error("The env attribute is required.");if(!/^[a-z0-9-]+$/.test(t))throw new Error("The env attribute contains an invalid value.");return t}function P(n){return n?String(n).trim().toLowerCase():"web"}function C(n){return"https://api."+n+".vitraun.com/v1/tryon/init"}function O(n,t,e){var i=t||c,o="https://app."+n+".vitraun.com/"+encodeURIComponent(i)+"/virtual-tryon";return e&&(o+="?simulation=1"),o}function U(n,t,e,i){return!t||t<=0?n:new Promise(function(o,l){var a=!1,s=setTimeout(function(){if(!a){a=!0;try{i&&typeof i.abort=="function"&&i.abort()}catch{}l(new Error(e||"The operation timed out."))}},t);n.then(function(u){a||(a=!0,clearTimeout(s),o(u))}).catch(function(u){a||(a=!0,clearTimeout(s),l(u))})})}function g(){if(typeof window>"u"||!window.crypto||!window.crypto.randomUUID)return"00000000-0000-4000-8000-000000000000";try{var n=sessionStorage.getItem(f);if(n){var t=JSON.parse(n);if(t&&typeof t.id=="string"&&typeof t.exp=="number"&&Date.now()<t.exp)return t.id}}catch{}var e=window.crypto.randomUUID(),i=Date.now()+I;try{sessionStorage.setItem(f,JSON.stringify({id:e,exp:i}))}catch{}return e}class E extends HTMLElement{static get observedAttributes(){return["merchant-id","env","lang","isolated-sku","apply-skus","flow","basket-opens-in","checkout-opens-in","use-simple-page","show-details","show-product-price","price-from","price-to","currency-symbol","is-simulation-mode","simulation-inline-config","container-min-height","app-id","platform","bundle-id","package-name","app-version","attestation-token","debug","init-timeout-ms"]}constructor(){super(),this.attachShadow({mode:"open"}),this._state={merchantId:"",env:"",lang:c,isolatedSku:null,applySkus:[],iframeOrigin:null,flow:"checkout",basketOpensIn:"event",checkoutOpensIn:"event",useSimplePage:!0,showDetails:!0,showProductPrice:!1,priceFrom:null,priceTo:null,currencySymbol:null,isSimulationMode:!1,simulationInlineConfig:null,appId:null,platform:"web",bundleId:null,packageName:null,appVersion:null,attestationToken:null,debug:!1,sessionToken:null,tryonSessionId:null,resolvedInitUrl:null,resolvedIframeUrl:null,initTimeoutMs:d},this._boundHandleMessage=this._handleMessage.bind(this),this._initPromise=null,this._initStateKey=null,this._activeInitRequestId=0,this._renderVersion=0,this._abortController=null}connectedCallback(){this._readAttributes(),this._render(),typeof window<"u"&&window.addEventListener("message",this._boundHandleMessage)}disconnectedCallback(){if(typeof window<"u"&&window.removeEventListener("message",this._boundHandleMessage),this._abortController&&typeof this._abortController.abort=="function")try{this._abortController.abort()}catch{}}attributeChangedCallback(t,e,i){e!==i&&(this._readAttributes(),this._render())}_log(){if(!(!this._state.debug||typeof console>"u"||!console.log)){var t=Array.prototype.slice.call(arguments);t.unshift("[vitraun-vto]"),console.log.apply(console,t)}}_readAttributes(){var t=w(this,"simulation-inline-config"),e=!1;t&&t.features&&typeof t.features.showProductPrice=="boolean"&&(e=t.features.showProductPrice);var i=!0;t&&t.features&&typeof t.features.useSimplePage=="boolean"&&(i=t.features.useSimplePage);var o="checkout";t&&t.features&&(t.features.flow==="catalog"||t.features.flow==="checkout")&&(o=t.features.flow);var l=!0;t&&t.features&&typeof t.features.showDetails=="boolean"&&(l=t.features.showDetails);var a="";try{a=T(r(this,"env",""))}catch{a=""}var s=parseInt(r(this,"init-timeout-ms",String(d)),10);(!Number.isFinite(s)||s<0)&&(s=d),this._state={merchantId:r(this,"merchant-id",""),env:a,lang:r(this,"lang",c),isolatedSku:r(this,"isolated-sku",null)||null,applySkus:b(r(this,"apply-skus","")),iframeOrigin:this._state&&this._state.iframeOrigin?this._state.iframeOrigin:null,flow:r(this,"flow",o),basketOpensIn:r(this,"basket-opens-in","event"),checkoutOpensIn:r(this,"checkout-opens-in","event"),useSimplePage:h(r(this,"use-simple-page",""),i),showDetails:h(r(this,"show-details",""),l),showProductPrice:h(r(this,"show-product-price",""),e),priceFrom:m(r(this,"price-from",null)),priceTo:m(r(this,"price-to",null)),currencySymbol:r(this,"currency-symbol",null)||null,isSimulationMode:h(r(this,"is-simulation-mode","false"),!1),simulationInlineConfig:t,appId:r(this,"app-id",null)||null,platform:P(r(this,"platform",null)),bundleId:r(this,"bundle-id",null)||null,packageName:r(this,"package-name",null)||null,appVersion:r(this,"app-version",null)||null,attestationToken:r(this,"attestation-token",null)||null,debug:h(r(this,"debug","false"),!1),sessionToken:this._state&&this._state.sessionToken?this._state.sessionToken:null,tryonSessionId:this._state&&this._state.tryonSessionId?this._state.tryonSessionId:null,resolvedInitUrl:this._state&&this._state.resolvedInitUrl?this._state.resolvedInitUrl:null,resolvedIframeUrl:this._state&&this._state.resolvedIframeUrl?this._state.resolvedIframeUrl:null,initTimeoutMs:s}}_emit(t,e){this.dispatchEvent(new CustomEvent(t,{detail:e??null,bubbles:!0,composed:!0}))}_setStatus(t,e){this.setAttribute("data-status",t),this._emit("statusChange",{status:t,detail:e||null})}_getIframeElement(){return this.shadowRoot?this.shadowRoot.querySelector("iframe"):null}_handleMessage(t){var e=t.data;if(!(!e||typeof e!="object")){var i=this._getIframeElement();if(!(!i||!i.contentWindow)&&t.source===i.contentWindow&&!(!this._state.iframeOrigin||t.origin!==this._state.iframeOrigin)){var o=e.type,l=e.detail;if(o==="VTO_USAGE"){this._emit("vtoUsage",l);return}var a=["addToCart","removeFromCart","redirectToCart","analysisFinished"];a.indexOf(o)!==-1&&this._emit(o,l)}}}_getInitStateKey(){return JSON.stringify({merchantId:this._state.merchantId,env:this._state.env,lang:this._state.lang,isolatedSku:this._state.isolatedSku,applySkus:this._state.applySkus,flow:this._state.flow,basketOpensIn:this._state.basketOpensIn,checkoutOpensIn:this._state.checkoutOpensIn,useSimplePage:this._state.useSimplePage,showDetails:this._state.showDetails,showProductPrice:this._state.showProductPrice,priceFrom:this._state.priceFrom,priceTo:this._state.priceTo,currencySymbol:this._state.currencySymbol,isSimulationMode:this._state.isSimulationMode,simulationInlineConfig:this._state.simulationInlineConfig,appId:this._state.appId,platform:this._state.platform,bundleId:this._state.bundleId,packageName:this._state.packageName,appVersion:this._state.appVersion,attestationToken:this._state.attestationToken})}_buildResolvedUrls(){if(!this._state.env)throw new Error("The env attribute is required.");var t=O(this._state.env,this._state.lang,this._state.isSimulationMode);return{initUrl:C(this._state.env),iframeUrl:t,iframeOrigin:k(t)}}_buildInitPayload(){var t=g();return{merchantId:this._state.merchantId,tryonSessionId:t,lang:this._state.lang,isolatedSku:this._state.isolatedSku,applySkus:this._state.applySkus,flow:this._state.flow,basketOpensIn:this._state.basketOpensIn,checkoutOpensIn:this._state.checkoutOpensIn,useSimplePage:this._state.useSimplePage,showDetails:this._state.showDetails,showProductPrice:this._state.showProductPrice,priceFrom:this._state.priceFrom,priceTo:this._state.priceTo,currencySymbol:this._state.currencySymbol,isSimulationMode:this._state.isSimulationMode,inlineVirtualTryonConfig:this._state.isSimulationMode&&this._state.simulationInlineConfig&&typeof this._state.simulationInlineConfig=="object"?this._state.simulationInlineConfig:null,app:{appId:this._state.appId,platform:this._state.platform,bundleId:this._state.bundleId,packageName:this._state.packageName,appVersion:this._state.appVersion,attestationToken:this._state.attestationToken},context:{hostPageOrigin:p(),hostPageUrl:_(),userAgent:typeof navigator<"u"&&navigator.userAgent?navigator.userAgent:null,referrer:typeof document<"u"&&document.referrer?document.referrer:null,timezone:typeof Intl<"u"&&Intl.DateTimeFormat?Intl.DateTimeFormat().resolvedOptions().timeZone:null}}}_normalizeInitResponse(t,e,i){if(!t||typeof t!="object")throw new Error("Invalid init response.");var o=typeof t.sessionToken=="string"&&t.sessionToken?t.sessionToken:null,l=typeof t.tryonSessionId=="string"&&t.tryonSessionId?t.tryonSessionId:i;if(!o)throw new Error("The init API did not return sessionToken.");return{sessionToken:o,tryonSessionId:l,initUrl:e.initUrl,iframeUrl:e.iframeUrl,iframeOrigin:e.iframeOrigin}}_initializeSessionIfNeeded(){var t=this;if(!this._state.merchantId)return Promise.reject(new Error("The merchant-id attribute is required."));if(!this._state.env)return Promise.reject(new Error("The env attribute is required."));var e=this._getInitStateKey();if(this._initPromise&&this._initStateKey===e)return this._initPromise;if(this._abortController&&typeof this._abortController.abort=="function")try{this._abortController.abort()}catch{}this._initStateKey=e,this._activeInitRequestId+=1;var i=this._activeInitRequestId;this._setStatus("loading");var o;try{o=this._buildResolvedUrls()}catch(s){return Promise.reject(s)}var l=this._buildInitPayload();this._state.tryonSessionId=l.tryonSessionId,this._abortController=typeof AbortController<"u"?new AbortController:null;var a=fetch(o.initUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l),signal:this._abortController?this._abortController.signal:void 0}).then(function(s){return s.ok?s.json():s.text().then(function(u){var y=S(u),x=y&&y.message||u||"Failed to initialize session ("+s.status+").";throw new Error(x)})}).then(function(s){return t._normalizeInitResponse(s,o,l.tryonSessionId)});return this._initPromise=U(a,this._state.initTimeoutMs,"Timed out while initializing the Vitraun session.",this._abortController).then(function(s){return i!==t._activeInitRequestId||(t._state.sessionToken=s.sessionToken,t._state.tryonSessionId=s.tryonSessionId,t._state.resolvedInitUrl=s.initUrl,t._state.resolvedIframeUrl=s.iframeUrl,t._state.iframeOrigin=s.iframeOrigin,t._setStatus("ready")),s}).catch(function(s){throw i!==t._activeInitRequestId||(t._state.sessionToken=null,t._state.resolvedInitUrl=null,t._state.resolvedIframeUrl=null,t._state.iframeOrigin=null,t._setStatus("error",{message:s&&s.message?s.message:"Initialization failed."})),s}).finally(function(){i===t._activeInitRequestId&&(t._initPromise=null)}),this._initPromise}_sendConfigToIframe(){var t=this._getIframeElement();if(!(!t||!t.contentWindow)){var e=this._state.iframeOrigin;if(!e){this._log("Config not sent: iframeOrigin is missing.");return}var i={merchantId:this._state.merchantId,sessionToken:this._state.sessionToken,tryonSessionId:this._state.tryonSessionId||g(),lang:this._state.lang,isolatedSku:this._state.isolatedSku,applySkus:this._state.applySkus,flow:this._state.flow,basketOpensIn:this._state.basketOpensIn,checkoutOpensIn:this._state.checkoutOpensIn,useSimplePage:this._state.useSimplePage,showDetails:this._state.showDetails,showProductPrice:this._state.showProductPrice,priceFrom:this._state.priceFrom,priceTo:this._state.priceTo,currencySymbol:this._state.currencySymbol,isSimulationMode:this._state.isSimulationMode,app:{appId:this._state.appId,platform:this._state.platform,bundleId:this._state.bundleId,packageName:this._state.packageName,appVersion:this._state.appVersion,attestationToken:this._state.attestationToken},hostPageOrigin:p(),hostPageUrl:_()};this._state.isSimulationMode&&this._state.simulationInlineConfig&&typeof this._state.simulationInlineConfig=="object"&&(i.inlineVirtualTryonConfig=this._state.simulationInlineConfig),t.contentWindow.postMessage({type:v,payload:i},e)}}_renderLoading(){if(this.shadowRoot){var t=r(this,"container-min-height","80vh");this.shadowRoot.innerHTML="";var e=document.createElement("style");e.textContent=":host { display:block; width:100%; min-height:"+t+"; box-sizing:border-box; }.vitraun-loading {min-height:"+t+";display:flex;align-items:center;justify-content:center;border:1px solid #ececec;background:#fafafa;color:#333;font:14px/1.4 Arial, sans-serif;padding:16px;box-sizing:border-box;border-radius:8px;text-align:center;}";var i=document.createElement("div");i.className="vitraun-loading",i.textContent="Loading Vitraun...",this.shadowRoot.appendChild(e),this.shadowRoot.appendChild(i)}}_renderError(t){if(this.shadowRoot){var e=r(this,"container-min-height","80vh");this.shadowRoot.innerHTML="";var i=document.createElement("style");i.textContent=":host { display:block; width:100%; min-height:"+e+"; box-sizing:border-box; }.vitraun-error {min-height:"+e+";display:flex;align-items:center;justify-content:center;border:1px solid #f1d5d5;background:#fff7f7;color:#7a1f1f;font:14px/1.4 Arial, sans-serif;padding:16px;box-sizing:border-box;border-radius:8px;text-align:center;}";var o=document.createElement("div");o.className="vitraun-error",o.textContent=t||"Failed to load Vitraun.",this.shadowRoot.appendChild(i),this.shadowRoot.appendChild(o)}}_renderIframe(t,e){if(this.shadowRoot){var i=this,o=r(this,"container-min-height","80vh");this.shadowRoot.innerHTML="";var l=document.createElement("style");l.textContent=":host { display:block; width:100%; min-height:"+o+"; box-sizing:border-box; }";var a=document.createElement("iframe");a.src=t,a.title="Vitraun VTO",a.style.cssText="width:100%;height:100%;border:0;min-height:"+o,a.setAttribute("allow","camera"),a.setAttribute("referrerpolicy","strict-origin-when-cross-origin"),a.onload=function(){e===i._renderVersion&&[0,50,150,400,1e3].forEach(function(s){setTimeout(function(){e===i._renderVersion&&i._sendConfigToIframe()},s)})},this.shadowRoot.appendChild(l),this.shadowRoot.appendChild(a)}}_render(){if(this.shadowRoot){this._renderVersion+=1;var t=this._renderVersion;if(!this._state.merchantId){this._setStatus("error",{message:"The merchant-id attribute is required."}),this._renderError("The merchant-id attribute is required.");return}if(!this._state.env){this._setStatus("error",{message:"The env attribute is required."}),this._renderError("The env attribute is required.");return}this._renderLoading(),this._initializeSessionIfNeeded().then(function(e){t===this._renderVersion&&this._renderIframe(e.iframeUrl,t)}.bind(this)).catch(function(e){t===this._renderVersion&&this._renderError(e&&e.message?e.message:"Failed to load Vitraun.")}.bind(this))}}open(){return this.style.display="",Promise.resolve()}close(){return this.style.display="none",Promise.resolve()}}typeof customElements<"u"&&!customElements.get("vitraun-vto")&&customElements.define("vitraun-vto",E)})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var VitraunWebAR=(()=>{(function(){"use strict";var v="VITRAUN_CONFIG",f="vtrn-vto-session",I=18e5,d=1e4,c="en-US";function r(n,t,e){var i=n.getAttribute(t);return i!=null&&i!==""?i:e}function h(n,t){if(n==null||n==="")return t;var e=String(n).toLowerCase();return e==="true"||e==="1"||e==="yes"}function m(n){if(n==null||n==="")return null;var t=parseFloat(String(n));return Number.isFinite(t)?t:null}function b(n){return!n||typeof n!="string"?[]:n.split(",").map(function(t){return t.trim()}).filter(Boolean)}function w(n,t){var e=r(n,t,"");if(!e||typeof e!="string")return null;try{return JSON.parse(e)}catch(i){return null}}function S(n){try{return JSON.parse(n)}catch(t){return null}}function p(){return typeof window=="undefined"||!window.location||!window.location.origin?null:window.location.origin}function _(){return typeof window=="undefined"||!window.location||!window.location.href?null:window.location.href}function k(n){if(!n||typeof n!="string")return null;try{return new URL(n).origin}catch(t){return null}}function T(n){var t=String(n||"").trim().toLowerCase();if(!t)throw new Error("The env attribute is required.");if(!/^[a-z0-9-]+$/.test(t))throw new Error("The env attribute contains an invalid value.");return t}function P(n){return n?String(n).trim().toLowerCase():"web"}function C(n){return"https://api."+n+".vitraun.com/v1/tryon/init"}function O(n,t,e){var i=t||c,o="https://app."+n+".vitraun.com/"+encodeURIComponent(i)+"/virtual-tryon";return e&&(o+="?simulation=1"),o}function U(n,t,e,i){return!t||t<=0?n:new Promise(function(o,l){var a=!1,s=setTimeout(function(){if(!a){a=!0;try{i&&typeof i.abort=="function"&&i.abort()}catch(u){}l(new Error(e||"The operation timed out."))}},t);n.then(function(u){a||(a=!0,clearTimeout(s),o(u))}).catch(function(u){a||(a=!0,clearTimeout(s),l(u))})})}function g(){if(typeof window=="undefined"||!window.crypto||!window.crypto.randomUUID)return"00000000-0000-4000-8000-000000000000";try{var n=sessionStorage.getItem(f);if(n){var t=JSON.parse(n);if(t&&typeof t.id=="string"&&typeof t.exp=="number"&&Date.now()<t.exp)return t.id}}catch(o){}var e=window.crypto.randomUUID(),i=Date.now()+I;try{sessionStorage.setItem(f,JSON.stringify({id:e,exp:i}))}catch(o){}return e}class E extends HTMLElement{static get observedAttributes(){return["merchant-id","env","lang","isolated-sku","apply-skus","flow","basket-opens-in","checkout-opens-in","use-simple-page","show-details","show-product-price","price-from","price-to","currency-symbol","is-simulation-mode","simulation-inline-config","container-min-height","app-id","platform","bundle-id","package-name","app-version","attestation-token","debug","init-timeout-ms"]}constructor(){super(),this.attachShadow({mode:"open"}),this._state={merchantId:"",env:"",lang:c,isolatedSku:null,applySkus:[],iframeOrigin:null,flow:"checkout",basketOpensIn:"event",checkoutOpensIn:"event",useSimplePage:!0,showDetails:!0,showProductPrice:!1,priceFrom:null,priceTo:null,currencySymbol:null,isSimulationMode:!1,simulationInlineConfig:null,appId:null,platform:"web",bundleId:null,packageName:null,appVersion:null,attestationToken:null,debug:!1,sessionToken:null,tryonSessionId:null,resolvedInitUrl:null,resolvedIframeUrl:null,initTimeoutMs:d},this._boundHandleMessage=this._handleMessage.bind(this),this._initPromise=null,this._initStateKey=null,this._activeInitRequestId=0,this._renderVersion=0,this._abortController=null}connectedCallback(){this._readAttributes(),this._render(),typeof window!="undefined"&&window.addEventListener("message",this._boundHandleMessage)}disconnectedCallback(){if(typeof window!="undefined"&&window.removeEventListener("message",this._boundHandleMessage),this._abortController&&typeof this._abortController.abort=="function")try{this._abortController.abort()}catch(t){}}attributeChangedCallback(t,e,i){e!==i&&(this._readAttributes(),this._render())}_log(){if(!(!this._state.debug||typeof console=="undefined"||!console.log)){var t=Array.prototype.slice.call(arguments);t.unshift("[vitraun-vto]"),console.log.apply(console,t)}}_readAttributes(){var t=w(this,"simulation-inline-config"),e=!1;t&&t.features&&typeof t.features.showProductPrice=="boolean"&&(e=t.features.showProductPrice);var i=!0;t&&t.features&&typeof t.features.useSimplePage=="boolean"&&(i=t.features.useSimplePage);var o="checkout";t&&t.features&&(t.features.flow==="catalog"||t.features.flow==="checkout")&&(o=t.features.flow);var l=!0;t&&t.features&&typeof t.features.showDetails=="boolean"&&(l=t.features.showDetails);var a="";try{a=T(r(this,"env",""))}catch(u){a=""}var s=parseInt(r(this,"init-timeout-ms",String(d)),10);(!Number.isFinite(s)||s<0)&&(s=d),this._state={merchantId:r(this,"merchant-id",""),env:a,lang:r(this,"lang",c),isolatedSku:r(this,"isolated-sku",null)||null,applySkus:b(r(this,"apply-skus","")),iframeOrigin:this._state&&this._state.iframeOrigin?this._state.iframeOrigin:null,flow:r(this,"flow",o),basketOpensIn:r(this,"basket-opens-in","event"),checkoutOpensIn:r(this,"checkout-opens-in","event"),useSimplePage:h(r(this,"use-simple-page",""),i),showDetails:h(r(this,"show-details",""),l),showProductPrice:h(r(this,"show-product-price",""),e),priceFrom:m(r(this,"price-from",null)),priceTo:m(r(this,"price-to",null)),currencySymbol:r(this,"currency-symbol",null)||null,isSimulationMode:h(r(this,"is-simulation-mode","false"),!1),simulationInlineConfig:t,appId:r(this,"app-id",null)||null,platform:P(r(this,"platform",null)),bundleId:r(this,"bundle-id",null)||null,packageName:r(this,"package-name",null)||null,appVersion:r(this,"app-version",null)||null,attestationToken:r(this,"attestation-token",null)||null,debug:h(r(this,"debug","false"),!1),sessionToken:this._state&&this._state.sessionToken?this._state.sessionToken:null,tryonSessionId:this._state&&this._state.tryonSessionId?this._state.tryonSessionId:null,resolvedInitUrl:this._state&&this._state.resolvedInitUrl?this._state.resolvedInitUrl:null,resolvedIframeUrl:this._state&&this._state.resolvedIframeUrl?this._state.resolvedIframeUrl:null,initTimeoutMs:s}}_emit(t,e){this.dispatchEvent(new CustomEvent(t,{detail:e!=null?e:null,bubbles:!0,composed:!0}))}_setStatus(t,e){this.setAttribute("data-status",t),this._emit("statusChange",{status:t,detail:e||null})}_getIframeElement(){return this.shadowRoot?this.shadowRoot.querySelector("iframe"):null}_handleMessage(t){var e=t.data;if(!(!e||typeof e!="object")){var i=this._getIframeElement();if(!(!i||!i.contentWindow)&&t.source===i.contentWindow&&!(!this._state.iframeOrigin||t.origin!==this._state.iframeOrigin)){var o=e.type,l=e.detail;if(o==="VTO_USAGE"){this._emit("vtoUsage",l);return}var a=["addToCart","removeFromCart","redirectToCart","analysisFinished"];a.indexOf(o)!==-1&&this._emit(o,l)}}}_getInitStateKey(){return JSON.stringify({merchantId:this._state.merchantId,env:this._state.env,lang:this._state.lang,isolatedSku:this._state.isolatedSku,applySkus:this._state.applySkus,flow:this._state.flow,basketOpensIn:this._state.basketOpensIn,checkoutOpensIn:this._state.checkoutOpensIn,useSimplePage:this._state.useSimplePage,showDetails:this._state.showDetails,showProductPrice:this._state.showProductPrice,priceFrom:this._state.priceFrom,priceTo:this._state.priceTo,currencySymbol:this._state.currencySymbol,isSimulationMode:this._state.isSimulationMode,simulationInlineConfig:this._state.simulationInlineConfig,appId:this._state.appId,platform:this._state.platform,bundleId:this._state.bundleId,packageName:this._state.packageName,appVersion:this._state.appVersion,attestationToken:this._state.attestationToken})}_buildResolvedUrls(){if(!this._state.env)throw new Error("The env attribute is required.");var t=O(this._state.env,this._state.lang,this._state.isSimulationMode);return{initUrl:C(this._state.env),iframeUrl:t,iframeOrigin:k(t)}}_buildInitPayload(){var t=g();return{merchantId:this._state.merchantId,tryonSessionId:t,lang:this._state.lang,isolatedSku:this._state.isolatedSku,applySkus:this._state.applySkus,flow:this._state.flow,basketOpensIn:this._state.basketOpensIn,checkoutOpensIn:this._state.checkoutOpensIn,useSimplePage:this._state.useSimplePage,showDetails:this._state.showDetails,showProductPrice:this._state.showProductPrice,priceFrom:this._state.priceFrom,priceTo:this._state.priceTo,currencySymbol:this._state.currencySymbol,isSimulationMode:this._state.isSimulationMode,inlineVirtualTryonConfig:this._state.isSimulationMode&&this._state.simulationInlineConfig&&typeof this._state.simulationInlineConfig=="object"?this._state.simulationInlineConfig:null,app:{appId:this._state.appId,platform:this._state.platform,bundleId:this._state.bundleId,packageName:this._state.packageName,appVersion:this._state.appVersion,attestationToken:this._state.attestationToken},context:{hostPageOrigin:p(),hostPageUrl:_(),userAgent:typeof navigator!="undefined"&&navigator.userAgent?navigator.userAgent:null,referrer:typeof document!="undefined"&&document.referrer?document.referrer:null,timezone:typeof Intl!="undefined"&&Intl.DateTimeFormat?Intl.DateTimeFormat().resolvedOptions().timeZone:null}}}_normalizeInitResponse(t,e,i){if(!t||typeof t!="object")throw new Error("Invalid init response.");var o=typeof t.sessionToken=="string"&&t.sessionToken?t.sessionToken:null,l=typeof t.tryonSessionId=="string"&&t.tryonSessionId?t.tryonSessionId:i;if(!o)throw new Error("The init API did not return sessionToken.");return{sessionToken:o,tryonSessionId:l,initUrl:e.initUrl,iframeUrl:e.iframeUrl,iframeOrigin:e.iframeOrigin}}_initializeSessionIfNeeded(){var t=this;if(!this._state.merchantId)return Promise.reject(new Error("The merchant-id attribute is required."));if(!this._state.env)return Promise.reject(new Error("The env attribute is required."));var e=this._getInitStateKey();if(this._initPromise&&this._initStateKey===e)return this._initPromise;if(this._abortController&&typeof this._abortController.abort=="function")try{this._abortController.abort()}catch(s){}this._initStateKey=e,this._activeInitRequestId+=1;var i=this._activeInitRequestId;this._setStatus("loading");var o;try{o=this._buildResolvedUrls()}catch(s){return Promise.reject(s)}var l=this._buildInitPayload();this._state.tryonSessionId=l.tryonSessionId,this._abortController=typeof AbortController!="undefined"?new AbortController:null;var a=fetch(o.initUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l),signal:this._abortController?this._abortController.signal:void 0}).then(function(s){return s.ok?s.json():s.text().then(function(u){var y=S(u),x=y&&y.message||u||"Failed to initialize session ("+s.status+").";throw new Error(x)})}).then(function(s){return t._normalizeInitResponse(s,o,l.tryonSessionId)});return this._initPromise=U(a,this._state.initTimeoutMs,"Timed out while initializing the Vitraun session.",this._abortController).then(function(s){return i!==t._activeInitRequestId||(t._state.sessionToken=s.sessionToken,t._state.tryonSessionId=s.tryonSessionId,t._state.resolvedInitUrl=s.initUrl,t._state.resolvedIframeUrl=s.iframeUrl,t._state.iframeOrigin=s.iframeOrigin,t._setStatus("ready")),s}).catch(function(s){throw i!==t._activeInitRequestId||(t._state.sessionToken=null,t._state.resolvedInitUrl=null,t._state.resolvedIframeUrl=null,t._state.iframeOrigin=null,t._setStatus("error",{message:s&&s.message?s.message:"Initialization failed."})),s}).finally(function(){i===t._activeInitRequestId&&(t._initPromise=null)}),this._initPromise}_sendConfigToIframe(){var t=this._getIframeElement();if(!(!t||!t.contentWindow)){var e=this._state.iframeOrigin;if(!e){this._log("Config not sent: iframeOrigin is missing.");return}var i={merchantId:this._state.merchantId,sessionToken:this._state.sessionToken,tryonSessionId:this._state.tryonSessionId||g(),lang:this._state.lang,isolatedSku:this._state.isolatedSku,applySkus:this._state.applySkus,flow:this._state.flow,basketOpensIn:this._state.basketOpensIn,checkoutOpensIn:this._state.checkoutOpensIn,useSimplePage:this._state.useSimplePage,showDetails:this._state.showDetails,showProductPrice:this._state.showProductPrice,priceFrom:this._state.priceFrom,priceTo:this._state.priceTo,currencySymbol:this._state.currencySymbol,isSimulationMode:this._state.isSimulationMode,app:{appId:this._state.appId,platform:this._state.platform,bundleId:this._state.bundleId,packageName:this._state.packageName,appVersion:this._state.appVersion,attestationToken:this._state.attestationToken},hostPageOrigin:p(),hostPageUrl:_()};this._state.isSimulationMode&&this._state.simulationInlineConfig&&typeof this._state.simulationInlineConfig=="object"&&(i.inlineVirtualTryonConfig=this._state.simulationInlineConfig),t.contentWindow.postMessage({type:v,payload:i},e)}}_renderLoading(){if(this.shadowRoot){var t=r(this,"container-min-height","80vh");this.shadowRoot.innerHTML="";var e=document.createElement("style");e.textContent=":host { display:block; width:100%; min-height:"+t+"; box-sizing:border-box; }.vitraun-loading {min-height:"+t+";display:flex;align-items:center;justify-content:center;border:1px solid #ececec;background:#fafafa;color:#333;font:14px/1.4 Arial, sans-serif;padding:16px;box-sizing:border-box;border-radius:8px;text-align:center;}";var i=document.createElement("div");i.className="vitraun-loading",i.textContent="Loading Vitraun...",this.shadowRoot.appendChild(e),this.shadowRoot.appendChild(i)}}_renderError(t){if(this.shadowRoot){var e=r(this,"container-min-height","80vh");this.shadowRoot.innerHTML="";var i=document.createElement("style");i.textContent=":host { display:block; width:100%; min-height:"+e+"; box-sizing:border-box; }.vitraun-error {min-height:"+e+";display:flex;align-items:center;justify-content:center;border:1px solid #f1d5d5;background:#fff7f7;color:#7a1f1f;font:14px/1.4 Arial, sans-serif;padding:16px;box-sizing:border-box;border-radius:8px;text-align:center;}";var o=document.createElement("div");o.className="vitraun-error",o.textContent=t||"Failed to load Vitraun.",this.shadowRoot.appendChild(i),this.shadowRoot.appendChild(o)}}_renderIframe(t,e){if(this.shadowRoot){var i=this,o=r(this,"container-min-height","80vh");this.shadowRoot.innerHTML="";var l=document.createElement("style");l.textContent=":host { display:block; width:100%; min-height:"+o+"; box-sizing:border-box; }";var a=document.createElement("iframe");a.src=t,a.title="Vitraun VTO",a.style.cssText="width:100%;height:100%;border:0;min-height:"+o,a.setAttribute("allow","camera"),a.setAttribute("referrerpolicy","strict-origin-when-cross-origin"),a.onload=function(){e===i._renderVersion&&[0,50,150,400,1e3].forEach(function(s){setTimeout(function(){e===i._renderVersion&&i._sendConfigToIframe()},s)})},this.shadowRoot.appendChild(l),this.shadowRoot.appendChild(a)}}_render(){if(this.shadowRoot){this._renderVersion+=1;var t=this._renderVersion;if(!this._state.merchantId){this._setStatus("error",{message:"The merchant-id attribute is required."}),this._renderError("The merchant-id attribute is required.");return}if(!this._state.env){this._setStatus("error",{message:"The env attribute is required."}),this._renderError("The env attribute is required.");return}this._renderLoading(),this._initializeSessionIfNeeded().then(function(e){t===this._renderVersion&&this._renderIframe(e.iframeUrl,t)}.bind(this)).catch(function(e){t===this._renderVersion&&this._renderError(e&&e.message?e.message:"Failed to load Vitraun.")}.bind(this))}}open(){return this.style.display="",Promise.resolve()}close(){return this.style.display="none",Promise.resolve()}}typeof customElements!="undefined"&&!customElements.get("vitraun-vto")&&customElements.define("vitraun-vto",E)})();})();
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vitraun/webar",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vitraun WebAR widget as Web Component",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/clagils/tryon-new-version.git",
|
|
9
|
+
"directory": "vto-npm/webar"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/clagils/tryon-new-version/tree/main/vto-npm/webar",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/clagils/tryon-new-version/issues"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"private": false,
|
|
19
|
+
"type": "module",
|
|
20
|
+
"main": "./dist/index.min.js",
|
|
21
|
+
"module": "./dist/index.min.js",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"import": "./dist/index.min.js",
|
|
27
|
+
"default": "./dist/index.min.js"
|
|
28
|
+
},
|
|
29
|
+
"./react": {
|
|
30
|
+
"types": "./dist/react.d.ts",
|
|
31
|
+
"import": "./dist/react.min.js",
|
|
32
|
+
"default": "./dist/react.min.js"
|
|
33
|
+
},
|
|
34
|
+
"./widget.min.js": "./dist/widget.min.js",
|
|
35
|
+
"./widget": "./dist/widget.min.js",
|
|
36
|
+
"./runtime": "./dist/widget-runtime.min.js",
|
|
37
|
+
"./events": "./dist/events.min.js"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist/index.min.js",
|
|
41
|
+
"dist/index.d.ts",
|
|
42
|
+
"dist/events.min.js",
|
|
43
|
+
"dist/react.min.js",
|
|
44
|
+
"dist/react.d.ts",
|
|
45
|
+
"dist/widget.min.js",
|
|
46
|
+
"dist/widget-runtime.min.js"
|
|
47
|
+
],
|
|
48
|
+
"scripts": {
|
|
49
|
+
"prepare": "node ./scripts/prepare.mjs",
|
|
50
|
+
"build": "npm run clean && npm run build:types && npm run bundle:js",
|
|
51
|
+
"build:types": "node ./scripts/build-types.mjs",
|
|
52
|
+
"bundle:js": "node ./scripts/bundle-dist.mjs",
|
|
53
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
54
|
+
"lint": "eslint \"src/**/*.js\"",
|
|
55
|
+
"clean": "rm -rf dist",
|
|
56
|
+
"deploy:cdn": "node ./scripts/upload-cdn-assets.mjs"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@vitraun/core": "0.1.0",
|
|
60
|
+
"@types/node": "^20",
|
|
61
|
+
"@types/react": "^19.2.14",
|
|
62
|
+
"esbuild": "^0.25.9",
|
|
63
|
+
"eslint": "^9.39.1",
|
|
64
|
+
"typescript": "^5.9.3"
|
|
65
|
+
},
|
|
66
|
+
"peerDependencies": {
|
|
67
|
+
"react": ">=18",
|
|
68
|
+
"react-dom": ">=18"
|
|
69
|
+
}
|
|
70
|
+
}
|