@yourroad/sdk 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
- "use strict";var E=Object.defineProperty;var k=(r,t,e)=>t in r?E(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var o=(r,t,e)=>k(r,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S="https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/bootstrap-embed-access";function A(r){if(typeof r!="object"||r===null||Array.isArray(r))throw new Error("Invalid bootstrap response.");const{iframeUrl:t,expiresAt:e}=r;if(typeof t!="string"||t.trim()==="")throw new Error("Invalid bootstrap response.");let s;try{s=new URL(t)}catch{throw new Error("Invalid bootstrap response.")}if(s.protocol!=="http:"&&s.protocol!=="https:")throw new Error("Invalid bootstrap response.");if(typeof e!="string"||e.trim()===""||Number.isNaN(Date.parse(e)))throw new Error("Invalid bootstrap response.");return{iframeUrl:t,expiresAt:e}}async function O(r,t){const e=await fetch(S,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),credentials:"omit",cache:"no-store",signal:t});if(!e.ok)throw new Error("Bootstrap request was unsuccessful.");return A(await e.json())}const f=r=>Object.fromEntries(Object.entries(r??{}).filter(([,t])=>t!==void 0));function b(r,t){const e={...r,...f(t)};for(const s of["vehicle","dealer","page"])t[s]!==void 0&&(e[s]={...r[s],...f(t[s])});return e}const h=r=>b({},r??{}),a=1;function I(r){const t=new URL(r);if(t.protocol!=="https:"&&t.protocol!=="http:")throw new TypeError("The iframe URL must use HTTP(S).");return t.origin}const m=r=>{if(r===null||typeof r!="object")return!1;const t=Object.getPrototypeOf(r);return t===Object.prototype||t===null},R=r=>m(r)?r.source==="yourroad.embed"&&r.version===a&&r.type==="ready"&&r.payload===void 0&&(r.requestId===void 0||typeof r.requestId=="string"):!1,j=r=>m(r)&&Object.keys(r).length===3&&r.source==="yourroad.embed"&&r.version===a&&r.type==="journey_session_restart";class T{constructor(t,e,s,i,n){o(this,"ready",!1);o(this,"started",!1);o(this,"handleMessage",t=>{if(t.origin!==this.trustedRuntimeOrigin)return;const e=this.iframe.contentWindow;if(!(e===null||t.source!==e)){if(this.ready){j(t.data)&&this.onJourneySessionRestart();return}R(t.data)&&(this.ready=!0,this.post({source:"yourroad.sdk",version:a,type:"ack"}),this.post({source:"yourroad.sdk",version:a,type:"context",payload:h(this.getCurrentContext())}),this.sendJourneySession(this.getJourneySessionId()))}});this.iframe=t,this.trustedRuntimeOrigin=e,this.getCurrentContext=s,this.getJourneySessionId=i,this.onJourneySessionRestart=n}start(){this.started||(window.addEventListener("message",this.handleMessage),this.started=!0)}contextUpdated(t){this.ready&&this.post({source:"yourroad.sdk",version:a,type:"context_updated",payload:h(t)})}destroy(){this.started&&window.removeEventListener("message",this.handleMessage),this.started=!1,this.ready=!1}sendJourneySession(t){this.ready&&this.post({source:"yourroad.sdk",version:a,type:"journey_session",payload:{sessionId:t}})}post(t){const e=this.iframe.contentWindow;if(e!==null)try{e.postMessage(t,this.trustedRuntimeOrigin)}catch{}}}class c extends Error{constructor(e,s,i){super(s,i);o(this,"name","YourRoadError");this.code=e}}class _{constructor(){o(this,"listeners",new Map)}on(t,e){const s=this.listeners.get(t)??new Set;return s.add(e),this.listeners.set(t,s),()=>s.delete(e)}emit(t,e){var s;(s=this.listeners.get(t))==null||s.forEach(i=>i(e))}clear(){this.listeners.clear()}}class N{constructor(){o(this,"previous",null)}capture(){this.previous=document.activeElement instanceof HTMLElement?document.activeElement:null}moveTo(t){t.focus()}restore(){var t;(t=this.previous)!=null&&t.isConnected&&this.previous.focus(),this.previous=null}}class C{constructor(){o(this,"saved");o(this,"scrollX",0);o(this,"scrollY",0)}lock(){if(this.saved)return;const t=document.body.style;this.saved={position:t.position,top:t.top,left:t.left,right:t.right,width:t.width,overflow:t.overflow},this.scrollX=window.scrollX,this.scrollY=window.scrollY,Object.assign(t,{position:"fixed",top:`-${this.scrollY}px`,left:`-${this.scrollX}px`,right:"0",width:"100%",overflow:"hidden"})}unlock(){this.saved&&(Object.assign(document.body.style,this.saved),this.saved=void 0,window.scrollTo(this.scrollX,this.scrollY))}}class Y{constructor(t,e){o(this,"element");this.element=document.createElement("iframe"),this.element.dataset.yourroadFrame="",this.element.title="YourRoad pre-approval",this.element.src=t,this.element.addEventListener("error",e,{once:!0})}destroy(){this.element.remove()}}const L=2147483e3,D=`
2
- [data-yourroad-overlay-root] { all: initial; position: fixed; inset: 0; z-index: ${L}; display: block; font-family: system-ui, sans-serif; color: #111; }
1
+ "use strict";var k=Object.defineProperty;var A=(r,t,e)=>t in r?k(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var o=(r,t,e)=>A(r,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S="https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/bootstrap-embed-access";function O(r){if(typeof r!="object"||r===null||Array.isArray(r))throw new Error("Invalid bootstrap response.");const{iframeUrl:t,expiresAt:e}=r;if(typeof t!="string"||t.trim()==="")throw new Error("Invalid bootstrap response.");let s;try{s=new URL(t)}catch{throw new Error("Invalid bootstrap response.")}if(s.protocol!=="http:"&&s.protocol!=="https:")throw new Error("Invalid bootstrap response.");if(typeof e!="string"||e.trim()===""||Number.isNaN(Date.parse(e)))throw new Error("Invalid bootstrap response.");return{iframeUrl:t,expiresAt:e}}async function I(r,t){const e=await fetch(S,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),credentials:"omit",cache:"no-store",signal:t});if(!e.ok)throw new Error("Bootstrap request was unsuccessful.");return O(await e.json())}const y=r=>Object.fromEntries(Object.entries(r??{}).filter(([,t])=>t!==void 0));function m(r,t){const e={...r,...y(t)};for(const s of["vehicle","dealer","page"])t[s]!==void 0&&(e[s]={...r[s],...y(t[s])});return e}const u=r=>m({},r??{}),d=1;function R(r){const t=new URL(r);if(t.protocol!=="https:"&&t.protocol!=="http:")throw new TypeError("The iframe URL must use HTTP(S).");return t.origin}const v=r=>{if(r===null||typeof r!="object")return!1;const t=Object.getPrototypeOf(r);return t===Object.prototype||t===null},j=r=>v(r)?r.source==="yourroad.embed"&&r.version===d&&r.type==="ready"&&r.payload===void 0&&(r.requestId===void 0||typeof r.requestId=="string"):!1,T=r=>v(r)&&Object.keys(r).length===3&&r.source==="yourroad.embed"&&r.version===d&&r.type==="journey_session_restart";class _{constructor(t,e,s,i,a){o(this,"ready",!1);o(this,"started",!1);o(this,"handleMessage",t=>{if(t.origin!==this.trustedRuntimeOrigin)return;const e=this.iframe.contentWindow;if(!(e===null||t.source!==e)){if(this.ready){T(t.data)&&this.onJourneySessionRestart();return}j(t.data)&&(this.ready=!0,this.post({source:"yourroad.sdk",version:d,type:"ack"}),this.post({source:"yourroad.sdk",version:d,type:"context",payload:u(this.getCurrentContext())}),this.sendJourneySession(this.getJourneySessionId()))}});this.iframe=t,this.trustedRuntimeOrigin=e,this.getCurrentContext=s,this.getJourneySessionId=i,this.onJourneySessionRestart=a}start(){this.started||(window.addEventListener("message",this.handleMessage),this.started=!0)}contextUpdated(t){this.ready&&this.post({source:"yourroad.sdk",version:d,type:"context_updated",payload:u(t)})}destroy(){this.started&&window.removeEventListener("message",this.handleMessage),this.started=!1,this.ready=!1}sendJourneySession(t){this.ready&&this.post({source:"yourroad.sdk",version:d,type:"journey_session",payload:{sessionId:t}})}post(t){const e=this.iframe.contentWindow;if(e!==null)try{e.postMessage(t,this.trustedRuntimeOrigin)}catch{}}}class h extends Error{constructor(e,s,i){super(s,i);o(this,"name","YourRoadError");this.code=e}}class N{constructor(){o(this,"listeners",new Map)}on(t,e){const s=this.listeners.get(t)??new Set;return s.add(e),this.listeners.set(t,s),()=>s.delete(e)}emit(t,e){var s;(s=this.listeners.get(t))==null||s.forEach(i=>i(e))}clear(){this.listeners.clear()}}class C{constructor(){o(this,"previous",null)}capture(){this.previous=document.activeElement instanceof HTMLElement?document.activeElement:null}moveTo(t){t.focus()}restore(){var t;(t=this.previous)!=null&&t.isConnected&&this.previous.focus(),this.previous=null}}class L{constructor(){o(this,"saved");o(this,"scrollX",0);o(this,"scrollY",0)}lock(){if(this.saved)return;const t=document.body.style;this.saved={position:t.position,top:t.top,left:t.left,right:t.right,width:t.width,overflow:t.overflow},this.scrollX=window.scrollX,this.scrollY=window.scrollY,Object.assign(t,{position:"fixed",top:`-${this.scrollY}px`,left:`-${this.scrollX}px`,right:"0",width:"100%",overflow:"hidden"})}unlock(){this.saved&&(Object.assign(document.body.style,this.saved),this.saved=void 0,window.scrollTo(this.scrollX,this.scrollY))}}class Y{constructor(t,e){o(this,"element");this.element=document.createElement("iframe"),this.element.dataset.yourroadFrame="",this.element.title="YourRoad pre-approval",this.element.src=t,this.element.addEventListener("error",e,{once:!0})}destroy(){this.element.remove()}}const D=2147483e3,P=`
2
+ [data-yourroad-overlay-root] { all: initial; position: fixed; inset: 0; z-index: ${D}; display: block; font-family: system-ui, sans-serif; color: #111; }
3
3
  [data-yourroad-scrim] { all: initial; position: absolute; inset: 0; display: block; background: rgba(0, 0, 0, .55); }
4
- [data-yourroad-panel] { all: initial; box-sizing: border-box; position: absolute; inset-block: 0; inset-inline-end: 0; display: flex; flex-direction: column; width: min(520px, 92vw); height: 100vh; height: 100dvh; background: #fff; box-shadow: -8px 0 30px rgba(0,0,0,.2); }
4
+ [data-yourroad-panel] { all: initial; box-sizing: border-box; position: absolute; inset-block: 0; inset-inline-end: 0; display: flex; flex-direction: column; width: min(520px, 92vw); height: 100vh; height: 100dvh; padding-block-start: calc(max(12px, env(safe-area-inset-top)) + 56px); overflow: hidden; border-radius: 24px 0 0 24px; background: #fff; box-shadow: -8px 0 30px rgba(0,0,0,.2); }
5
5
  [data-yourroad-close] { all: unset; box-sizing: border-box; position: absolute; z-index: 1; inset-block-start: max(12px, env(safe-area-inset-top)); inset-inline-end: max(12px, env(safe-area-inset-right)); width: 44px; height: 44px; display: grid; place-items: center; border-radius: 999px; background: #fff; color: #111; box-shadow: 0 1px 8px rgba(0,0,0,.25); cursor: pointer; font: 28px/1 system-ui, sans-serif; }
6
6
  [data-yourroad-close]:focus-visible { outline: 3px solid #1769e0; outline-offset: 2px; }
7
- [data-yourroad-frame] { all: initial; box-sizing: border-box; display: block; width: 100%; height: 100%; border: 0; background: #fff; }
8
- @media (max-width: 600px) { [data-yourroad-panel] { width: 100vw; max-width: none; } }
9
- `;function K(){const r=document.head.querySelector("style[data-yourroad-sdk]");if(r)return r;const t=document.createElement("style");return t.dataset.yourroadSdk="",t.textContent=D,document.head.append(t),t}class P{constructor(t,e,s){o(this,"root");o(this,"closeButton");o(this,"iframe");o(this,"abort",new AbortController);K(),this.root=document.createElement("div"),this.root.dataset.yourroadOverlayRoot="",this.root.setAttribute("role","dialog"),this.root.setAttribute("aria-modal","true"),this.root.setAttribute("aria-label","YourRoad pre-approval");const i=document.createElement("div");i.dataset.yourroadScrim="";const n=document.createElement("div");n.dataset.yourroadPanel="",this.closeButton=document.createElement("button"),this.closeButton.type="button",this.closeButton.dataset.yourroadClose="",this.closeButton.setAttribute("aria-label","Close YourRoad"),this.closeButton.textContent="×",this.iframe=new Y(t,s),n.append(this.closeButton,this.iframe.element),this.root.append(i,n);const d=this.abort.signal;i.addEventListener("click",e,{signal:d}),this.closeButton.addEventListener("click",e,{signal:d}),document.addEventListener("keydown",l=>{l.key==="Escape"&&e()},{signal:d})}mount(){document.body.append(this.root)}destroy(){var t;this.abort.abort(),this.iframe.destroy(),this.root.remove(),document.querySelector("[data-yourroad-overlay-root]")||(t=document.head.querySelector("style[data-yourroad-sdk]"))==null||t.remove()}}const u="yr_journey_session_pre_approval_v1",p=r=>typeof r=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(r);function U(){try{return globalThis.localStorage}catch{return}}function B(r=U()){const t=()=>{try{r==null||r.removeItem(u)}catch{}};return{read(){let e;try{e=(r==null?void 0:r.getItem(u))??null}catch{return}if(e!==null){if(!p(e)){t();return}return e}},write(e){if(p(e))try{r==null||r.setItem(u,e)}catch{}},clear:t}}const J="https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/create-embed-journey-session",q="https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/probe-embed-journey-session",v=r=>{if(r===null||typeof r!="object")return!1;const t=Object.getPrototypeOf(r);return t===Object.prototype||t===null},w=r=>typeof r=="string"&&r.trim()!==""&&!Number.isNaN(Date.parse(r)),g=(r,t)=>({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),credentials:"omit",cache:"no-store",signal:t});async function y(r,t){const e=await fetch(J,g({partnerKey:r,surface:"pre-approval"},t));if(e.status!==201)throw new Error("Journey session creation was unsuccessful.");const s=await e.json();if(!v(s)||!p(s.sessionId)||!w(s.expiresAt))throw new Error("Invalid journey session response.");return s.sessionId}async function M(r,t){const e=await fetch(q,g({partnerKey:r,surface:"pre-approval",sessionId:t})),s=await e.json();if(!v(s))throw new Error("Invalid journey session probe response.");if(e.status===200&&s.status==="resumable"&&s.sessionId===t&&w(s.expiresAt))return{status:"resumable",sessionId:t};if(e.status===410&&s.status==="expired"&&s.code==="SESSION_EXPIRED")return{status:"expired"};if(e.status===404&&s.status==="invalid"&&s.code==="SESSION_INVALID")return{status:"invalid"};throw new Error("Journey session probe was unsuccessful.")}class F{constructor(t,e=B()){o(this,"state",{kind:"cold"});o(this,"restart");this.partnerKey=t,this.marker=e;const s=e.read();if(!s)return;const i=this.probe(s);this.state={kind:"probing",completion:i}}async resolveForOpen(t){if(this.state.kind==="probing"&&await this.state.completion,this.state.kind==="probe_failed")throw new Error("Journey session validity could not be established.");if(this.state.kind==="active"||this.state.kind==="expired")return this.state.sessionId;const e=await y(this.partnerKey,t);return this.marker.write(e),this.state={kind:"active",sessionId:e},e}restartExpired(t){if(this.state.kind!=="expired")return;if(this.restart)return this.restart;const e=y(this.partnerKey,t).then(s=>(this.marker.write(s),this.state={kind:"active",sessionId:s},s)).finally(()=>{this.restart===e&&(this.restart=void 0)});return this.restart=e,e}async probe(t){try{const e=await M(this.partnerKey,t);e.status==="resumable"?this.state={kind:"active",sessionId:t}:e.status==="expired"?(this.marker.clear(),this.state={kind:"expired",sessionId:t}):(this.marker.clear(),this.state={kind:"cold"})}catch{this.state={kind:"probe_failed"}}}}class X{constructor(t){o(this,"events",new _);o(this,"scroll",new C);o(this,"focus",new N);o(this,"overlay");o(this,"bridge");o(this,"context",{});o(this,"destroyed",!1);o(this,"opening");o(this,"bootstrapAbort");o(this,"restartAbort");o(this,"session");this.config=t,this.session=new F(t.partnerKey)}async open(t){if(this.assertUsable(),!t||t.surface!=="pre-approval")throw this.fail("INVALID_SURFACE",'The only supported surface is "pre-approval".');if(this.overlay)return;if(this.opening)return this.opening;this.context=h(t.context);const e=new AbortController;this.bootstrapAbort=e;const s=this.performOpen(t.surface,e);return this.opening=s,s}updateContext(t){var e;this.assertUsable(),this.context=b(this.context,t),(e=this.bridge)==null||e.contextUpdated(this.context)}close(){var t,e;this.assertUsable(),this.bootstrapAbort&&(this.bootstrapAbort.abort(),this.bootstrapAbort=void 0,this.opening=void 0),(t=this.restartAbort)==null||t.abort(),this.restartAbort=void 0,this.overlay&&((e=this.bridge)==null||e.destroy(),this.bridge=void 0,this.overlay.destroy(),this.overlay=void 0,this.scroll.unlock(),this.focus.restore(),this.events.emit("closed",void 0))}on(t,e){return this.assertUsable(),this.events.on(t,e)}destroy(){this.destroyed||(this.close(),this.events.clear(),this.context={},this.destroyed=!0)}async performOpen(t,e){var s,i;try{const[n,d]=await Promise.all([O({partnerKey:this.config.partnerKey,surface:t},e.signal),this.session.resolveForOpen(e.signal)]),{iframeUrl:l}=n;if(e.signal.aborted||this.destroyed||this.bootstrapAbort!==e)return;this.focus.capture();try{this.overlay=new P(l,()=>this.close(),()=>this.fail("IFRAME_LOAD_FAILED","The embedded experience failed to load.")),this.bridge=new T(this.overlay.iframe.element,I(l),()=>h(this.context),()=>d,()=>this.restartExpiredSession(this.bridge)),this.bridge.start(),this.overlay.mount(),this.scroll.lock(),this.focus.moveTo(this.overlay.closeButton),this.events.emit("opened",void 0)}catch(x){throw(s=this.bridge)==null||s.destroy(),this.bridge=void 0,(i=this.overlay)==null||i.destroy(),this.overlay=void 0,this.scroll.unlock(),this.focus.restore(),this.fail("OVERLAY_CREATION_FAILED","The YourRoad overlay could not be created.",x)}}catch(n){if(e.signal.aborted)return;throw n instanceof c?n:this.fail("BOOTSTRAP_FAILED","The YourRoad experience could not be started securely.",n)}finally{this.bootstrapAbort===e&&(this.bootstrapAbort=void 0,this.opening=void 0)}}restartExpiredSession(t){if(this.destroyed||t===void 0||t!==this.bridge||this.restartAbort)return;const e=new AbortController;this.restartAbort=e;const s=this.session.restartExpired(e.signal);if(!s){this.restartAbort=void 0;return}s.then(i=>{!this.destroyed&&!e.signal.aborted&&this.bridge===t&&t.sendJourneySession(i)}).catch(()=>{}).finally(()=>{this.restartAbort===e&&(this.restartAbort=void 0)})}assertUsable(){if(this.destroyed)throw new c("DESTROYED","This YourRoad SDK instance has been destroyed.")}fail(t,e,s){const i=new c(t,e,s===void 0?void 0:{cause:s});return this.events.emit("error",i),i}}function z(r){return new X(r)}class V{static init(t){if(!t||typeof t.partnerKey!="string"||t.partnerKey.trim()==="")throw new c("INVALID_INITIALISATION","partnerKey must be a non-empty string.");return z({partnerKey:t.partnerKey})}}exports.YourRoad=V;exports.YourRoadError=c;
7
+ [data-yourroad-frame] { all: initial; box-sizing: border-box; display: block; flex: 1 1 auto; min-height: 0; width: 100%; border: 0; background: #fff; }
8
+ @media (max-width: 600px) { [data-yourroad-panel] { inset-block-start: auto; inset-block-end: 0; inset-inline-end: 0; width: 100vw; max-width: none; height: 92vh; height: 92dvh; border-radius: 24px 24px 0 0; box-shadow: 0 -8px 30px rgba(0,0,0,.2); } }
9
+ `;function B(){const r=document.head.querySelector("style[data-yourroad-sdk]");if(r)return r;const t=document.createElement("style");return t.dataset.yourroadSdk="",t.textContent=P,document.head.append(t),t}class K{constructor(t,e,s){o(this,"root");o(this,"closeButton");o(this,"iframe");o(this,"abort",new AbortController);B(),this.root=document.createElement("div"),this.root.dataset.yourroadOverlayRoot="",this.root.setAttribute("role","dialog"),this.root.setAttribute("aria-modal","true"),this.root.setAttribute("aria-label","YourRoad pre-approval");const i=document.createElement("div");i.dataset.yourroadScrim="";const a=document.createElement("div");a.dataset.yourroadPanel="",this.closeButton=document.createElement("button"),this.closeButton.type="button",this.closeButton.dataset.yourroadClose="",this.closeButton.setAttribute("aria-label","Close YourRoad");const n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","24"),n.setAttribute("height","24"),n.setAttribute("fill","none"),n.setAttribute("stroke","currentColor"),n.setAttribute("stroke-width","2"),n.setAttribute("stroke-linecap","round"),n.setAttribute("aria-hidden","true");const c=document.createElementNS("http://www.w3.org/2000/svg","path");c.setAttribute("d","M6 6l12 12M18 6L6 18"),n.append(c),this.closeButton.append(n),this.iframe=new Y(t,s),a.append(this.closeButton,this.iframe.element),this.root.append(i,a);const l=this.abort.signal;i.addEventListener("click",e,{signal:l}),this.closeButton.addEventListener("click",e,{signal:l}),document.addEventListener("keydown",E=>{E.key==="Escape"&&e()},{signal:l})}mount(){document.body.append(this.root)}destroy(){var t;this.abort.abort(),this.iframe.destroy(),this.root.remove(),document.querySelector("[data-yourroad-overlay-root]")||(t=document.head.querySelector("style[data-yourroad-sdk]"))==null||t.remove()}}const p="yr_journey_session_pre_approval_v1",f=r=>typeof r=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(r);function U(){try{return globalThis.localStorage}catch{return}}function J(r=U()){const t=()=>{try{r==null||r.removeItem(p)}catch{}};return{read(){let e;try{e=(r==null?void 0:r.getItem(p))??null}catch{return}if(e!==null){if(!f(e)){t();return}return e}},write(e){if(f(e))try{r==null||r.setItem(p,e)}catch{}},clear:t}}const M="https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/create-embed-journey-session",q="https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/probe-embed-journey-session",w=r=>{if(r===null||typeof r!="object")return!1;const t=Object.getPrototypeOf(r);return t===Object.prototype||t===null},g=r=>typeof r=="string"&&r.trim()!==""&&!Number.isNaN(Date.parse(r)),x=(r,t)=>({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),credentials:"omit",cache:"no-store",signal:t});async function b(r,t){const e=await fetch(M,x({partnerKey:r,surface:"pre-approval"},t));if(e.status!==201)throw new Error("Journey session creation was unsuccessful.");const s=await e.json();if(!w(s)||!f(s.sessionId)||!g(s.expiresAt))throw new Error("Invalid journey session response.");return s.sessionId}async function F(r,t){const e=await fetch(q,x({partnerKey:r,surface:"pre-approval",sessionId:t})),s=await e.json();if(!w(s))throw new Error("Invalid journey session probe response.");if(e.status===200&&s.status==="resumable"&&s.sessionId===t&&g(s.expiresAt))return{status:"resumable",sessionId:t};if(e.status===410&&s.status==="expired"&&s.code==="SESSION_EXPIRED")return{status:"expired"};if(e.status===404&&s.status==="invalid"&&s.code==="SESSION_INVALID")return{status:"invalid"};throw new Error("Journey session probe was unsuccessful.")}class X{constructor(t,e=J()){o(this,"state",{kind:"cold"});o(this,"restart");this.partnerKey=t,this.marker=e;const s=e.read();if(!s)return;const i=this.probe(s);this.state={kind:"probing",completion:i}}async resolveForOpen(t){if(this.state.kind==="probing"&&await this.state.completion,this.state.kind==="probe_failed")throw new Error("Journey session validity could not be established.");if(this.state.kind==="active"||this.state.kind==="expired")return this.state.sessionId;const e=await b(this.partnerKey,t);return this.marker.write(e),this.state={kind:"active",sessionId:e},e}restartExpired(t){if(this.state.kind!=="expired")return;if(this.restart)return this.restart;const e=b(this.partnerKey,t).then(s=>(this.marker.write(s),this.state={kind:"active",sessionId:s},s)).finally(()=>{this.restart===e&&(this.restart=void 0)});return this.restart=e,e}async probe(t){try{const e=await F(this.partnerKey,t);e.status==="resumable"?this.state={kind:"active",sessionId:t}:e.status==="expired"?(this.marker.clear(),this.state={kind:"expired",sessionId:t}):(this.marker.clear(),this.state={kind:"cold"})}catch{this.state={kind:"probe_failed"}}}}class z{constructor(t){o(this,"events",new N);o(this,"scroll",new L);o(this,"focus",new C);o(this,"overlay");o(this,"bridge");o(this,"context",{});o(this,"destroyed",!1);o(this,"opening");o(this,"bootstrapAbort");o(this,"restartAbort");o(this,"session");this.config=t,this.session=new X(t.partnerKey)}async open(t){if(this.assertUsable(),!t||t.surface!=="pre-approval")throw this.fail("INVALID_SURFACE",'The only supported surface is "pre-approval".');if(this.overlay)return;if(this.opening)return this.opening;this.context=u(t.context);const e=new AbortController;this.bootstrapAbort=e;const s=this.performOpen(t.surface,e);return this.opening=s,s}updateContext(t){var e;this.assertUsable(),this.context=m(this.context,t),(e=this.bridge)==null||e.contextUpdated(this.context)}close(){var t,e;this.assertUsable(),this.bootstrapAbort&&(this.bootstrapAbort.abort(),this.bootstrapAbort=void 0,this.opening=void 0),(t=this.restartAbort)==null||t.abort(),this.restartAbort=void 0,this.overlay&&((e=this.bridge)==null||e.destroy(),this.bridge=void 0,this.overlay.destroy(),this.overlay=void 0,this.scroll.unlock(),this.focus.restore(),this.events.emit("closed",void 0))}on(t,e){return this.assertUsable(),this.events.on(t,e)}destroy(){this.destroyed||(this.close(),this.events.clear(),this.context={},this.destroyed=!0)}async performOpen(t,e){var s,i;try{const[a,n]=await Promise.all([I({partnerKey:this.config.partnerKey,surface:t},e.signal),this.session.resolveForOpen(e.signal)]),{iframeUrl:c}=a;if(e.signal.aborted||this.destroyed||this.bootstrapAbort!==e)return;this.focus.capture();try{this.overlay=new K(c,()=>this.close(),()=>this.fail("IFRAME_LOAD_FAILED","The embedded experience failed to load.")),this.bridge=new _(this.overlay.iframe.element,R(c),()=>u(this.context),()=>n,()=>this.restartExpiredSession(this.bridge)),this.bridge.start(),this.overlay.mount(),this.scroll.lock(),this.focus.moveTo(this.overlay.closeButton),this.events.emit("opened",void 0)}catch(l){throw(s=this.bridge)==null||s.destroy(),this.bridge=void 0,(i=this.overlay)==null||i.destroy(),this.overlay=void 0,this.scroll.unlock(),this.focus.restore(),this.fail("OVERLAY_CREATION_FAILED","The YourRoad overlay could not be created.",l)}}catch(a){if(e.signal.aborted)return;throw a instanceof h?a:this.fail("BOOTSTRAP_FAILED","The YourRoad experience could not be started securely.",a)}finally{this.bootstrapAbort===e&&(this.bootstrapAbort=void 0,this.opening=void 0)}}restartExpiredSession(t){if(this.destroyed||t===void 0||t!==this.bridge||this.restartAbort)return;const e=new AbortController;this.restartAbort=e;const s=this.session.restartExpired(e.signal);if(!s){this.restartAbort=void 0;return}s.then(i=>{!this.destroyed&&!e.signal.aborted&&this.bridge===t&&t.sendJourneySession(i)}).catch(()=>{}).finally(()=>{this.restartAbort===e&&(this.restartAbort=void 0)})}assertUsable(){if(this.destroyed)throw new h("DESTROYED","This YourRoad SDK instance has been destroyed.")}fail(t,e,s){const i=new h(t,e,s===void 0?void 0:{cause:s});return this.events.emit("error",i),i}}function V(r){return new z(r)}class ${static init(t){if(!t||typeof t.partnerKey!="string"||t.partnerKey.trim()==="")throw new h("INVALID_INITIALISATION","partnerKey must be a non-empty string.");return V({partnerKey:t.partnerKey})}}exports.YourRoad=$;exports.YourRoadError=h;
10
10
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/bootstrap/bootstrapClient.ts","../src/context/mergeContext.ts","../src/bridge/protocol.ts","../src/bridge/BridgeController.ts","../src/errors/YourRoadError.ts","../src/events/EventEmitter.ts","../src/lifecycle/focus.ts","../src/lifecycle/scrollLock.ts","../src/iframe/IframeController.ts","../src/overlay/styles.ts","../src/overlay/OverlayController.ts","../src/session/sessionMarker.ts","../src/session/sessionClient.ts","../src/session/SessionController.ts","../src/client/YourRoadClient.ts","../src/index.ts"],"sourcesContent":["import type { YourRoadSurface } from '../config/types';\n\nconst BOOTSTRAP_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/bootstrap-embed-access';\n\ninterface BootstrapRequest {\n partnerKey: string;\n surface: YourRoadSurface;\n}\n\nexport interface BootstrapResult {\n iframeUrl: string;\n expiresAt: string;\n}\n\nfunction validateResponse(value: unknown): BootstrapResult {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new Error('Invalid bootstrap response.');\n const { iframeUrl, expiresAt } = value as Record<string, unknown>;\n if (typeof iframeUrl !== 'string' || iframeUrl.trim() === '') throw new Error('Invalid bootstrap response.');\n let parsedUrl: URL;\n try { parsedUrl = new URL(iframeUrl); } catch { throw new Error('Invalid bootstrap response.'); }\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') throw new Error('Invalid bootstrap response.');\n if (typeof expiresAt !== 'string' || expiresAt.trim() === '' || Number.isNaN(Date.parse(expiresAt))) {\n throw new Error('Invalid bootstrap response.');\n }\n return { iframeUrl, expiresAt };\n}\n\nexport async function requestBootstrap(request: BootstrapRequest, signal: AbortSignal): Promise<BootstrapResult> {\n const response = await fetch(BOOTSTRAP_ENDPOINT, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n credentials: 'omit',\n cache: 'no-store',\n signal,\n });\n if (!response.ok) throw new Error('Bootstrap request was unsuccessful.');\n return validateResponse(await response.json());\n}\n","import type { YourRoadContext, YourRoadContextUpdate } from './types';\n\nconst defined = <T extends object>(value: T | undefined): Partial<T> =>\n Object.fromEntries(Object.entries(value ?? {}).filter(([, item]) => item !== undefined)) as Partial<T>;\n\n/** Merges known context sections. Explicit `undefined` values are ignored. */\nexport function mergeContext(current: YourRoadContext, update: YourRoadContextUpdate): YourRoadContext {\n const next: YourRoadContext = { ...current, ...defined(update) };\n for (const key of ['vehicle', 'dealer', 'page'] as const) {\n if (update[key] !== undefined) next[key] = { ...current[key], ...defined(update[key]) };\n }\n return next;\n}\n\nexport const copyContext = (context?: YourRoadContext): YourRoadContext => mergeContext({}, context ?? {});\n","import type { YourRoadContext } from '../context/types';\n\nexport const BRIDGE_VERSION = 1 as const;\n\nexport type BridgeMessage<T = unknown> = {\n source: 'yourroad.sdk' | 'yourroad.embed';\n version: typeof BRIDGE_VERSION;\n type: string;\n requestId?: string;\n payload?: T;\n};\n\nexport type SdkBridgeMessage =\n | BridgeMessage & { source: 'yourroad.sdk'; type: 'ack' }\n | BridgeMessage<YourRoadContext> & { source: 'yourroad.sdk'; type: 'context' | 'context_updated'; payload: YourRoadContext }\n | BridgeMessage<{ sessionId: string }> & { source: 'yourroad.sdk'; type: 'journey_session'; payload: { sessionId: string } };\n","import { copyContext } from '../context/mergeContext';\nimport type { YourRoadContext } from '../context/types';\nimport { BRIDGE_VERSION, type SdkBridgeMessage } from './protocol';\n\nexport function runtimeOriginFromIframeUrl(iframeUrl: string): string {\n const url = new URL(iframeUrl);\n if (url.protocol !== 'https:' && url.protocol !== 'http:') throw new TypeError('The iframe URL must use HTTP(S).');\n return url.origin;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object') return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\nconst isReadyMessage = (value: unknown): boolean => {\n if (!isPlainObject(value)) return false;\n return value.source === 'yourroad.embed'\n && value.version === BRIDGE_VERSION\n && value.type === 'ready'\n && value.payload === undefined\n && (value.requestId === undefined || typeof value.requestId === 'string');\n};\n\nconst isRestartMessage = (value: unknown): boolean => isPlainObject(value)\n && Object.keys(value).length === 3\n && value.source === 'yourroad.embed'\n && value.version === BRIDGE_VERSION\n && value.type === 'journey_session_restart';\n\nexport class BridgeController {\n private ready = false;\n private started = false;\n\n constructor(\n private readonly iframe: HTMLIFrameElement,\n private readonly trustedRuntimeOrigin: string,\n private readonly getCurrentContext: () => YourRoadContext,\n private readonly getJourneySessionId: () => string,\n private readonly onJourneySessionRestart: () => void,\n ) {}\n\n start(): void {\n if (this.started) return;\n window.addEventListener('message', this.handleMessage);\n this.started = true;\n }\n\n contextUpdated(currentContext: YourRoadContext): void {\n if (!this.ready) return;\n this.post({\n source: 'yourroad.sdk',\n version: BRIDGE_VERSION,\n type: 'context_updated',\n payload: copyContext(currentContext),\n });\n }\n\n destroy(): void {\n if (this.started) window.removeEventListener('message', this.handleMessage);\n this.started = false;\n this.ready = false;\n }\n\n private readonly handleMessage = (event: MessageEvent): void => {\n if (event.origin !== this.trustedRuntimeOrigin) return;\n const iframeWindow = this.iframe.contentWindow;\n if (iframeWindow === null || event.source !== iframeWindow) return;\n if (this.ready) {\n if (isRestartMessage(event.data)) this.onJourneySessionRestart();\n return;\n }\n if (!isReadyMessage(event.data)) return;\n this.ready = true;\n this.post({ source: 'yourroad.sdk', version: BRIDGE_VERSION, type: 'ack' });\n this.post({\n source: 'yourroad.sdk',\n version: BRIDGE_VERSION,\n type: 'context',\n payload: copyContext(this.getCurrentContext()),\n });\n this.sendJourneySession(this.getJourneySessionId());\n };\n\n sendJourneySession(sessionId: string): void {\n if (!this.ready) return;\n this.post({ source: 'yourroad.sdk', version: BRIDGE_VERSION, type: 'journey_session', payload: { sessionId } });\n }\n\n private post(message: SdkBridgeMessage): void {\n const iframeWindow = this.iframe.contentWindow;\n if (iframeWindow === null) return;\n try {\n iframeWindow.postMessage(message, this.trustedRuntimeOrigin);\n } catch {\n // The iframe may be removed concurrently; bridge delivery is best-effort.\n }\n }\n}\n","export type YourRoadErrorCode = 'INVALID_INITIALISATION' | 'INVALID_SURFACE' | 'DESTROYED' | 'BOOTSTRAP_FAILED' | 'OVERLAY_CREATION_FAILED' | 'IFRAME_LOAD_FAILED';\n\nexport class YourRoadError extends Error {\n readonly name = 'YourRoadError';\n constructor(public readonly code: YourRoadErrorCode, message: string, options?: ErrorOptions) {\n super(message, options);\n }\n}\n","export type Handler<T> = (payload: T) => void;\n\nexport class EventEmitter<Events extends object> {\n private listeners = new Map<keyof Events, Set<Handler<never>>>();\n\n on<K extends keyof Events>(event: K, handler: Handler<Events[K]>): () => void {\n const handlers = this.listeners.get(event) ?? new Set();\n handlers.add(handler as Handler<never>);\n this.listeners.set(event, handlers);\n return () => handlers.delete(handler as Handler<never>);\n }\n\n emit<K extends keyof Events>(event: K, payload: Events[K]): void {\n this.listeners.get(event)?.forEach((handler) => handler(payload as never));\n }\n\n clear(): void { this.listeners.clear(); }\n}\n","export class FocusLifecycle {\n private previous: HTMLElement | null = null;\n capture(): void { this.previous = document.activeElement instanceof HTMLElement ? document.activeElement : null; }\n moveTo(element: HTMLElement): void { element.focus(); }\n restore(): void {\n if (this.previous?.isConnected) this.previous.focus();\n this.previous = null;\n }\n}\n","interface SavedStyles { position: string; top: string; left: string; right: string; width: string; overflow: string }\n\nexport class ScrollLock {\n private saved?: SavedStyles;\n private scrollX = 0;\n private scrollY = 0;\n\n lock(): void {\n if (this.saved) return;\n const style = document.body.style;\n this.saved = { position: style.position, top: style.top, left: style.left, right: style.right, width: style.width, overflow: style.overflow };\n this.scrollX = window.scrollX;\n this.scrollY = window.scrollY;\n Object.assign(style, { position: 'fixed', top: `-${this.scrollY}px`, left: `-${this.scrollX}px`, right: '0', width: '100%', overflow: 'hidden' });\n }\n\n unlock(): void {\n if (!this.saved) return;\n Object.assign(document.body.style, this.saved);\n this.saved = undefined;\n window.scrollTo(this.scrollX, this.scrollY);\n }\n}\n","export class IframeController {\n readonly element: HTMLIFrameElement;\n constructor(source: string, onError: () => void) {\n this.element = document.createElement('iframe');\n this.element.dataset.yourroadFrame = '';\n this.element.title = 'YourRoad pre-approval';\n this.element.src = source;\n this.element.addEventListener('error', onError, { once: true });\n }\n destroy(): void { this.element.remove(); }\n}\n","export const SDK_Z_INDEX = 2147483000;\n\nexport const SDK_STYLES = `\n[data-yourroad-overlay-root] { all: initial; position: fixed; inset: 0; z-index: ${SDK_Z_INDEX}; display: block; font-family: system-ui, sans-serif; color: #111; }\n[data-yourroad-scrim] { all: initial; position: absolute; inset: 0; display: block; background: rgba(0, 0, 0, .55); }\n[data-yourroad-panel] { all: initial; box-sizing: border-box; position: absolute; inset-block: 0; inset-inline-end: 0; display: flex; flex-direction: column; width: min(520px, 92vw); height: 100vh; height: 100dvh; background: #fff; box-shadow: -8px 0 30px rgba(0,0,0,.2); }\n[data-yourroad-close] { all: unset; box-sizing: border-box; position: absolute; z-index: 1; inset-block-start: max(12px, env(safe-area-inset-top)); inset-inline-end: max(12px, env(safe-area-inset-right)); width: 44px; height: 44px; display: grid; place-items: center; border-radius: 999px; background: #fff; color: #111; box-shadow: 0 1px 8px rgba(0,0,0,.25); cursor: pointer; font: 28px/1 system-ui, sans-serif; }\n[data-yourroad-close]:focus-visible { outline: 3px solid #1769e0; outline-offset: 2px; }\n[data-yourroad-frame] { all: initial; box-sizing: border-box; display: block; width: 100%; height: 100%; border: 0; background: #fff; }\n@media (max-width: 600px) { [data-yourroad-panel] { width: 100vw; max-width: none; } }\n`;\n\nexport function ensureStyles(): HTMLStyleElement {\n const existing = document.head.querySelector<HTMLStyleElement>('style[data-yourroad-sdk]');\n if (existing) return existing;\n const style = document.createElement('style');\n style.dataset.yourroadSdk = '';\n style.textContent = SDK_STYLES;\n document.head.append(style);\n return style;\n}\n","import { IframeController } from '../iframe/IframeController';\nimport { ensureStyles } from './styles';\n\nexport class OverlayController {\n readonly root: HTMLDivElement;\n readonly closeButton: HTMLButtonElement;\n readonly iframe: IframeController;\n private readonly abort = new AbortController();\n\n constructor(source: string, onClose: () => void, onFrameError: () => void) {\n ensureStyles();\n this.root = document.createElement('div');\n this.root.dataset.yourroadOverlayRoot = '';\n this.root.setAttribute('role', 'dialog');\n this.root.setAttribute('aria-modal', 'true');\n this.root.setAttribute('aria-label', 'YourRoad pre-approval');\n const scrim = document.createElement('div');\n scrim.dataset.yourroadScrim = '';\n const panel = document.createElement('div');\n panel.dataset.yourroadPanel = '';\n this.closeButton = document.createElement('button');\n this.closeButton.type = 'button';\n this.closeButton.dataset.yourroadClose = '';\n this.closeButton.setAttribute('aria-label', 'Close YourRoad');\n this.closeButton.textContent = '×';\n this.iframe = new IframeController(source, onFrameError);\n panel.append(this.closeButton, this.iframe.element);\n this.root.append(scrim, panel);\n const signal = this.abort.signal;\n scrim.addEventListener('click', onClose, { signal });\n this.closeButton.addEventListener('click', onClose, { signal });\n document.addEventListener('keydown', (event) => { if (event.key === 'Escape') onClose(); }, { signal });\n }\n\n mount(): void { document.body.append(this.root); }\n destroy(): void {\n this.abort.abort();\n this.iframe.destroy();\n this.root.remove();\n if (!document.querySelector('[data-yourroad-overlay-root]')) {\n document.head.querySelector('style[data-yourroad-sdk]')?.remove();\n }\n }\n}\n","export const JOURNEY_SESSION_MARKER_KEY = 'yr_journey_session_pre_approval_v1';\n\nexport const isUuid = (value: unknown): value is string =>\n typeof value === 'string'\n && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n\nexport interface SessionMarker {\n read(): string | undefined;\n write(sessionId: string): void;\n clear(): void;\n}\n\ntype MarkerStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;\n\nfunction resolveStorage(): MarkerStorage | undefined {\n try { return globalThis.localStorage; } catch { return undefined; }\n}\n\nexport function createSessionMarker(storage: MarkerStorage | undefined = resolveStorage()): SessionMarker {\n const clear = (): void => {\n try { storage?.removeItem(JOURNEY_SESSION_MARKER_KEY); } catch { /* Storage is optional. */ }\n };\n return {\n read() {\n let value: string | null;\n try { value = storage?.getItem(JOURNEY_SESSION_MARKER_KEY) ?? null; } catch { return undefined; }\n if (value === null) return undefined;\n if (!isUuid(value)) { clear(); return undefined; }\n return value;\n },\n write(sessionId) {\n if (!isUuid(sessionId)) return;\n try { storage?.setItem(JOURNEY_SESSION_MARKER_KEY, sessionId); } catch { /* Keep the in-memory session usable. */ }\n },\n clear,\n };\n}\n","import { isUuid } from './sessionMarker';\n\nconst CREATE_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/create-embed-journey-session';\nconst PROBE_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/probe-embed-journey-session';\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object') return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\nconst isDate = (value: unknown): value is string => typeof value === 'string' && value.trim() !== '' && !Number.isNaN(Date.parse(value));\nconst options = (body: object, signal?: AbortSignal): RequestInit => ({\n method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body),\n credentials: 'omit', cache: 'no-store', signal,\n});\n\nexport async function createJourneySession(partnerKey: string, signal?: AbortSignal): Promise<string> {\n const response = await fetch(CREATE_ENDPOINT, options({ partnerKey, surface: 'pre-approval' }, signal));\n if (response.status !== 201) throw new Error('Journey session creation was unsuccessful.');\n const value: unknown = await response.json();\n if (!isPlainObject(value) || !isUuid(value.sessionId) || !isDate(value.expiresAt)) throw new Error('Invalid journey session response.');\n return value.sessionId;\n}\n\nexport type ProbeResult = { status: 'resumable'; sessionId: string } | { status: 'expired' } | { status: 'invalid' };\n\nexport async function probeJourneySession(partnerKey: string, sessionId: string): Promise<ProbeResult> {\n const response = await fetch(PROBE_ENDPOINT, options({ partnerKey, surface: 'pre-approval', sessionId }));\n const value: unknown = await response.json();\n if (!isPlainObject(value)) throw new Error('Invalid journey session probe response.');\n if (response.status === 200 && value.status === 'resumable' && value.sessionId === sessionId && isDate(value.expiresAt)) {\n return { status: 'resumable', sessionId };\n }\n if (response.status === 410 && value.status === 'expired' && value.code === 'SESSION_EXPIRED') return { status: 'expired' };\n if (response.status === 404 && value.status === 'invalid' && value.code === 'SESSION_INVALID') return { status: 'invalid' };\n throw new Error('Journey session probe was unsuccessful.');\n}\n","import { createJourneySession, probeJourneySession } from './sessionClient';\nimport { createSessionMarker, type SessionMarker } from './sessionMarker';\n\ntype State =\n | { kind: 'cold' }\n | { kind: 'probing'; completion: Promise<void> }\n | { kind: 'active'; sessionId: string }\n | { kind: 'expired'; sessionId: string }\n | { kind: 'probe_failed' };\n\nexport class SessionController {\n private state: State = { kind: 'cold' };\n private restart?: Promise<string>;\n\n constructor(private readonly partnerKey: string, private readonly marker: SessionMarker = createSessionMarker()) {\n const sessionId = marker.read();\n if (!sessionId) return;\n const completion = this.probe(sessionId);\n this.state = { kind: 'probing', completion };\n }\n\n async resolveForOpen(signal: AbortSignal): Promise<string> {\n if (this.state.kind === 'probing') await this.state.completion;\n if (this.state.kind === 'probe_failed') throw new Error('Journey session validity could not be established.');\n if (this.state.kind === 'active' || this.state.kind === 'expired') return this.state.sessionId;\n const sessionId = await createJourneySession(this.partnerKey, signal);\n this.marker.write(sessionId);\n this.state = { kind: 'active', sessionId };\n return sessionId;\n }\n\n restartExpired(signal: AbortSignal): Promise<string> | undefined {\n if (this.state.kind !== 'expired') return undefined;\n if (this.restart) return this.restart;\n const operation = createJourneySession(this.partnerKey, signal).then((sessionId) => {\n this.marker.write(sessionId);\n this.state = { kind: 'active', sessionId };\n return sessionId;\n }).finally(() => { if (this.restart === operation) this.restart = undefined; });\n this.restart = operation;\n return operation;\n }\n\n private async probe(sessionId: string): Promise<void> {\n try {\n const result = await probeJourneySession(this.partnerKey, sessionId);\n if (result.status === 'resumable') this.state = { kind: 'active', sessionId };\n else if (result.status === 'expired') { this.marker.clear(); this.state = { kind: 'expired', sessionId }; }\n else { this.marker.clear(); this.state = { kind: 'cold' }; }\n } catch { this.state = { kind: 'probe_failed' }; }\n }\n}\n","import type { YourRoadInitConfig, YourRoadSurface } from '../config/types';\nimport { requestBootstrap } from '../bootstrap/bootstrapClient';\nimport { BridgeController, runtimeOriginFromIframeUrl } from '../bridge/BridgeController';\nimport { copyContext, mergeContext } from '../context/mergeContext';\nimport type { YourRoadContext, YourRoadContextUpdate } from '../context/types';\nimport { YourRoadError } from '../errors/YourRoadError';\nimport { EventEmitter } from '../events/EventEmitter';\nimport { FocusLifecycle } from '../lifecycle/focus';\nimport { ScrollLock } from '../lifecycle/scrollLock';\nimport { OverlayController } from '../overlay/OverlayController';\nimport { SessionController } from '../session/SessionController';\n\nexport interface OpenOptions { surface: YourRoadSurface; context?: YourRoadContext }\nexport interface YourRoadEvents { opened: undefined; closed: undefined; error: YourRoadError }\n\nexport interface YourRoadClient {\n open(options: OpenOptions): Promise<void>;\n updateContext(update: YourRoadContextUpdate): void;\n close(): void;\n on<K extends keyof YourRoadEvents>(event: K, handler: (payload: YourRoadEvents[K]) => void): () => void;\n destroy(): void;\n}\n\nclass YourRoadClientImpl implements YourRoadClient {\n private readonly events = new EventEmitter<YourRoadEvents>();\n private readonly scroll = new ScrollLock();\n private readonly focus = new FocusLifecycle();\n private overlay?: OverlayController;\n private bridge?: BridgeController;\n private context: YourRoadContext = {};\n private destroyed = false;\n private opening?: Promise<void>;\n private bootstrapAbort?: AbortController;\n private restartAbort?: AbortController;\n private readonly session: SessionController;\n\n constructor(private readonly config: Readonly<YourRoadInitConfig>) {\n this.session = new SessionController(config.partnerKey);\n }\n\n async open(options: OpenOptions): Promise<void> {\n this.assertUsable();\n if (!options || options.surface !== 'pre-approval') throw this.fail('INVALID_SURFACE', 'The only supported surface is \"pre-approval\".');\n if (this.overlay) return;\n if (this.opening) return this.opening;\n this.context = copyContext(options.context);\n const abort = new AbortController();\n this.bootstrapAbort = abort;\n const operation = this.performOpen(options.surface, abort);\n this.opening = operation;\n return operation;\n }\n\n updateContext(update: YourRoadContextUpdate): void {\n this.assertUsable();\n this.context = mergeContext(this.context, update);\n this.bridge?.contextUpdated(this.context);\n }\n\n close(): void {\n this.assertUsable();\n if (this.bootstrapAbort) {\n this.bootstrapAbort.abort();\n this.bootstrapAbort = undefined;\n this.opening = undefined;\n }\n this.restartAbort?.abort();\n this.restartAbort = undefined;\n if (!this.overlay) return;\n this.bridge?.destroy();\n this.bridge = undefined;\n this.overlay.destroy();\n this.overlay = undefined;\n this.scroll.unlock();\n this.focus.restore();\n this.events.emit('closed', undefined);\n }\n\n on<K extends keyof YourRoadEvents>(event: K, handler: (payload: YourRoadEvents[K]) => void): () => void {\n this.assertUsable();\n return this.events.on(event, handler);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.close();\n this.events.clear();\n this.context = {};\n this.destroyed = true;\n }\n\n private async performOpen(surface: YourRoadSurface, abort: AbortController): Promise<void> {\n try {\n const [bootstrap, sessionId] = await Promise.all([\n requestBootstrap({ partnerKey: this.config.partnerKey, surface }, abort.signal),\n this.session.resolveForOpen(abort.signal),\n ]);\n const { iframeUrl } = bootstrap;\n if (abort.signal.aborted || this.destroyed || this.bootstrapAbort !== abort) return;\n this.focus.capture();\n try {\n this.overlay = new OverlayController(iframeUrl, () => this.close(), () => this.fail('IFRAME_LOAD_FAILED', 'The embedded experience failed to load.'));\n this.bridge = new BridgeController(\n this.overlay.iframe.element,\n runtimeOriginFromIframeUrl(iframeUrl),\n () => copyContext(this.context),\n () => sessionId,\n () => this.restartExpiredSession(this.bridge),\n );\n this.bridge.start();\n this.overlay.mount();\n this.scroll.lock();\n this.focus.moveTo(this.overlay.closeButton);\n this.events.emit('opened', undefined);\n } catch (cause) {\n this.bridge?.destroy();\n this.bridge = undefined;\n this.overlay?.destroy();\n this.overlay = undefined;\n this.scroll.unlock();\n this.focus.restore();\n throw this.fail('OVERLAY_CREATION_FAILED', 'The YourRoad overlay could not be created.', cause);\n }\n } catch (cause) {\n if (abort.signal.aborted) return;\n if (cause instanceof YourRoadError) throw cause;\n throw this.fail('BOOTSTRAP_FAILED', 'The YourRoad experience could not be started securely.', cause);\n } finally {\n if (this.bootstrapAbort === abort) {\n this.bootstrapAbort = undefined;\n this.opening = undefined;\n }\n }\n }\n\n private restartExpiredSession(bridge: BridgeController | undefined): void {\n if (this.destroyed || bridge === undefined || bridge !== this.bridge || this.restartAbort) return;\n const restartAbort = new AbortController();\n this.restartAbort = restartAbort;\n const operation = this.session.restartExpired(restartAbort.signal);\n if (!operation) { this.restartAbort = undefined; return; }\n void operation.then((sessionId) => {\n if (!this.destroyed && !restartAbort.signal.aborted && this.bridge === bridge) bridge.sendJourneySession(sessionId);\n }).catch(() => { /* The runtime may offer a later explicit retry. */ }).finally(() => {\n if (this.restartAbort === restartAbort) this.restartAbort = undefined;\n });\n }\n\n private assertUsable(): void { if (this.destroyed) throw new YourRoadError('DESTROYED', 'This YourRoad SDK instance has been destroyed.'); }\n private fail(code: ConstructorParameters<typeof YourRoadError>[0], message: string, cause?: unknown): YourRoadError {\n const error = new YourRoadError(code, message, cause === undefined ? undefined : { cause });\n this.events.emit('error', error);\n return error;\n }\n}\n\nexport function createYourRoadClient(config: Readonly<YourRoadInitConfig>): YourRoadClient {\n return new YourRoadClientImpl(config);\n}\n","import { createYourRoadClient, type YourRoadClient } from './client/YourRoadClient';\nimport type { YourRoadInitConfig } from './config/types';\nimport { YourRoadError } from './errors/YourRoadError';\n\nexport type { OpenOptions, YourRoadClient, YourRoadEvents } from './client/YourRoadClient';\nexport type { YourRoadInitConfig, YourRoadSurface } from './config/types';\nexport type { DealerContext, PageContext, VehicleContext, YourRoadContext, YourRoadContextUpdate } from './context/types';\nexport { YourRoadError };\n\nexport class YourRoad {\n static init(config: YourRoadInitConfig): YourRoadClient {\n if (!config || typeof config.partnerKey !== 'string' || config.partnerKey.trim() === '') {\n throw new YourRoadError('INVALID_INITIALISATION', 'partnerKey must be a non-empty string.');\n }\n return createYourRoadClient({ partnerKey: config.partnerKey });\n }\n}\n"],"names":["BOOTSTRAP_ENDPOINT","validateResponse","value","iframeUrl","expiresAt","parsedUrl","requestBootstrap","request","signal","response","defined","item","mergeContext","current","update","next","key","copyContext","context","BRIDGE_VERSION","runtimeOriginFromIframeUrl","url","isPlainObject","prototype","isReadyMessage","isRestartMessage","BridgeController","iframe","trustedRuntimeOrigin","getCurrentContext","getJourneySessionId","onJourneySessionRestart","__publicField","event","iframeWindow","currentContext","sessionId","message","YourRoadError","code","options","EventEmitter","handler","handlers","payload","_a","FocusLifecycle","element","ScrollLock","style","IframeController","source","onError","SDK_Z_INDEX","SDK_STYLES","ensureStyles","existing","OverlayController","onClose","onFrameError","scrim","panel","JOURNEY_SESSION_MARKER_KEY","isUuid","resolveStorage","createSessionMarker","storage","clear","CREATE_ENDPOINT","PROBE_ENDPOINT","isDate","body","createJourneySession","partnerKey","probeJourneySession","SessionController","marker","completion","operation","result","YourRoadClientImpl","config","abort","_b","surface","bootstrap","cause","bridge","restartAbort","error","createYourRoadClient","YourRoad"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/bootstrap/bootstrapClient.ts","../src/context/mergeContext.ts","../src/bridge/protocol.ts","../src/bridge/BridgeController.ts","../src/errors/YourRoadError.ts","../src/events/EventEmitter.ts","../src/lifecycle/focus.ts","../src/lifecycle/scrollLock.ts","../src/iframe/IframeController.ts","../src/overlay/styles.ts","../src/overlay/OverlayController.ts","../src/session/sessionMarker.ts","../src/session/sessionClient.ts","../src/session/SessionController.ts","../src/client/YourRoadClient.ts","../src/index.ts"],"sourcesContent":["import type { YourRoadSurface } from '../config/types';\n\nconst BOOTSTRAP_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/bootstrap-embed-access';\n\ninterface BootstrapRequest {\n partnerKey: string;\n surface: YourRoadSurface;\n}\n\nexport interface BootstrapResult {\n iframeUrl: string;\n expiresAt: string;\n}\n\nfunction validateResponse(value: unknown): BootstrapResult {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new Error('Invalid bootstrap response.');\n const { iframeUrl, expiresAt } = value as Record<string, unknown>;\n if (typeof iframeUrl !== 'string' || iframeUrl.trim() === '') throw new Error('Invalid bootstrap response.');\n let parsedUrl: URL;\n try { parsedUrl = new URL(iframeUrl); } catch { throw new Error('Invalid bootstrap response.'); }\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') throw new Error('Invalid bootstrap response.');\n if (typeof expiresAt !== 'string' || expiresAt.trim() === '' || Number.isNaN(Date.parse(expiresAt))) {\n throw new Error('Invalid bootstrap response.');\n }\n return { iframeUrl, expiresAt };\n}\n\nexport async function requestBootstrap(request: BootstrapRequest, signal: AbortSignal): Promise<BootstrapResult> {\n const response = await fetch(BOOTSTRAP_ENDPOINT, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n credentials: 'omit',\n cache: 'no-store',\n signal,\n });\n if (!response.ok) throw new Error('Bootstrap request was unsuccessful.');\n return validateResponse(await response.json());\n}\n","import type { YourRoadContext, YourRoadContextUpdate } from './types';\n\nconst defined = <T extends object>(value: T | undefined): Partial<T> =>\n Object.fromEntries(Object.entries(value ?? {}).filter(([, item]) => item !== undefined)) as Partial<T>;\n\n/** Merges known context sections. Explicit `undefined` values are ignored. */\nexport function mergeContext(current: YourRoadContext, update: YourRoadContextUpdate): YourRoadContext {\n const next: YourRoadContext = { ...current, ...defined(update) };\n for (const key of ['vehicle', 'dealer', 'page'] as const) {\n if (update[key] !== undefined) next[key] = { ...current[key], ...defined(update[key]) };\n }\n return next;\n}\n\nexport const copyContext = (context?: YourRoadContext): YourRoadContext => mergeContext({}, context ?? {});\n","import type { YourRoadContext } from '../context/types';\n\nexport const BRIDGE_VERSION = 1 as const;\n\nexport type BridgeMessage<T = unknown> = {\n source: 'yourroad.sdk' | 'yourroad.embed';\n version: typeof BRIDGE_VERSION;\n type: string;\n requestId?: string;\n payload?: T;\n};\n\nexport type SdkBridgeMessage =\n | BridgeMessage & { source: 'yourroad.sdk'; type: 'ack' }\n | BridgeMessage<YourRoadContext> & { source: 'yourroad.sdk'; type: 'context' | 'context_updated'; payload: YourRoadContext }\n | BridgeMessage<{ sessionId: string }> & { source: 'yourroad.sdk'; type: 'journey_session'; payload: { sessionId: string } };\n","import { copyContext } from '../context/mergeContext';\nimport type { YourRoadContext } from '../context/types';\nimport { BRIDGE_VERSION, type SdkBridgeMessage } from './protocol';\n\nexport function runtimeOriginFromIframeUrl(iframeUrl: string): string {\n const url = new URL(iframeUrl);\n if (url.protocol !== 'https:' && url.protocol !== 'http:') throw new TypeError('The iframe URL must use HTTP(S).');\n return url.origin;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object') return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\nconst isReadyMessage = (value: unknown): boolean => {\n if (!isPlainObject(value)) return false;\n return value.source === 'yourroad.embed'\n && value.version === BRIDGE_VERSION\n && value.type === 'ready'\n && value.payload === undefined\n && (value.requestId === undefined || typeof value.requestId === 'string');\n};\n\nconst isRestartMessage = (value: unknown): boolean => isPlainObject(value)\n && Object.keys(value).length === 3\n && value.source === 'yourroad.embed'\n && value.version === BRIDGE_VERSION\n && value.type === 'journey_session_restart';\n\nexport class BridgeController {\n private ready = false;\n private started = false;\n\n constructor(\n private readonly iframe: HTMLIFrameElement,\n private readonly trustedRuntimeOrigin: string,\n private readonly getCurrentContext: () => YourRoadContext,\n private readonly getJourneySessionId: () => string,\n private readonly onJourneySessionRestart: () => void,\n ) {}\n\n start(): void {\n if (this.started) return;\n window.addEventListener('message', this.handleMessage);\n this.started = true;\n }\n\n contextUpdated(currentContext: YourRoadContext): void {\n if (!this.ready) return;\n this.post({\n source: 'yourroad.sdk',\n version: BRIDGE_VERSION,\n type: 'context_updated',\n payload: copyContext(currentContext),\n });\n }\n\n destroy(): void {\n if (this.started) window.removeEventListener('message', this.handleMessage);\n this.started = false;\n this.ready = false;\n }\n\n private readonly handleMessage = (event: MessageEvent): void => {\n if (event.origin !== this.trustedRuntimeOrigin) return;\n const iframeWindow = this.iframe.contentWindow;\n if (iframeWindow === null || event.source !== iframeWindow) return;\n if (this.ready) {\n if (isRestartMessage(event.data)) this.onJourneySessionRestart();\n return;\n }\n if (!isReadyMessage(event.data)) return;\n this.ready = true;\n this.post({ source: 'yourroad.sdk', version: BRIDGE_VERSION, type: 'ack' });\n this.post({\n source: 'yourroad.sdk',\n version: BRIDGE_VERSION,\n type: 'context',\n payload: copyContext(this.getCurrentContext()),\n });\n this.sendJourneySession(this.getJourneySessionId());\n };\n\n sendJourneySession(sessionId: string): void {\n if (!this.ready) return;\n this.post({ source: 'yourroad.sdk', version: BRIDGE_VERSION, type: 'journey_session', payload: { sessionId } });\n }\n\n private post(message: SdkBridgeMessage): void {\n const iframeWindow = this.iframe.contentWindow;\n if (iframeWindow === null) return;\n try {\n iframeWindow.postMessage(message, this.trustedRuntimeOrigin);\n } catch {\n // The iframe may be removed concurrently; bridge delivery is best-effort.\n }\n }\n}\n","export type YourRoadErrorCode = 'INVALID_INITIALISATION' | 'INVALID_SURFACE' | 'DESTROYED' | 'BOOTSTRAP_FAILED' | 'OVERLAY_CREATION_FAILED' | 'IFRAME_LOAD_FAILED';\n\nexport class YourRoadError extends Error {\n readonly name = 'YourRoadError';\n constructor(public readonly code: YourRoadErrorCode, message: string, options?: ErrorOptions) {\n super(message, options);\n }\n}\n","export type Handler<T> = (payload: T) => void;\n\nexport class EventEmitter<Events extends object> {\n private listeners = new Map<keyof Events, Set<Handler<never>>>();\n\n on<K extends keyof Events>(event: K, handler: Handler<Events[K]>): () => void {\n const handlers = this.listeners.get(event) ?? new Set();\n handlers.add(handler as Handler<never>);\n this.listeners.set(event, handlers);\n return () => handlers.delete(handler as Handler<never>);\n }\n\n emit<K extends keyof Events>(event: K, payload: Events[K]): void {\n this.listeners.get(event)?.forEach((handler) => handler(payload as never));\n }\n\n clear(): void { this.listeners.clear(); }\n}\n","export class FocusLifecycle {\n private previous: HTMLElement | null = null;\n capture(): void { this.previous = document.activeElement instanceof HTMLElement ? document.activeElement : null; }\n moveTo(element: HTMLElement): void { element.focus(); }\n restore(): void {\n if (this.previous?.isConnected) this.previous.focus();\n this.previous = null;\n }\n}\n","interface SavedStyles { position: string; top: string; left: string; right: string; width: string; overflow: string }\n\nexport class ScrollLock {\n private saved?: SavedStyles;\n private scrollX = 0;\n private scrollY = 0;\n\n lock(): void {\n if (this.saved) return;\n const style = document.body.style;\n this.saved = { position: style.position, top: style.top, left: style.left, right: style.right, width: style.width, overflow: style.overflow };\n this.scrollX = window.scrollX;\n this.scrollY = window.scrollY;\n Object.assign(style, { position: 'fixed', top: `-${this.scrollY}px`, left: `-${this.scrollX}px`, right: '0', width: '100%', overflow: 'hidden' });\n }\n\n unlock(): void {\n if (!this.saved) return;\n Object.assign(document.body.style, this.saved);\n this.saved = undefined;\n window.scrollTo(this.scrollX, this.scrollY);\n }\n}\n","export class IframeController {\n readonly element: HTMLIFrameElement;\n constructor(source: string, onError: () => void) {\n this.element = document.createElement('iframe');\n this.element.dataset.yourroadFrame = '';\n this.element.title = 'YourRoad pre-approval';\n this.element.src = source;\n this.element.addEventListener('error', onError, { once: true });\n }\n destroy(): void { this.element.remove(); }\n}\n","export const SDK_Z_INDEX = 2147483000;\n\nexport const SDK_STYLES = `\n[data-yourroad-overlay-root] { all: initial; position: fixed; inset: 0; z-index: ${SDK_Z_INDEX}; display: block; font-family: system-ui, sans-serif; color: #111; }\n[data-yourroad-scrim] { all: initial; position: absolute; inset: 0; display: block; background: rgba(0, 0, 0, .55); }\n[data-yourroad-panel] { all: initial; box-sizing: border-box; position: absolute; inset-block: 0; inset-inline-end: 0; display: flex; flex-direction: column; width: min(520px, 92vw); height: 100vh; height: 100dvh; padding-block-start: calc(max(12px, env(safe-area-inset-top)) + 56px); overflow: hidden; border-radius: 24px 0 0 24px; background: #fff; box-shadow: -8px 0 30px rgba(0,0,0,.2); }\n[data-yourroad-close] { all: unset; box-sizing: border-box; position: absolute; z-index: 1; inset-block-start: max(12px, env(safe-area-inset-top)); inset-inline-end: max(12px, env(safe-area-inset-right)); width: 44px; height: 44px; display: grid; place-items: center; border-radius: 999px; background: #fff; color: #111; box-shadow: 0 1px 8px rgba(0,0,0,.25); cursor: pointer; font: 28px/1 system-ui, sans-serif; }\n[data-yourroad-close]:focus-visible { outline: 3px solid #1769e0; outline-offset: 2px; }\n[data-yourroad-frame] { all: initial; box-sizing: border-box; display: block; flex: 1 1 auto; min-height: 0; width: 100%; border: 0; background: #fff; }\n@media (max-width: 600px) { [data-yourroad-panel] { inset-block-start: auto; inset-block-end: 0; inset-inline-end: 0; width: 100vw; max-width: none; height: 92vh; height: 92dvh; border-radius: 24px 24px 0 0; box-shadow: 0 -8px 30px rgba(0,0,0,.2); } }\n`;\n\nexport function ensureStyles(): HTMLStyleElement {\n const existing = document.head.querySelector<HTMLStyleElement>('style[data-yourroad-sdk]');\n if (existing) return existing;\n const style = document.createElement('style');\n style.dataset.yourroadSdk = '';\n style.textContent = SDK_STYLES;\n document.head.append(style);\n return style;\n}\n","import { IframeController } from '../iframe/IframeController';\nimport { ensureStyles } from './styles';\n\nexport class OverlayController {\n readonly root: HTMLDivElement;\n readonly closeButton: HTMLButtonElement;\n readonly iframe: IframeController;\n private readonly abort = new AbortController();\n\n constructor(source: string, onClose: () => void, onFrameError: () => void) {\n ensureStyles();\n this.root = document.createElement('div');\n this.root.dataset.yourroadOverlayRoot = '';\n this.root.setAttribute('role', 'dialog');\n this.root.setAttribute('aria-modal', 'true');\n this.root.setAttribute('aria-label', 'YourRoad pre-approval');\n const scrim = document.createElement('div');\n scrim.dataset.yourroadScrim = '';\n const panel = document.createElement('div');\n panel.dataset.yourroadPanel = '';\n this.closeButton = document.createElement('button');\n this.closeButton.type = 'button';\n this.closeButton.dataset.yourroadClose = '';\n this.closeButton.setAttribute('aria-label', 'Close YourRoad');\n const closeIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n closeIcon.setAttribute('viewBox', '0 0 24 24');\n closeIcon.setAttribute('width', '24');\n closeIcon.setAttribute('height', '24');\n closeIcon.setAttribute('fill', 'none');\n closeIcon.setAttribute('stroke', 'currentColor');\n closeIcon.setAttribute('stroke-width', '2');\n closeIcon.setAttribute('stroke-linecap', 'round');\n closeIcon.setAttribute('aria-hidden', 'true');\n const closeIconPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n closeIconPath.setAttribute('d', 'M6 6l12 12M18 6L6 18');\n closeIcon.append(closeIconPath);\n this.closeButton.append(closeIcon);\n this.iframe = new IframeController(source, onFrameError);\n panel.append(this.closeButton, this.iframe.element);\n this.root.append(scrim, panel);\n const signal = this.abort.signal;\n scrim.addEventListener('click', onClose, { signal });\n this.closeButton.addEventListener('click', onClose, { signal });\n document.addEventListener('keydown', (event) => { if (event.key === 'Escape') onClose(); }, { signal });\n }\n\n mount(): void { document.body.append(this.root); }\n destroy(): void {\n this.abort.abort();\n this.iframe.destroy();\n this.root.remove();\n if (!document.querySelector('[data-yourroad-overlay-root]')) {\n document.head.querySelector('style[data-yourroad-sdk]')?.remove();\n }\n }\n}\n","export const JOURNEY_SESSION_MARKER_KEY = 'yr_journey_session_pre_approval_v1';\n\nexport const isUuid = (value: unknown): value is string =>\n typeof value === 'string'\n && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n\nexport interface SessionMarker {\n read(): string | undefined;\n write(sessionId: string): void;\n clear(): void;\n}\n\ntype MarkerStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;\n\nfunction resolveStorage(): MarkerStorage | undefined {\n try { return globalThis.localStorage; } catch { return undefined; }\n}\n\nexport function createSessionMarker(storage: MarkerStorage | undefined = resolveStorage()): SessionMarker {\n const clear = (): void => {\n try { storage?.removeItem(JOURNEY_SESSION_MARKER_KEY); } catch { /* Storage is optional. */ }\n };\n return {\n read() {\n let value: string | null;\n try { value = storage?.getItem(JOURNEY_SESSION_MARKER_KEY) ?? null; } catch { return undefined; }\n if (value === null) return undefined;\n if (!isUuid(value)) { clear(); return undefined; }\n return value;\n },\n write(sessionId) {\n if (!isUuid(sessionId)) return;\n try { storage?.setItem(JOURNEY_SESSION_MARKER_KEY, sessionId); } catch { /* Keep the in-memory session usable. */ }\n },\n clear,\n };\n}\n","import { isUuid } from './sessionMarker';\n\nconst CREATE_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/create-embed-journey-session';\nconst PROBE_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/probe-embed-journey-session';\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object') return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\nconst isDate = (value: unknown): value is string => typeof value === 'string' && value.trim() !== '' && !Number.isNaN(Date.parse(value));\nconst options = (body: object, signal?: AbortSignal): RequestInit => ({\n method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body),\n credentials: 'omit', cache: 'no-store', signal,\n});\n\nexport async function createJourneySession(partnerKey: string, signal?: AbortSignal): Promise<string> {\n const response = await fetch(CREATE_ENDPOINT, options({ partnerKey, surface: 'pre-approval' }, signal));\n if (response.status !== 201) throw new Error('Journey session creation was unsuccessful.');\n const value: unknown = await response.json();\n if (!isPlainObject(value) || !isUuid(value.sessionId) || !isDate(value.expiresAt)) throw new Error('Invalid journey session response.');\n return value.sessionId;\n}\n\nexport type ProbeResult = { status: 'resumable'; sessionId: string } | { status: 'expired' } | { status: 'invalid' };\n\nexport async function probeJourneySession(partnerKey: string, sessionId: string): Promise<ProbeResult> {\n const response = await fetch(PROBE_ENDPOINT, options({ partnerKey, surface: 'pre-approval', sessionId }));\n const value: unknown = await response.json();\n if (!isPlainObject(value)) throw new Error('Invalid journey session probe response.');\n if (response.status === 200 && value.status === 'resumable' && value.sessionId === sessionId && isDate(value.expiresAt)) {\n return { status: 'resumable', sessionId };\n }\n if (response.status === 410 && value.status === 'expired' && value.code === 'SESSION_EXPIRED') return { status: 'expired' };\n if (response.status === 404 && value.status === 'invalid' && value.code === 'SESSION_INVALID') return { status: 'invalid' };\n throw new Error('Journey session probe was unsuccessful.');\n}\n","import { createJourneySession, probeJourneySession } from './sessionClient';\nimport { createSessionMarker, type SessionMarker } from './sessionMarker';\n\ntype State =\n | { kind: 'cold' }\n | { kind: 'probing'; completion: Promise<void> }\n | { kind: 'active'; sessionId: string }\n | { kind: 'expired'; sessionId: string }\n | { kind: 'probe_failed' };\n\nexport class SessionController {\n private state: State = { kind: 'cold' };\n private restart?: Promise<string>;\n\n constructor(private readonly partnerKey: string, private readonly marker: SessionMarker = createSessionMarker()) {\n const sessionId = marker.read();\n if (!sessionId) return;\n const completion = this.probe(sessionId);\n this.state = { kind: 'probing', completion };\n }\n\n async resolveForOpen(signal: AbortSignal): Promise<string> {\n if (this.state.kind === 'probing') await this.state.completion;\n if (this.state.kind === 'probe_failed') throw new Error('Journey session validity could not be established.');\n if (this.state.kind === 'active' || this.state.kind === 'expired') return this.state.sessionId;\n const sessionId = await createJourneySession(this.partnerKey, signal);\n this.marker.write(sessionId);\n this.state = { kind: 'active', sessionId };\n return sessionId;\n }\n\n restartExpired(signal: AbortSignal): Promise<string> | undefined {\n if (this.state.kind !== 'expired') return undefined;\n if (this.restart) return this.restart;\n const operation = createJourneySession(this.partnerKey, signal).then((sessionId) => {\n this.marker.write(sessionId);\n this.state = { kind: 'active', sessionId };\n return sessionId;\n }).finally(() => { if (this.restart === operation) this.restart = undefined; });\n this.restart = operation;\n return operation;\n }\n\n private async probe(sessionId: string): Promise<void> {\n try {\n const result = await probeJourneySession(this.partnerKey, sessionId);\n if (result.status === 'resumable') this.state = { kind: 'active', sessionId };\n else if (result.status === 'expired') { this.marker.clear(); this.state = { kind: 'expired', sessionId }; }\n else { this.marker.clear(); this.state = { kind: 'cold' }; }\n } catch { this.state = { kind: 'probe_failed' }; }\n }\n}\n","import type { YourRoadInitConfig, YourRoadSurface } from '../config/types';\nimport { requestBootstrap } from '../bootstrap/bootstrapClient';\nimport { BridgeController, runtimeOriginFromIframeUrl } from '../bridge/BridgeController';\nimport { copyContext, mergeContext } from '../context/mergeContext';\nimport type { YourRoadContext, YourRoadContextUpdate } from '../context/types';\nimport { YourRoadError } from '../errors/YourRoadError';\nimport { EventEmitter } from '../events/EventEmitter';\nimport { FocusLifecycle } from '../lifecycle/focus';\nimport { ScrollLock } from '../lifecycle/scrollLock';\nimport { OverlayController } from '../overlay/OverlayController';\nimport { SessionController } from '../session/SessionController';\n\nexport interface OpenOptions { surface: YourRoadSurface; context?: YourRoadContext }\nexport interface YourRoadEvents { opened: undefined; closed: undefined; error: YourRoadError }\n\nexport interface YourRoadClient {\n open(options: OpenOptions): Promise<void>;\n updateContext(update: YourRoadContextUpdate): void;\n close(): void;\n on<K extends keyof YourRoadEvents>(event: K, handler: (payload: YourRoadEvents[K]) => void): () => void;\n destroy(): void;\n}\n\nclass YourRoadClientImpl implements YourRoadClient {\n private readonly events = new EventEmitter<YourRoadEvents>();\n private readonly scroll = new ScrollLock();\n private readonly focus = new FocusLifecycle();\n private overlay?: OverlayController;\n private bridge?: BridgeController;\n private context: YourRoadContext = {};\n private destroyed = false;\n private opening?: Promise<void>;\n private bootstrapAbort?: AbortController;\n private restartAbort?: AbortController;\n private readonly session: SessionController;\n\n constructor(private readonly config: Readonly<YourRoadInitConfig>) {\n this.session = new SessionController(config.partnerKey);\n }\n\n async open(options: OpenOptions): Promise<void> {\n this.assertUsable();\n if (!options || options.surface !== 'pre-approval') throw this.fail('INVALID_SURFACE', 'The only supported surface is \"pre-approval\".');\n if (this.overlay) return;\n if (this.opening) return this.opening;\n this.context = copyContext(options.context);\n const abort = new AbortController();\n this.bootstrapAbort = abort;\n const operation = this.performOpen(options.surface, abort);\n this.opening = operation;\n return operation;\n }\n\n updateContext(update: YourRoadContextUpdate): void {\n this.assertUsable();\n this.context = mergeContext(this.context, update);\n this.bridge?.contextUpdated(this.context);\n }\n\n close(): void {\n this.assertUsable();\n if (this.bootstrapAbort) {\n this.bootstrapAbort.abort();\n this.bootstrapAbort = undefined;\n this.opening = undefined;\n }\n this.restartAbort?.abort();\n this.restartAbort = undefined;\n if (!this.overlay) return;\n this.bridge?.destroy();\n this.bridge = undefined;\n this.overlay.destroy();\n this.overlay = undefined;\n this.scroll.unlock();\n this.focus.restore();\n this.events.emit('closed', undefined);\n }\n\n on<K extends keyof YourRoadEvents>(event: K, handler: (payload: YourRoadEvents[K]) => void): () => void {\n this.assertUsable();\n return this.events.on(event, handler);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.close();\n this.events.clear();\n this.context = {};\n this.destroyed = true;\n }\n\n private async performOpen(surface: YourRoadSurface, abort: AbortController): Promise<void> {\n try {\n const [bootstrap, sessionId] = await Promise.all([\n requestBootstrap({ partnerKey: this.config.partnerKey, surface }, abort.signal),\n this.session.resolveForOpen(abort.signal),\n ]);\n const { iframeUrl } = bootstrap;\n if (abort.signal.aborted || this.destroyed || this.bootstrapAbort !== abort) return;\n this.focus.capture();\n try {\n this.overlay = new OverlayController(iframeUrl, () => this.close(), () => this.fail('IFRAME_LOAD_FAILED', 'The embedded experience failed to load.'));\n this.bridge = new BridgeController(\n this.overlay.iframe.element,\n runtimeOriginFromIframeUrl(iframeUrl),\n () => copyContext(this.context),\n () => sessionId,\n () => this.restartExpiredSession(this.bridge),\n );\n this.bridge.start();\n this.overlay.mount();\n this.scroll.lock();\n this.focus.moveTo(this.overlay.closeButton);\n this.events.emit('opened', undefined);\n } catch (cause) {\n this.bridge?.destroy();\n this.bridge = undefined;\n this.overlay?.destroy();\n this.overlay = undefined;\n this.scroll.unlock();\n this.focus.restore();\n throw this.fail('OVERLAY_CREATION_FAILED', 'The YourRoad overlay could not be created.', cause);\n }\n } catch (cause) {\n if (abort.signal.aborted) return;\n if (cause instanceof YourRoadError) throw cause;\n throw this.fail('BOOTSTRAP_FAILED', 'The YourRoad experience could not be started securely.', cause);\n } finally {\n if (this.bootstrapAbort === abort) {\n this.bootstrapAbort = undefined;\n this.opening = undefined;\n }\n }\n }\n\n private restartExpiredSession(bridge: BridgeController | undefined): void {\n if (this.destroyed || bridge === undefined || bridge !== this.bridge || this.restartAbort) return;\n const restartAbort = new AbortController();\n this.restartAbort = restartAbort;\n const operation = this.session.restartExpired(restartAbort.signal);\n if (!operation) { this.restartAbort = undefined; return; }\n void operation.then((sessionId) => {\n if (!this.destroyed && !restartAbort.signal.aborted && this.bridge === bridge) bridge.sendJourneySession(sessionId);\n }).catch(() => { /* The runtime may offer a later explicit retry. */ }).finally(() => {\n if (this.restartAbort === restartAbort) this.restartAbort = undefined;\n });\n }\n\n private assertUsable(): void { if (this.destroyed) throw new YourRoadError('DESTROYED', 'This YourRoad SDK instance has been destroyed.'); }\n private fail(code: ConstructorParameters<typeof YourRoadError>[0], message: string, cause?: unknown): YourRoadError {\n const error = new YourRoadError(code, message, cause === undefined ? undefined : { cause });\n this.events.emit('error', error);\n return error;\n }\n}\n\nexport function createYourRoadClient(config: Readonly<YourRoadInitConfig>): YourRoadClient {\n return new YourRoadClientImpl(config);\n}\n","import { createYourRoadClient, type YourRoadClient } from './client/YourRoadClient';\nimport type { YourRoadInitConfig } from './config/types';\nimport { YourRoadError } from './errors/YourRoadError';\n\nexport type { OpenOptions, YourRoadClient, YourRoadEvents } from './client/YourRoadClient';\nexport type { YourRoadInitConfig, YourRoadSurface } from './config/types';\nexport type { DealerContext, PageContext, VehicleContext, YourRoadContext, YourRoadContextUpdate } from './context/types';\nexport { YourRoadError };\n\nexport class YourRoad {\n static init(config: YourRoadInitConfig): YourRoadClient {\n if (!config || typeof config.partnerKey !== 'string' || config.partnerKey.trim() === '') {\n throw new YourRoadError('INVALID_INITIALISATION', 'partnerKey must be a non-empty string.');\n }\n return createYourRoadClient({ partnerKey: config.partnerKey });\n }\n}\n"],"names":["BOOTSTRAP_ENDPOINT","validateResponse","value","iframeUrl","expiresAt","parsedUrl","requestBootstrap","request","signal","response","defined","item","mergeContext","current","update","next","key","copyContext","context","BRIDGE_VERSION","runtimeOriginFromIframeUrl","url","isPlainObject","prototype","isReadyMessage","isRestartMessage","BridgeController","iframe","trustedRuntimeOrigin","getCurrentContext","getJourneySessionId","onJourneySessionRestart","__publicField","event","iframeWindow","currentContext","sessionId","message","YourRoadError","code","options","EventEmitter","handler","handlers","payload","_a","FocusLifecycle","element","ScrollLock","style","IframeController","source","onError","SDK_Z_INDEX","SDK_STYLES","ensureStyles","existing","OverlayController","onClose","onFrameError","scrim","panel","closeIcon","closeIconPath","JOURNEY_SESSION_MARKER_KEY","isUuid","resolveStorage","createSessionMarker","storage","clear","CREATE_ENDPOINT","PROBE_ENDPOINT","isDate","body","createJourneySession","partnerKey","probeJourneySession","SessionController","marker","completion","operation","result","YourRoadClientImpl","config","abort","_b","surface","bootstrap","cause","bridge","restartAbort","error","createYourRoadClient","YourRoad"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- var E = Object.defineProperty;
2
- var k = (s, t, e) => t in s ? E(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
3
- var o = (s, t, e) => k(s, typeof t != "symbol" ? t + "" : t, e);
1
+ var k = Object.defineProperty;
2
+ var A = (s, t, e) => t in s ? k(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
3
+ var o = (s, t, e) => A(s, typeof t != "symbol" ? t + "" : t, e);
4
4
  const S = "https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/bootstrap-embed-access";
5
- function A(s) {
5
+ function I(s) {
6
6
  if (typeof s != "object" || s === null || Array.isArray(s)) throw new Error("Invalid bootstrap response.");
7
7
  const { iframeUrl: t, expiresAt: e } = s;
8
8
  if (typeof t != "string" || t.trim() === "") throw new Error("Invalid bootstrap response.");
@@ -27,28 +27,28 @@ async function O(s, t) {
27
27
  signal: t
28
28
  });
29
29
  if (!e.ok) throw new Error("Bootstrap request was unsuccessful.");
30
- return A(await e.json());
30
+ return I(await e.json());
31
31
  }
32
- const f = (s) => Object.fromEntries(Object.entries(s ?? {}).filter(([, t]) => t !== void 0));
33
- function b(s, t) {
34
- const e = { ...s, ...f(t) };
32
+ const y = (s) => Object.fromEntries(Object.entries(s ?? {}).filter(([, t]) => t !== void 0));
33
+ function m(s, t) {
34
+ const e = { ...s, ...y(t) };
35
35
  for (const r of ["vehicle", "dealer", "page"])
36
- t[r] !== void 0 && (e[r] = { ...s[r], ...f(t[r]) });
36
+ t[r] !== void 0 && (e[r] = { ...s[r], ...y(t[r]) });
37
37
  return e;
38
38
  }
39
- const h = (s) => b({}, s ?? {}), a = 1;
40
- function I(s) {
39
+ const u = (s) => m({}, s ?? {}), d = 1;
40
+ function R(s) {
41
41
  const t = new URL(s);
42
42
  if (t.protocol !== "https:" && t.protocol !== "http:") throw new TypeError("The iframe URL must use HTTP(S).");
43
43
  return t.origin;
44
44
  }
45
- const m = (s) => {
45
+ const v = (s) => {
46
46
  if (s === null || typeof s != "object") return !1;
47
47
  const t = Object.getPrototypeOf(s);
48
48
  return t === Object.prototype || t === null;
49
- }, R = (s) => m(s) ? s.source === "yourroad.embed" && s.version === a && s.type === "ready" && s.payload === void 0 && (s.requestId === void 0 || typeof s.requestId == "string") : !1, j = (s) => m(s) && Object.keys(s).length === 3 && s.source === "yourroad.embed" && s.version === a && s.type === "journey_session_restart";
50
- class T {
51
- constructor(t, e, r, i, n) {
49
+ }, j = (s) => v(s) ? s.source === "yourroad.embed" && s.version === d && s.type === "ready" && s.payload === void 0 && (s.requestId === void 0 || typeof s.requestId == "string") : !1, T = (s) => v(s) && Object.keys(s).length === 3 && s.source === "yourroad.embed" && s.version === d && s.type === "journey_session_restart";
50
+ class _ {
51
+ constructor(t, e, r, i, a) {
52
52
  o(this, "ready", !1);
53
53
  o(this, "started", !1);
54
54
  o(this, "handleMessage", (t) => {
@@ -56,18 +56,18 @@ class T {
56
56
  const e = this.iframe.contentWindow;
57
57
  if (!(e === null || t.source !== e)) {
58
58
  if (this.ready) {
59
- j(t.data) && this.onJourneySessionRestart();
59
+ T(t.data) && this.onJourneySessionRestart();
60
60
  return;
61
61
  }
62
- R(t.data) && (this.ready = !0, this.post({ source: "yourroad.sdk", version: a, type: "ack" }), this.post({
62
+ j(t.data) && (this.ready = !0, this.post({ source: "yourroad.sdk", version: d, type: "ack" }), this.post({
63
63
  source: "yourroad.sdk",
64
- version: a,
64
+ version: d,
65
65
  type: "context",
66
- payload: h(this.getCurrentContext())
66
+ payload: u(this.getCurrentContext())
67
67
  }), this.sendJourneySession(this.getJourneySessionId()));
68
68
  }
69
69
  });
70
- this.iframe = t, this.trustedRuntimeOrigin = e, this.getCurrentContext = r, this.getJourneySessionId = i, this.onJourneySessionRestart = n;
70
+ this.iframe = t, this.trustedRuntimeOrigin = e, this.getCurrentContext = r, this.getJourneySessionId = i, this.onJourneySessionRestart = a;
71
71
  }
72
72
  start() {
73
73
  this.started || (window.addEventListener("message", this.handleMessage), this.started = !0);
@@ -75,16 +75,16 @@ class T {
75
75
  contextUpdated(t) {
76
76
  this.ready && this.post({
77
77
  source: "yourroad.sdk",
78
- version: a,
78
+ version: d,
79
79
  type: "context_updated",
80
- payload: h(t)
80
+ payload: u(t)
81
81
  });
82
82
  }
83
83
  destroy() {
84
84
  this.started && window.removeEventListener("message", this.handleMessage), this.started = !1, this.ready = !1;
85
85
  }
86
86
  sendJourneySession(t) {
87
- this.ready && this.post({ source: "yourroad.sdk", version: a, type: "journey_session", payload: { sessionId: t } });
87
+ this.ready && this.post({ source: "yourroad.sdk", version: d, type: "journey_session", payload: { sessionId: t } });
88
88
  }
89
89
  post(t) {
90
90
  const e = this.iframe.contentWindow;
@@ -95,14 +95,14 @@ class T {
95
95
  }
96
96
  }
97
97
  }
98
- class l extends Error {
98
+ class h extends Error {
99
99
  constructor(e, r, i) {
100
100
  super(r, i);
101
101
  o(this, "name", "YourRoadError");
102
102
  this.code = e;
103
103
  }
104
104
  }
105
- class _ {
105
+ class N {
106
106
  constructor() {
107
107
  o(this, "listeners", /* @__PURE__ */ new Map());
108
108
  }
@@ -118,7 +118,7 @@ class _ {
118
118
  this.listeners.clear();
119
119
  }
120
120
  }
121
- class N {
121
+ class C {
122
122
  constructor() {
123
123
  o(this, "previous", null);
124
124
  }
@@ -133,7 +133,7 @@ class N {
133
133
  (t = this.previous) != null && t.isConnected && this.previous.focus(), this.previous = null;
134
134
  }
135
135
  }
136
- class C {
136
+ class L {
137
137
  constructor() {
138
138
  o(this, "saved");
139
139
  o(this, "scrollX", 0);
@@ -148,7 +148,7 @@ class C {
148
148
  this.saved && (Object.assign(document.body.style, this.saved), this.saved = void 0, window.scrollTo(this.scrollX, this.scrollY));
149
149
  }
150
150
  }
151
- class L {
151
+ class D {
152
152
  constructor(t, e) {
153
153
  o(this, "element");
154
154
  this.element = document.createElement("iframe"), this.element.dataset.yourroadFrame = "", this.element.title = "YourRoad pre-approval", this.element.src = t, this.element.addEventListener("error", e, { once: !0 });
@@ -157,22 +157,22 @@ class L {
157
157
  this.element.remove();
158
158
  }
159
159
  }
160
- const D = 2147483e3, Y = `
161
- [data-yourroad-overlay-root] { all: initial; position: fixed; inset: 0; z-index: ${D}; display: block; font-family: system-ui, sans-serif; color: #111; }
160
+ const Y = 2147483e3, B = `
161
+ [data-yourroad-overlay-root] { all: initial; position: fixed; inset: 0; z-index: ${Y}; display: block; font-family: system-ui, sans-serif; color: #111; }
162
162
  [data-yourroad-scrim] { all: initial; position: absolute; inset: 0; display: block; background: rgba(0, 0, 0, .55); }
163
- [data-yourroad-panel] { all: initial; box-sizing: border-box; position: absolute; inset-block: 0; inset-inline-end: 0; display: flex; flex-direction: column; width: min(520px, 92vw); height: 100vh; height: 100dvh; background: #fff; box-shadow: -8px 0 30px rgba(0,0,0,.2); }
163
+ [data-yourroad-panel] { all: initial; box-sizing: border-box; position: absolute; inset-block: 0; inset-inline-end: 0; display: flex; flex-direction: column; width: min(520px, 92vw); height: 100vh; height: 100dvh; padding-block-start: calc(max(12px, env(safe-area-inset-top)) + 56px); overflow: hidden; border-radius: 24px 0 0 24px; background: #fff; box-shadow: -8px 0 30px rgba(0,0,0,.2); }
164
164
  [data-yourroad-close] { all: unset; box-sizing: border-box; position: absolute; z-index: 1; inset-block-start: max(12px, env(safe-area-inset-top)); inset-inline-end: max(12px, env(safe-area-inset-right)); width: 44px; height: 44px; display: grid; place-items: center; border-radius: 999px; background: #fff; color: #111; box-shadow: 0 1px 8px rgba(0,0,0,.25); cursor: pointer; font: 28px/1 system-ui, sans-serif; }
165
165
  [data-yourroad-close]:focus-visible { outline: 3px solid #1769e0; outline-offset: 2px; }
166
- [data-yourroad-frame] { all: initial; box-sizing: border-box; display: block; width: 100%; height: 100%; border: 0; background: #fff; }
167
- @media (max-width: 600px) { [data-yourroad-panel] { width: 100vw; max-width: none; } }
166
+ [data-yourroad-frame] { all: initial; box-sizing: border-box; display: block; flex: 1 1 auto; min-height: 0; width: 100%; border: 0; background: #fff; }
167
+ @media (max-width: 600px) { [data-yourroad-panel] { inset-block-start: auto; inset-block-end: 0; inset-inline-end: 0; width: 100vw; max-width: none; height: 92vh; height: 92dvh; border-radius: 24px 24px 0 0; box-shadow: 0 -8px 30px rgba(0,0,0,.2); } }
168
168
  `;
169
169
  function K() {
170
170
  const s = document.head.querySelector("style[data-yourroad-sdk]");
171
171
  if (s) return s;
172
172
  const t = document.createElement("style");
173
- return t.dataset.yourroadSdk = "", t.textContent = Y, document.head.append(t), t;
173
+ return t.dataset.yourroadSdk = "", t.textContent = B, document.head.append(t), t;
174
174
  }
175
- class U {
175
+ class P {
176
176
  constructor(t, e, r) {
177
177
  o(this, "root");
178
178
  o(this, "closeButton");
@@ -181,12 +181,16 @@ class U {
181
181
  K(), this.root = document.createElement("div"), this.root.dataset.yourroadOverlayRoot = "", this.root.setAttribute("role", "dialog"), this.root.setAttribute("aria-modal", "true"), this.root.setAttribute("aria-label", "YourRoad pre-approval");
182
182
  const i = document.createElement("div");
183
183
  i.dataset.yourroadScrim = "";
184
- const n = document.createElement("div");
185
- n.dataset.yourroadPanel = "", this.closeButton = document.createElement("button"), this.closeButton.type = "button", this.closeButton.dataset.yourroadClose = "", this.closeButton.setAttribute("aria-label", "Close YourRoad"), this.closeButton.textContent = "×", this.iframe = new L(t, r), n.append(this.closeButton, this.iframe.element), this.root.append(i, n);
186
- const d = this.abort.signal;
187
- i.addEventListener("click", e, { signal: d }), this.closeButton.addEventListener("click", e, { signal: d }), document.addEventListener("keydown", (c) => {
188
- c.key === "Escape" && e();
189
- }, { signal: d });
184
+ const a = document.createElement("div");
185
+ a.dataset.yourroadPanel = "", this.closeButton = document.createElement("button"), this.closeButton.type = "button", this.closeButton.dataset.yourroadClose = "", this.closeButton.setAttribute("aria-label", "Close YourRoad");
186
+ const n = document.createElementNS("http://www.w3.org/2000/svg", "svg");
187
+ n.setAttribute("viewBox", "0 0 24 24"), n.setAttribute("width", "24"), n.setAttribute("height", "24"), n.setAttribute("fill", "none"), n.setAttribute("stroke", "currentColor"), n.setAttribute("stroke-width", "2"), n.setAttribute("stroke-linecap", "round"), n.setAttribute("aria-hidden", "true");
188
+ const c = document.createElementNS("http://www.w3.org/2000/svg", "path");
189
+ c.setAttribute("d", "M6 6l12 12M18 6L6 18"), n.append(c), this.closeButton.append(n), this.iframe = new D(t, r), a.append(this.closeButton, this.iframe.element), this.root.append(i, a);
190
+ const l = this.abort.signal;
191
+ i.addEventListener("click", e, { signal: l }), this.closeButton.addEventListener("click", e, { signal: l }), document.addEventListener("keydown", (E) => {
192
+ E.key === "Escape" && e();
193
+ }, { signal: l });
190
194
  }
191
195
  mount() {
192
196
  document.body.append(this.root);
@@ -196,18 +200,18 @@ class U {
196
200
  this.abort.abort(), this.iframe.destroy(), this.root.remove(), document.querySelector("[data-yourroad-overlay-root]") || (t = document.head.querySelector("style[data-yourroad-sdk]")) == null || t.remove();
197
201
  }
198
202
  }
199
- const u = "yr_journey_session_pre_approval_v1", p = (s) => typeof s == "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(s);
200
- function B() {
203
+ const p = "yr_journey_session_pre_approval_v1", f = (s) => typeof s == "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(s);
204
+ function U() {
201
205
  try {
202
206
  return globalThis.localStorage;
203
207
  } catch {
204
208
  return;
205
209
  }
206
210
  }
207
- function P(s = B()) {
211
+ function J(s = U()) {
208
212
  const t = () => {
209
213
  try {
210
- s == null || s.removeItem(u);
214
+ s == null || s.removeItem(p);
211
215
  } catch {
212
216
  }
213
217
  };
@@ -215,12 +219,12 @@ function P(s = B()) {
215
219
  read() {
216
220
  let e;
217
221
  try {
218
- e = (s == null ? void 0 : s.getItem(u)) ?? null;
222
+ e = (s == null ? void 0 : s.getItem(p)) ?? null;
219
223
  } catch {
220
224
  return;
221
225
  }
222
226
  if (e !== null) {
223
- if (!p(e)) {
227
+ if (!f(e)) {
224
228
  t();
225
229
  return;
226
230
  }
@@ -228,20 +232,20 @@ function P(s = B()) {
228
232
  }
229
233
  },
230
234
  write(e) {
231
- if (p(e))
235
+ if (f(e))
232
236
  try {
233
- s == null || s.setItem(u, e);
237
+ s == null || s.setItem(p, e);
234
238
  } catch {
235
239
  }
236
240
  },
237
241
  clear: t
238
242
  };
239
243
  }
240
- const J = "https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/create-embed-journey-session", q = "https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/probe-embed-journey-session", v = (s) => {
244
+ const q = "https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/create-embed-journey-session", M = "https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/probe-embed-journey-session", w = (s) => {
241
245
  if (s === null || typeof s != "object") return !1;
242
246
  const t = Object.getPrototypeOf(s);
243
247
  return t === Object.prototype || t === null;
244
- }, w = (s) => typeof s == "string" && s.trim() !== "" && !Number.isNaN(Date.parse(s)), x = (s, t) => ({
248
+ }, x = (s) => typeof s == "string" && s.trim() !== "" && !Number.isNaN(Date.parse(s)), g = (s, t) => ({
245
249
  method: "POST",
246
250
  headers: { "Content-Type": "application/json" },
247
251
  body: JSON.stringify(s),
@@ -249,24 +253,24 @@ const J = "https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/create-embed-jo
249
253
  cache: "no-store",
250
254
  signal: t
251
255
  });
252
- async function y(s, t) {
253
- const e = await fetch(J, x({ partnerKey: s, surface: "pre-approval" }, t));
256
+ async function b(s, t) {
257
+ const e = await fetch(q, g({ partnerKey: s, surface: "pre-approval" }, t));
254
258
  if (e.status !== 201) throw new Error("Journey session creation was unsuccessful.");
255
259
  const r = await e.json();
256
- if (!v(r) || !p(r.sessionId) || !w(r.expiresAt)) throw new Error("Invalid journey session response.");
260
+ if (!w(r) || !f(r.sessionId) || !x(r.expiresAt)) throw new Error("Invalid journey session response.");
257
261
  return r.sessionId;
258
262
  }
259
- async function M(s, t) {
260
- const e = await fetch(q, x({ partnerKey: s, surface: "pre-approval", sessionId: t })), r = await e.json();
261
- if (!v(r)) throw new Error("Invalid journey session probe response.");
262
- if (e.status === 200 && r.status === "resumable" && r.sessionId === t && w(r.expiresAt))
263
+ async function F(s, t) {
264
+ const e = await fetch(M, g({ partnerKey: s, surface: "pre-approval", sessionId: t })), r = await e.json();
265
+ if (!w(r)) throw new Error("Invalid journey session probe response.");
266
+ if (e.status === 200 && r.status === "resumable" && r.sessionId === t && x(r.expiresAt))
263
267
  return { status: "resumable", sessionId: t };
264
268
  if (e.status === 410 && r.status === "expired" && r.code === "SESSION_EXPIRED") return { status: "expired" };
265
269
  if (e.status === 404 && r.status === "invalid" && r.code === "SESSION_INVALID") return { status: "invalid" };
266
270
  throw new Error("Journey session probe was unsuccessful.");
267
271
  }
268
- class F {
269
- constructor(t, e = P()) {
272
+ class X {
273
+ constructor(t, e = J()) {
270
274
  o(this, "state", { kind: "cold" });
271
275
  o(this, "restart");
272
276
  this.partnerKey = t, this.marker = e;
@@ -278,31 +282,31 @@ class F {
278
282
  async resolveForOpen(t) {
279
283
  if (this.state.kind === "probing" && await this.state.completion, this.state.kind === "probe_failed") throw new Error("Journey session validity could not be established.");
280
284
  if (this.state.kind === "active" || this.state.kind === "expired") return this.state.sessionId;
281
- const e = await y(this.partnerKey, t);
285
+ const e = await b(this.partnerKey, t);
282
286
  return this.marker.write(e), this.state = { kind: "active", sessionId: e }, e;
283
287
  }
284
288
  restartExpired(t) {
285
289
  if (this.state.kind !== "expired") return;
286
290
  if (this.restart) return this.restart;
287
- const e = y(this.partnerKey, t).then((r) => (this.marker.write(r), this.state = { kind: "active", sessionId: r }, r)).finally(() => {
291
+ const e = b(this.partnerKey, t).then((r) => (this.marker.write(r), this.state = { kind: "active", sessionId: r }, r)).finally(() => {
288
292
  this.restart === e && (this.restart = void 0);
289
293
  });
290
294
  return this.restart = e, e;
291
295
  }
292
296
  async probe(t) {
293
297
  try {
294
- const e = await M(this.partnerKey, t);
298
+ const e = await F(this.partnerKey, t);
295
299
  e.status === "resumable" ? this.state = { kind: "active", sessionId: t } : e.status === "expired" ? (this.marker.clear(), this.state = { kind: "expired", sessionId: t }) : (this.marker.clear(), this.state = { kind: "cold" });
296
300
  } catch {
297
301
  this.state = { kind: "probe_failed" };
298
302
  }
299
303
  }
300
304
  }
301
- class X {
305
+ class z {
302
306
  constructor(t) {
303
- o(this, "events", new _());
304
- o(this, "scroll", new C());
305
- o(this, "focus", new N());
307
+ o(this, "events", new N());
308
+ o(this, "scroll", new L());
309
+ o(this, "focus", new C());
306
310
  o(this, "overlay");
307
311
  o(this, "bridge");
308
312
  o(this, "context", {});
@@ -311,13 +315,13 @@ class X {
311
315
  o(this, "bootstrapAbort");
312
316
  o(this, "restartAbort");
313
317
  o(this, "session");
314
- this.config = t, this.session = new F(t.partnerKey);
318
+ this.config = t, this.session = new X(t.partnerKey);
315
319
  }
316
320
  async open(t) {
317
321
  if (this.assertUsable(), !t || t.surface !== "pre-approval") throw this.fail("INVALID_SURFACE", 'The only supported surface is "pre-approval".');
318
322
  if (this.overlay) return;
319
323
  if (this.opening) return this.opening;
320
- this.context = h(t.context);
324
+ this.context = u(t.context);
321
325
  const e = new AbortController();
322
326
  this.bootstrapAbort = e;
323
327
  const r = this.performOpen(t.surface, e);
@@ -325,7 +329,7 @@ class X {
325
329
  }
326
330
  updateContext(t) {
327
331
  var e;
328
- this.assertUsable(), this.context = b(this.context, t), (e = this.bridge) == null || e.contextUpdated(this.context);
332
+ this.assertUsable(), this.context = m(this.context, t), (e = this.bridge) == null || e.contextUpdated(this.context);
329
333
  }
330
334
  close() {
331
335
  var t, e;
@@ -340,26 +344,26 @@ class X {
340
344
  async performOpen(t, e) {
341
345
  var r, i;
342
346
  try {
343
- const [n, d] = await Promise.all([
347
+ const [a, n] = await Promise.all([
344
348
  O({ partnerKey: this.config.partnerKey, surface: t }, e.signal),
345
349
  this.session.resolveForOpen(e.signal)
346
- ]), { iframeUrl: c } = n;
350
+ ]), { iframeUrl: c } = a;
347
351
  if (e.signal.aborted || this.destroyed || this.bootstrapAbort !== e) return;
348
352
  this.focus.capture();
349
353
  try {
350
- this.overlay = new U(c, () => this.close(), () => this.fail("IFRAME_LOAD_FAILED", "The embedded experience failed to load.")), this.bridge = new T(
354
+ this.overlay = new P(c, () => this.close(), () => this.fail("IFRAME_LOAD_FAILED", "The embedded experience failed to load.")), this.bridge = new _(
351
355
  this.overlay.iframe.element,
352
- I(c),
353
- () => h(this.context),
354
- () => d,
356
+ R(c),
357
+ () => u(this.context),
358
+ () => n,
355
359
  () => this.restartExpiredSession(this.bridge)
356
360
  ), this.bridge.start(), this.overlay.mount(), this.scroll.lock(), this.focus.moveTo(this.overlay.closeButton), this.events.emit("opened", void 0);
357
- } catch (g) {
358
- throw (r = this.bridge) == null || r.destroy(), this.bridge = void 0, (i = this.overlay) == null || i.destroy(), this.overlay = void 0, this.scroll.unlock(), this.focus.restore(), this.fail("OVERLAY_CREATION_FAILED", "The YourRoad overlay could not be created.", g);
361
+ } catch (l) {
362
+ throw (r = this.bridge) == null || r.destroy(), this.bridge = void 0, (i = this.overlay) == null || i.destroy(), this.overlay = void 0, this.scroll.unlock(), this.focus.restore(), this.fail("OVERLAY_CREATION_FAILED", "The YourRoad overlay could not be created.", l);
359
363
  }
360
- } catch (n) {
364
+ } catch (a) {
361
365
  if (e.signal.aborted) return;
362
- throw n instanceof l ? n : this.fail("BOOTSTRAP_FAILED", "The YourRoad experience could not be started securely.", n);
366
+ throw a instanceof h ? a : this.fail("BOOTSTRAP_FAILED", "The YourRoad experience could not be started securely.", a);
363
367
  } finally {
364
368
  this.bootstrapAbort === e && (this.bootstrapAbort = void 0, this.opening = void 0);
365
369
  }
@@ -381,25 +385,25 @@ class X {
381
385
  });
382
386
  }
383
387
  assertUsable() {
384
- if (this.destroyed) throw new l("DESTROYED", "This YourRoad SDK instance has been destroyed.");
388
+ if (this.destroyed) throw new h("DESTROYED", "This YourRoad SDK instance has been destroyed.");
385
389
  }
386
390
  fail(t, e, r) {
387
- const i = new l(t, e, r === void 0 ? void 0 : { cause: r });
391
+ const i = new h(t, e, r === void 0 ? void 0 : { cause: r });
388
392
  return this.events.emit("error", i), i;
389
393
  }
390
394
  }
391
- function z(s) {
392
- return new X(s);
395
+ function V(s) {
396
+ return new z(s);
393
397
  }
394
- class $ {
398
+ class W {
395
399
  static init(t) {
396
400
  if (!t || typeof t.partnerKey != "string" || t.partnerKey.trim() === "")
397
- throw new l("INVALID_INITIALISATION", "partnerKey must be a non-empty string.");
398
- return z({ partnerKey: t.partnerKey });
401
+ throw new h("INVALID_INITIALISATION", "partnerKey must be a non-empty string.");
402
+ return V({ partnerKey: t.partnerKey });
399
403
  }
400
404
  }
401
405
  export {
402
- $ as YourRoad,
403
- l as YourRoadError
406
+ W as YourRoad,
407
+ h as YourRoadError
404
408
  };
405
409
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/bootstrap/bootstrapClient.ts","../src/context/mergeContext.ts","../src/bridge/protocol.ts","../src/bridge/BridgeController.ts","../src/errors/YourRoadError.ts","../src/events/EventEmitter.ts","../src/lifecycle/focus.ts","../src/lifecycle/scrollLock.ts","../src/iframe/IframeController.ts","../src/overlay/styles.ts","../src/overlay/OverlayController.ts","../src/session/sessionMarker.ts","../src/session/sessionClient.ts","../src/session/SessionController.ts","../src/client/YourRoadClient.ts","../src/index.ts"],"sourcesContent":["import type { YourRoadSurface } from '../config/types';\n\nconst BOOTSTRAP_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/bootstrap-embed-access';\n\ninterface BootstrapRequest {\n partnerKey: string;\n surface: YourRoadSurface;\n}\n\nexport interface BootstrapResult {\n iframeUrl: string;\n expiresAt: string;\n}\n\nfunction validateResponse(value: unknown): BootstrapResult {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new Error('Invalid bootstrap response.');\n const { iframeUrl, expiresAt } = value as Record<string, unknown>;\n if (typeof iframeUrl !== 'string' || iframeUrl.trim() === '') throw new Error('Invalid bootstrap response.');\n let parsedUrl: URL;\n try { parsedUrl = new URL(iframeUrl); } catch { throw new Error('Invalid bootstrap response.'); }\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') throw new Error('Invalid bootstrap response.');\n if (typeof expiresAt !== 'string' || expiresAt.trim() === '' || Number.isNaN(Date.parse(expiresAt))) {\n throw new Error('Invalid bootstrap response.');\n }\n return { iframeUrl, expiresAt };\n}\n\nexport async function requestBootstrap(request: BootstrapRequest, signal: AbortSignal): Promise<BootstrapResult> {\n const response = await fetch(BOOTSTRAP_ENDPOINT, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n credentials: 'omit',\n cache: 'no-store',\n signal,\n });\n if (!response.ok) throw new Error('Bootstrap request was unsuccessful.');\n return validateResponse(await response.json());\n}\n","import type { YourRoadContext, YourRoadContextUpdate } from './types';\n\nconst defined = <T extends object>(value: T | undefined): Partial<T> =>\n Object.fromEntries(Object.entries(value ?? {}).filter(([, item]) => item !== undefined)) as Partial<T>;\n\n/** Merges known context sections. Explicit `undefined` values are ignored. */\nexport function mergeContext(current: YourRoadContext, update: YourRoadContextUpdate): YourRoadContext {\n const next: YourRoadContext = { ...current, ...defined(update) };\n for (const key of ['vehicle', 'dealer', 'page'] as const) {\n if (update[key] !== undefined) next[key] = { ...current[key], ...defined(update[key]) };\n }\n return next;\n}\n\nexport const copyContext = (context?: YourRoadContext): YourRoadContext => mergeContext({}, context ?? {});\n","import type { YourRoadContext } from '../context/types';\n\nexport const BRIDGE_VERSION = 1 as const;\n\nexport type BridgeMessage<T = unknown> = {\n source: 'yourroad.sdk' | 'yourroad.embed';\n version: typeof BRIDGE_VERSION;\n type: string;\n requestId?: string;\n payload?: T;\n};\n\nexport type SdkBridgeMessage =\n | BridgeMessage & { source: 'yourroad.sdk'; type: 'ack' }\n | BridgeMessage<YourRoadContext> & { source: 'yourroad.sdk'; type: 'context' | 'context_updated'; payload: YourRoadContext }\n | BridgeMessage<{ sessionId: string }> & { source: 'yourroad.sdk'; type: 'journey_session'; payload: { sessionId: string } };\n","import { copyContext } from '../context/mergeContext';\nimport type { YourRoadContext } from '../context/types';\nimport { BRIDGE_VERSION, type SdkBridgeMessage } from './protocol';\n\nexport function runtimeOriginFromIframeUrl(iframeUrl: string): string {\n const url = new URL(iframeUrl);\n if (url.protocol !== 'https:' && url.protocol !== 'http:') throw new TypeError('The iframe URL must use HTTP(S).');\n return url.origin;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object') return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\nconst isReadyMessage = (value: unknown): boolean => {\n if (!isPlainObject(value)) return false;\n return value.source === 'yourroad.embed'\n && value.version === BRIDGE_VERSION\n && value.type === 'ready'\n && value.payload === undefined\n && (value.requestId === undefined || typeof value.requestId === 'string');\n};\n\nconst isRestartMessage = (value: unknown): boolean => isPlainObject(value)\n && Object.keys(value).length === 3\n && value.source === 'yourroad.embed'\n && value.version === BRIDGE_VERSION\n && value.type === 'journey_session_restart';\n\nexport class BridgeController {\n private ready = false;\n private started = false;\n\n constructor(\n private readonly iframe: HTMLIFrameElement,\n private readonly trustedRuntimeOrigin: string,\n private readonly getCurrentContext: () => YourRoadContext,\n private readonly getJourneySessionId: () => string,\n private readonly onJourneySessionRestart: () => void,\n ) {}\n\n start(): void {\n if (this.started) return;\n window.addEventListener('message', this.handleMessage);\n this.started = true;\n }\n\n contextUpdated(currentContext: YourRoadContext): void {\n if (!this.ready) return;\n this.post({\n source: 'yourroad.sdk',\n version: BRIDGE_VERSION,\n type: 'context_updated',\n payload: copyContext(currentContext),\n });\n }\n\n destroy(): void {\n if (this.started) window.removeEventListener('message', this.handleMessage);\n this.started = false;\n this.ready = false;\n }\n\n private readonly handleMessage = (event: MessageEvent): void => {\n if (event.origin !== this.trustedRuntimeOrigin) return;\n const iframeWindow = this.iframe.contentWindow;\n if (iframeWindow === null || event.source !== iframeWindow) return;\n if (this.ready) {\n if (isRestartMessage(event.data)) this.onJourneySessionRestart();\n return;\n }\n if (!isReadyMessage(event.data)) return;\n this.ready = true;\n this.post({ source: 'yourroad.sdk', version: BRIDGE_VERSION, type: 'ack' });\n this.post({\n source: 'yourroad.sdk',\n version: BRIDGE_VERSION,\n type: 'context',\n payload: copyContext(this.getCurrentContext()),\n });\n this.sendJourneySession(this.getJourneySessionId());\n };\n\n sendJourneySession(sessionId: string): void {\n if (!this.ready) return;\n this.post({ source: 'yourroad.sdk', version: BRIDGE_VERSION, type: 'journey_session', payload: { sessionId } });\n }\n\n private post(message: SdkBridgeMessage): void {\n const iframeWindow = this.iframe.contentWindow;\n if (iframeWindow === null) return;\n try {\n iframeWindow.postMessage(message, this.trustedRuntimeOrigin);\n } catch {\n // The iframe may be removed concurrently; bridge delivery is best-effort.\n }\n }\n}\n","export type YourRoadErrorCode = 'INVALID_INITIALISATION' | 'INVALID_SURFACE' | 'DESTROYED' | 'BOOTSTRAP_FAILED' | 'OVERLAY_CREATION_FAILED' | 'IFRAME_LOAD_FAILED';\n\nexport class YourRoadError extends Error {\n readonly name = 'YourRoadError';\n constructor(public readonly code: YourRoadErrorCode, message: string, options?: ErrorOptions) {\n super(message, options);\n }\n}\n","export type Handler<T> = (payload: T) => void;\n\nexport class EventEmitter<Events extends object> {\n private listeners = new Map<keyof Events, Set<Handler<never>>>();\n\n on<K extends keyof Events>(event: K, handler: Handler<Events[K]>): () => void {\n const handlers = this.listeners.get(event) ?? new Set();\n handlers.add(handler as Handler<never>);\n this.listeners.set(event, handlers);\n return () => handlers.delete(handler as Handler<never>);\n }\n\n emit<K extends keyof Events>(event: K, payload: Events[K]): void {\n this.listeners.get(event)?.forEach((handler) => handler(payload as never));\n }\n\n clear(): void { this.listeners.clear(); }\n}\n","export class FocusLifecycle {\n private previous: HTMLElement | null = null;\n capture(): void { this.previous = document.activeElement instanceof HTMLElement ? document.activeElement : null; }\n moveTo(element: HTMLElement): void { element.focus(); }\n restore(): void {\n if (this.previous?.isConnected) this.previous.focus();\n this.previous = null;\n }\n}\n","interface SavedStyles { position: string; top: string; left: string; right: string; width: string; overflow: string }\n\nexport class ScrollLock {\n private saved?: SavedStyles;\n private scrollX = 0;\n private scrollY = 0;\n\n lock(): void {\n if (this.saved) return;\n const style = document.body.style;\n this.saved = { position: style.position, top: style.top, left: style.left, right: style.right, width: style.width, overflow: style.overflow };\n this.scrollX = window.scrollX;\n this.scrollY = window.scrollY;\n Object.assign(style, { position: 'fixed', top: `-${this.scrollY}px`, left: `-${this.scrollX}px`, right: '0', width: '100%', overflow: 'hidden' });\n }\n\n unlock(): void {\n if (!this.saved) return;\n Object.assign(document.body.style, this.saved);\n this.saved = undefined;\n window.scrollTo(this.scrollX, this.scrollY);\n }\n}\n","export class IframeController {\n readonly element: HTMLIFrameElement;\n constructor(source: string, onError: () => void) {\n this.element = document.createElement('iframe');\n this.element.dataset.yourroadFrame = '';\n this.element.title = 'YourRoad pre-approval';\n this.element.src = source;\n this.element.addEventListener('error', onError, { once: true });\n }\n destroy(): void { this.element.remove(); }\n}\n","export const SDK_Z_INDEX = 2147483000;\n\nexport const SDK_STYLES = `\n[data-yourroad-overlay-root] { all: initial; position: fixed; inset: 0; z-index: ${SDK_Z_INDEX}; display: block; font-family: system-ui, sans-serif; color: #111; }\n[data-yourroad-scrim] { all: initial; position: absolute; inset: 0; display: block; background: rgba(0, 0, 0, .55); }\n[data-yourroad-panel] { all: initial; box-sizing: border-box; position: absolute; inset-block: 0; inset-inline-end: 0; display: flex; flex-direction: column; width: min(520px, 92vw); height: 100vh; height: 100dvh; background: #fff; box-shadow: -8px 0 30px rgba(0,0,0,.2); }\n[data-yourroad-close] { all: unset; box-sizing: border-box; position: absolute; z-index: 1; inset-block-start: max(12px, env(safe-area-inset-top)); inset-inline-end: max(12px, env(safe-area-inset-right)); width: 44px; height: 44px; display: grid; place-items: center; border-radius: 999px; background: #fff; color: #111; box-shadow: 0 1px 8px rgba(0,0,0,.25); cursor: pointer; font: 28px/1 system-ui, sans-serif; }\n[data-yourroad-close]:focus-visible { outline: 3px solid #1769e0; outline-offset: 2px; }\n[data-yourroad-frame] { all: initial; box-sizing: border-box; display: block; width: 100%; height: 100%; border: 0; background: #fff; }\n@media (max-width: 600px) { [data-yourroad-panel] { width: 100vw; max-width: none; } }\n`;\n\nexport function ensureStyles(): HTMLStyleElement {\n const existing = document.head.querySelector<HTMLStyleElement>('style[data-yourroad-sdk]');\n if (existing) return existing;\n const style = document.createElement('style');\n style.dataset.yourroadSdk = '';\n style.textContent = SDK_STYLES;\n document.head.append(style);\n return style;\n}\n","import { IframeController } from '../iframe/IframeController';\nimport { ensureStyles } from './styles';\n\nexport class OverlayController {\n readonly root: HTMLDivElement;\n readonly closeButton: HTMLButtonElement;\n readonly iframe: IframeController;\n private readonly abort = new AbortController();\n\n constructor(source: string, onClose: () => void, onFrameError: () => void) {\n ensureStyles();\n this.root = document.createElement('div');\n this.root.dataset.yourroadOverlayRoot = '';\n this.root.setAttribute('role', 'dialog');\n this.root.setAttribute('aria-modal', 'true');\n this.root.setAttribute('aria-label', 'YourRoad pre-approval');\n const scrim = document.createElement('div');\n scrim.dataset.yourroadScrim = '';\n const panel = document.createElement('div');\n panel.dataset.yourroadPanel = '';\n this.closeButton = document.createElement('button');\n this.closeButton.type = 'button';\n this.closeButton.dataset.yourroadClose = '';\n this.closeButton.setAttribute('aria-label', 'Close YourRoad');\n this.closeButton.textContent = '×';\n this.iframe = new IframeController(source, onFrameError);\n panel.append(this.closeButton, this.iframe.element);\n this.root.append(scrim, panel);\n const signal = this.abort.signal;\n scrim.addEventListener('click', onClose, { signal });\n this.closeButton.addEventListener('click', onClose, { signal });\n document.addEventListener('keydown', (event) => { if (event.key === 'Escape') onClose(); }, { signal });\n }\n\n mount(): void { document.body.append(this.root); }\n destroy(): void {\n this.abort.abort();\n this.iframe.destroy();\n this.root.remove();\n if (!document.querySelector('[data-yourroad-overlay-root]')) {\n document.head.querySelector('style[data-yourroad-sdk]')?.remove();\n }\n }\n}\n","export const JOURNEY_SESSION_MARKER_KEY = 'yr_journey_session_pre_approval_v1';\n\nexport const isUuid = (value: unknown): value is string =>\n typeof value === 'string'\n && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n\nexport interface SessionMarker {\n read(): string | undefined;\n write(sessionId: string): void;\n clear(): void;\n}\n\ntype MarkerStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;\n\nfunction resolveStorage(): MarkerStorage | undefined {\n try { return globalThis.localStorage; } catch { return undefined; }\n}\n\nexport function createSessionMarker(storage: MarkerStorage | undefined = resolveStorage()): SessionMarker {\n const clear = (): void => {\n try { storage?.removeItem(JOURNEY_SESSION_MARKER_KEY); } catch { /* Storage is optional. */ }\n };\n return {\n read() {\n let value: string | null;\n try { value = storage?.getItem(JOURNEY_SESSION_MARKER_KEY) ?? null; } catch { return undefined; }\n if (value === null) return undefined;\n if (!isUuid(value)) { clear(); return undefined; }\n return value;\n },\n write(sessionId) {\n if (!isUuid(sessionId)) return;\n try { storage?.setItem(JOURNEY_SESSION_MARKER_KEY, sessionId); } catch { /* Keep the in-memory session usable. */ }\n },\n clear,\n };\n}\n","import { isUuid } from './sessionMarker';\n\nconst CREATE_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/create-embed-journey-session';\nconst PROBE_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/probe-embed-journey-session';\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object') return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\nconst isDate = (value: unknown): value is string => typeof value === 'string' && value.trim() !== '' && !Number.isNaN(Date.parse(value));\nconst options = (body: object, signal?: AbortSignal): RequestInit => ({\n method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body),\n credentials: 'omit', cache: 'no-store', signal,\n});\n\nexport async function createJourneySession(partnerKey: string, signal?: AbortSignal): Promise<string> {\n const response = await fetch(CREATE_ENDPOINT, options({ partnerKey, surface: 'pre-approval' }, signal));\n if (response.status !== 201) throw new Error('Journey session creation was unsuccessful.');\n const value: unknown = await response.json();\n if (!isPlainObject(value) || !isUuid(value.sessionId) || !isDate(value.expiresAt)) throw new Error('Invalid journey session response.');\n return value.sessionId;\n}\n\nexport type ProbeResult = { status: 'resumable'; sessionId: string } | { status: 'expired' } | { status: 'invalid' };\n\nexport async function probeJourneySession(partnerKey: string, sessionId: string): Promise<ProbeResult> {\n const response = await fetch(PROBE_ENDPOINT, options({ partnerKey, surface: 'pre-approval', sessionId }));\n const value: unknown = await response.json();\n if (!isPlainObject(value)) throw new Error('Invalid journey session probe response.');\n if (response.status === 200 && value.status === 'resumable' && value.sessionId === sessionId && isDate(value.expiresAt)) {\n return { status: 'resumable', sessionId };\n }\n if (response.status === 410 && value.status === 'expired' && value.code === 'SESSION_EXPIRED') return { status: 'expired' };\n if (response.status === 404 && value.status === 'invalid' && value.code === 'SESSION_INVALID') return { status: 'invalid' };\n throw new Error('Journey session probe was unsuccessful.');\n}\n","import { createJourneySession, probeJourneySession } from './sessionClient';\nimport { createSessionMarker, type SessionMarker } from './sessionMarker';\n\ntype State =\n | { kind: 'cold' }\n | { kind: 'probing'; completion: Promise<void> }\n | { kind: 'active'; sessionId: string }\n | { kind: 'expired'; sessionId: string }\n | { kind: 'probe_failed' };\n\nexport class SessionController {\n private state: State = { kind: 'cold' };\n private restart?: Promise<string>;\n\n constructor(private readonly partnerKey: string, private readonly marker: SessionMarker = createSessionMarker()) {\n const sessionId = marker.read();\n if (!sessionId) return;\n const completion = this.probe(sessionId);\n this.state = { kind: 'probing', completion };\n }\n\n async resolveForOpen(signal: AbortSignal): Promise<string> {\n if (this.state.kind === 'probing') await this.state.completion;\n if (this.state.kind === 'probe_failed') throw new Error('Journey session validity could not be established.');\n if (this.state.kind === 'active' || this.state.kind === 'expired') return this.state.sessionId;\n const sessionId = await createJourneySession(this.partnerKey, signal);\n this.marker.write(sessionId);\n this.state = { kind: 'active', sessionId };\n return sessionId;\n }\n\n restartExpired(signal: AbortSignal): Promise<string> | undefined {\n if (this.state.kind !== 'expired') return undefined;\n if (this.restart) return this.restart;\n const operation = createJourneySession(this.partnerKey, signal).then((sessionId) => {\n this.marker.write(sessionId);\n this.state = { kind: 'active', sessionId };\n return sessionId;\n }).finally(() => { if (this.restart === operation) this.restart = undefined; });\n this.restart = operation;\n return operation;\n }\n\n private async probe(sessionId: string): Promise<void> {\n try {\n const result = await probeJourneySession(this.partnerKey, sessionId);\n if (result.status === 'resumable') this.state = { kind: 'active', sessionId };\n else if (result.status === 'expired') { this.marker.clear(); this.state = { kind: 'expired', sessionId }; }\n else { this.marker.clear(); this.state = { kind: 'cold' }; }\n } catch { this.state = { kind: 'probe_failed' }; }\n }\n}\n","import type { YourRoadInitConfig, YourRoadSurface } from '../config/types';\nimport { requestBootstrap } from '../bootstrap/bootstrapClient';\nimport { BridgeController, runtimeOriginFromIframeUrl } from '../bridge/BridgeController';\nimport { copyContext, mergeContext } from '../context/mergeContext';\nimport type { YourRoadContext, YourRoadContextUpdate } from '../context/types';\nimport { YourRoadError } from '../errors/YourRoadError';\nimport { EventEmitter } from '../events/EventEmitter';\nimport { FocusLifecycle } from '../lifecycle/focus';\nimport { ScrollLock } from '../lifecycle/scrollLock';\nimport { OverlayController } from '../overlay/OverlayController';\nimport { SessionController } from '../session/SessionController';\n\nexport interface OpenOptions { surface: YourRoadSurface; context?: YourRoadContext }\nexport interface YourRoadEvents { opened: undefined; closed: undefined; error: YourRoadError }\n\nexport interface YourRoadClient {\n open(options: OpenOptions): Promise<void>;\n updateContext(update: YourRoadContextUpdate): void;\n close(): void;\n on<K extends keyof YourRoadEvents>(event: K, handler: (payload: YourRoadEvents[K]) => void): () => void;\n destroy(): void;\n}\n\nclass YourRoadClientImpl implements YourRoadClient {\n private readonly events = new EventEmitter<YourRoadEvents>();\n private readonly scroll = new ScrollLock();\n private readonly focus = new FocusLifecycle();\n private overlay?: OverlayController;\n private bridge?: BridgeController;\n private context: YourRoadContext = {};\n private destroyed = false;\n private opening?: Promise<void>;\n private bootstrapAbort?: AbortController;\n private restartAbort?: AbortController;\n private readonly session: SessionController;\n\n constructor(private readonly config: Readonly<YourRoadInitConfig>) {\n this.session = new SessionController(config.partnerKey);\n }\n\n async open(options: OpenOptions): Promise<void> {\n this.assertUsable();\n if (!options || options.surface !== 'pre-approval') throw this.fail('INVALID_SURFACE', 'The only supported surface is \"pre-approval\".');\n if (this.overlay) return;\n if (this.opening) return this.opening;\n this.context = copyContext(options.context);\n const abort = new AbortController();\n this.bootstrapAbort = abort;\n const operation = this.performOpen(options.surface, abort);\n this.opening = operation;\n return operation;\n }\n\n updateContext(update: YourRoadContextUpdate): void {\n this.assertUsable();\n this.context = mergeContext(this.context, update);\n this.bridge?.contextUpdated(this.context);\n }\n\n close(): void {\n this.assertUsable();\n if (this.bootstrapAbort) {\n this.bootstrapAbort.abort();\n this.bootstrapAbort = undefined;\n this.opening = undefined;\n }\n this.restartAbort?.abort();\n this.restartAbort = undefined;\n if (!this.overlay) return;\n this.bridge?.destroy();\n this.bridge = undefined;\n this.overlay.destroy();\n this.overlay = undefined;\n this.scroll.unlock();\n this.focus.restore();\n this.events.emit('closed', undefined);\n }\n\n on<K extends keyof YourRoadEvents>(event: K, handler: (payload: YourRoadEvents[K]) => void): () => void {\n this.assertUsable();\n return this.events.on(event, handler);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.close();\n this.events.clear();\n this.context = {};\n this.destroyed = true;\n }\n\n private async performOpen(surface: YourRoadSurface, abort: AbortController): Promise<void> {\n try {\n const [bootstrap, sessionId] = await Promise.all([\n requestBootstrap({ partnerKey: this.config.partnerKey, surface }, abort.signal),\n this.session.resolveForOpen(abort.signal),\n ]);\n const { iframeUrl } = bootstrap;\n if (abort.signal.aborted || this.destroyed || this.bootstrapAbort !== abort) return;\n this.focus.capture();\n try {\n this.overlay = new OverlayController(iframeUrl, () => this.close(), () => this.fail('IFRAME_LOAD_FAILED', 'The embedded experience failed to load.'));\n this.bridge = new BridgeController(\n this.overlay.iframe.element,\n runtimeOriginFromIframeUrl(iframeUrl),\n () => copyContext(this.context),\n () => sessionId,\n () => this.restartExpiredSession(this.bridge),\n );\n this.bridge.start();\n this.overlay.mount();\n this.scroll.lock();\n this.focus.moveTo(this.overlay.closeButton);\n this.events.emit('opened', undefined);\n } catch (cause) {\n this.bridge?.destroy();\n this.bridge = undefined;\n this.overlay?.destroy();\n this.overlay = undefined;\n this.scroll.unlock();\n this.focus.restore();\n throw this.fail('OVERLAY_CREATION_FAILED', 'The YourRoad overlay could not be created.', cause);\n }\n } catch (cause) {\n if (abort.signal.aborted) return;\n if (cause instanceof YourRoadError) throw cause;\n throw this.fail('BOOTSTRAP_FAILED', 'The YourRoad experience could not be started securely.', cause);\n } finally {\n if (this.bootstrapAbort === abort) {\n this.bootstrapAbort = undefined;\n this.opening = undefined;\n }\n }\n }\n\n private restartExpiredSession(bridge: BridgeController | undefined): void {\n if (this.destroyed || bridge === undefined || bridge !== this.bridge || this.restartAbort) return;\n const restartAbort = new AbortController();\n this.restartAbort = restartAbort;\n const operation = this.session.restartExpired(restartAbort.signal);\n if (!operation) { this.restartAbort = undefined; return; }\n void operation.then((sessionId) => {\n if (!this.destroyed && !restartAbort.signal.aborted && this.bridge === bridge) bridge.sendJourneySession(sessionId);\n }).catch(() => { /* The runtime may offer a later explicit retry. */ }).finally(() => {\n if (this.restartAbort === restartAbort) this.restartAbort = undefined;\n });\n }\n\n private assertUsable(): void { if (this.destroyed) throw new YourRoadError('DESTROYED', 'This YourRoad SDK instance has been destroyed.'); }\n private fail(code: ConstructorParameters<typeof YourRoadError>[0], message: string, cause?: unknown): YourRoadError {\n const error = new YourRoadError(code, message, cause === undefined ? undefined : { cause });\n this.events.emit('error', error);\n return error;\n }\n}\n\nexport function createYourRoadClient(config: Readonly<YourRoadInitConfig>): YourRoadClient {\n return new YourRoadClientImpl(config);\n}\n","import { createYourRoadClient, type YourRoadClient } from './client/YourRoadClient';\nimport type { YourRoadInitConfig } from './config/types';\nimport { YourRoadError } from './errors/YourRoadError';\n\nexport type { OpenOptions, YourRoadClient, YourRoadEvents } from './client/YourRoadClient';\nexport type { YourRoadInitConfig, YourRoadSurface } from './config/types';\nexport type { DealerContext, PageContext, VehicleContext, YourRoadContext, YourRoadContextUpdate } from './context/types';\nexport { YourRoadError };\n\nexport class YourRoad {\n static init(config: YourRoadInitConfig): YourRoadClient {\n if (!config || typeof config.partnerKey !== 'string' || config.partnerKey.trim() === '') {\n throw new YourRoadError('INVALID_INITIALISATION', 'partnerKey must be a non-empty string.');\n }\n return createYourRoadClient({ partnerKey: config.partnerKey });\n }\n}\n"],"names":["BOOTSTRAP_ENDPOINT","validateResponse","value","iframeUrl","expiresAt","parsedUrl","requestBootstrap","request","signal","response","defined","item","mergeContext","current","update","next","key","copyContext","context","BRIDGE_VERSION","runtimeOriginFromIframeUrl","url","isPlainObject","prototype","isReadyMessage","isRestartMessage","BridgeController","iframe","trustedRuntimeOrigin","getCurrentContext","getJourneySessionId","onJourneySessionRestart","__publicField","event","iframeWindow","currentContext","sessionId","message","YourRoadError","code","options","EventEmitter","handler","handlers","payload","_a","FocusLifecycle","element","ScrollLock","style","IframeController","source","onError","SDK_Z_INDEX","SDK_STYLES","ensureStyles","existing","OverlayController","onClose","onFrameError","scrim","panel","JOURNEY_SESSION_MARKER_KEY","isUuid","resolveStorage","createSessionMarker","storage","clear","CREATE_ENDPOINT","PROBE_ENDPOINT","isDate","body","createJourneySession","partnerKey","probeJourneySession","SessionController","marker","completion","operation","result","YourRoadClientImpl","config","abort","_b","surface","bootstrap","cause","bridge","restartAbort","error","createYourRoadClient","YourRoad"],"mappings":";;;AAEA,MAAMA,IAAqB;AAY3B,SAASC,EAAiBC,GAAiC;AACzD,MAAI,OAAOA,KAAU,YAAYA,MAAU,QAAQ,MAAM,QAAQA,CAAK,EAAG,OAAM,IAAI,MAAM,6BAA6B;AACtH,QAAM,EAAE,WAAAC,GAAW,WAAAC,EAAA,IAAcF;AACjC,MAAI,OAAOC,KAAc,YAAYA,EAAU,KAAA,MAAW,GAAI,OAAM,IAAI,MAAM,6BAA6B;AAC3G,MAAIE;AACJ,MAAI;AAAE,IAAAA,IAAY,IAAI,IAAIF,CAAS;AAAA,EAAG,QAAQ;AAAE,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAAG;AAChG,MAAIE,EAAU,aAAa,WAAWA,EAAU,aAAa,SAAU,OAAM,IAAI,MAAM,6BAA6B;AACpH,MAAI,OAAOD,KAAc,YAAYA,EAAU,KAAA,MAAW,MAAM,OAAO,MAAM,KAAK,MAAMA,CAAS,CAAC;AAChG,UAAM,IAAI,MAAM,6BAA6B;AAE/C,SAAO,EAAE,WAAAD,GAAW,WAAAC,EAAA;AACtB;AAEA,eAAsBE,EAAiBC,GAA2BC,GAA+C;AAC/G,QAAMC,IAAW,MAAM,MAAMT,GAAoB;AAAA,IAC/C,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAA;AAAA,IAC3B,MAAM,KAAK,UAAUO,CAAO;AAAA,IAC5B,aAAa;AAAA,IACb,OAAO;AAAA,IACP,QAAAC;AAAA,EAAA,CACD;AACD,MAAI,CAACC,EAAS,GAAI,OAAM,IAAI,MAAM,qCAAqC;AACvE,SAAOR,EAAiB,MAAMQ,EAAS,MAAM;AAC/C;ACpCA,MAAMC,IAAU,CAAmBR,MACjC,OAAO,YAAY,OAAO,QAAQA,KAAS,CAAA,CAAE,EAAE,OAAO,CAAC,CAAA,EAAGS,CAAI,MAAMA,MAAS,MAAS,CAAC;AAGlF,SAASC,EAAaC,GAA0BC,GAAgD;AACrG,QAAMC,IAAwB,EAAE,GAAGF,GAAS,GAAGH,EAAQI,CAAM,EAAA;AAC7D,aAAWE,KAAO,CAAC,WAAW,UAAU,MAAM;AAC5C,IAAIF,EAAOE,CAAG,MAAM,WAAWD,EAAKC,CAAG,IAAI,EAAE,GAAGH,EAAQG,CAAG,GAAG,GAAGN,EAAQI,EAAOE,CAAG,CAAC,EAAA;AAEtF,SAAOD;AACT;AAEO,MAAME,IAAc,CAACC,MAA+CN,EAAa,CAAA,GAAIM,KAAW,CAAA,CAAE,GCZ5FC,IAAiB;ACEvB,SAASC,EAA2BjB,GAA2B;AACpE,QAAMkB,IAAM,IAAI,IAAIlB,CAAS;AAC7B,MAAIkB,EAAI,aAAa,YAAYA,EAAI,aAAa,QAAS,OAAM,IAAI,UAAU,kCAAkC;AACjH,SAAOA,EAAI;AACb;AAEA,MAAMC,IAAgB,CAACpB,MAAqD;AAC1E,MAAIA,MAAU,QAAQ,OAAOA,KAAU,SAAU,QAAO;AACxD,QAAMqB,IAAY,OAAO,eAAerB,CAAK;AAC7C,SAAOqB,MAAc,OAAO,aAAaA,MAAc;AACzD,GAEMC,IAAiB,CAACtB,MACjBoB,EAAcpB,CAAK,IACjBA,EAAM,WAAW,oBACnBA,EAAM,YAAYiB,KAClBjB,EAAM,SAAS,WACfA,EAAM,YAAY,WACjBA,EAAM,cAAc,UAAa,OAAOA,EAAM,aAAc,YALhC,IAQ9BuB,IAAmB,CAACvB,MAA4BoB,EAAcpB,CAAK,KACpE,OAAO,KAAKA,CAAK,EAAE,WAAW,KAC9BA,EAAM,WAAW,oBACjBA,EAAM,YAAYiB,KAClBjB,EAAM,SAAS;AAEb,MAAMwB,EAAiB;AAAA,EAI5B,YACmBC,GACAC,GACAC,GACAC,GACAC,GACjB;AATM,IAAAC,EAAA,eAAQ;AACR,IAAAA,EAAA,iBAAU;AAgCD,IAAAA,EAAA,uBAAgB,CAACC,MAA8B;AAC9D,UAAIA,EAAM,WAAW,KAAK,qBAAsB;AAChD,YAAMC,IAAe,KAAK,OAAO;AACjC,UAAI,EAAAA,MAAiB,QAAQD,EAAM,WAAWC,IAC9C;AAAA,YAAI,KAAK,OAAO;AACd,UAAIT,EAAiBQ,EAAM,IAAI,UAAQ,wBAAA;AACvC;AAAA,QACF;AACA,QAAKT,EAAeS,EAAM,IAAI,MAC9B,KAAK,QAAQ,IACb,KAAK,KAAK,EAAE,QAAQ,gBAAgB,SAASd,GAAgB,MAAM,OAAO,GAC1E,KAAK,KAAK;AAAA,UACR,QAAQ;AAAA,UACR,SAASA;AAAA,UACT,MAAM;AAAA,UACN,SAASF,EAAY,KAAK,kBAAA,CAAmB;AAAA,QAAA,CAC9C,GACD,KAAK,mBAAmB,KAAK,qBAAqB;AAAA;AAAA,IACpD;AA/CmB,SAAA,SAAAU,GACA,KAAA,uBAAAC,GACA,KAAA,oBAAAC,GACA,KAAA,sBAAAC,GACA,KAAA,0BAAAC;AAAA,EAChB;AAAA,EAEH,QAAc;AACZ,IAAI,KAAK,YACT,OAAO,iBAAiB,WAAW,KAAK,aAAa,GACrD,KAAK,UAAU;AAAA,EACjB;AAAA,EAEA,eAAeI,GAAuC;AACpD,IAAK,KAAK,SACV,KAAK,KAAK;AAAA,MACR,QAAQ;AAAA,MACR,SAAShB;AAAA,MACT,MAAM;AAAA,MACN,SAASF,EAAYkB,CAAc;AAAA,IAAA,CACpC;AAAA,EACH;AAAA,EAEA,UAAgB;AACd,IAAI,KAAK,WAAS,OAAO,oBAAoB,WAAW,KAAK,aAAa,GAC1E,KAAK,UAAU,IACf,KAAK,QAAQ;AAAA,EACf;AAAA,EAsBA,mBAAmBC,GAAyB;AAC1C,IAAK,KAAK,SACV,KAAK,KAAK,EAAE,QAAQ,gBAAgB,SAASjB,GAAgB,MAAM,mBAAmB,SAAS,EAAE,WAAAiB,EAAA,EAAU,CAAG;AAAA,EAChH;AAAA,EAEQ,KAAKC,GAAiC;AAC5C,UAAMH,IAAe,KAAK,OAAO;AACjC,QAAIA,MAAiB;AACrB,UAAI;AACF,QAAAA,EAAa,YAAYG,GAAS,KAAK,oBAAoB;AAAA,MAC7D,QAAQ;AAAA,MAER;AAAA,EACF;AACF;ACjGO,MAAMC,UAAsB,MAAM;AAAA,EAEvC,YAA4BC,GAAyBF,GAAiBG,GAAwB;AAC5F,UAAMH,GAASG,CAAO;AAFf,IAAAR,EAAA,cAAO;AACY,SAAA,OAAAO;AAAA,EAE5B;AACF;ACLO,MAAME,EAAoC;AAAA,EAA1C;AACG,IAAAT,EAAA,uCAAgB,IAAA;AAAA;AAAA,EAExB,GAA2BC,GAAUS,GAAyC;AAC5E,UAAMC,IAAW,KAAK,UAAU,IAAIV,CAAK,yBAAS,IAAA;AAClD,WAAAU,EAAS,IAAID,CAAyB,GACtC,KAAK,UAAU,IAAIT,GAAOU,CAAQ,GAC3B,MAAMA,EAAS,OAAOD,CAAyB;AAAA,EACxD;AAAA,EAEA,KAA6BT,GAAUW,GAA0B;ALVnE,QAAAC;AKWI,KAAAA,IAAA,KAAK,UAAU,IAAIZ,CAAK,MAAxB,QAAAY,EAA2B,QAAQ,CAACH,MAAYA,EAAQE,CAAgB;AAAA,EAC1E;AAAA,EAEA,QAAc;AAAE,SAAK,UAAU,MAAA;AAAA,EAAS;AAC1C;ACjBO,MAAME,EAAe;AAAA,EAArB;AACG,IAAAd,EAAA,kBAA+B;AAAA;AAAA,EACvC,UAAgB;AAAE,SAAK,WAAW,SAAS,yBAAyB,cAAc,SAAS,gBAAgB;AAAA,EAAM;AAAA,EACjH,OAAOe,GAA4B;AAAE,IAAAA,EAAQ,MAAA;AAAA,EAAS;AAAA,EACtD,UAAgB;ANFlB,QAAAF;AMGI,KAAIA,IAAA,KAAK,aAAL,QAAAA,EAAe,eAAa,KAAK,SAAS,MAAA,GAC9C,KAAK,WAAW;AAAA,EAClB;AACF;ACNO,MAAMG,EAAW;AAAA,EAAjB;AACG,IAAAhB,EAAA;AACA,IAAAA,EAAA,iBAAU;AACV,IAAAA,EAAA,iBAAU;AAAA;AAAA,EAElB,OAAa;AACX,QAAI,KAAK,MAAO;AAChB,UAAMiB,IAAQ,SAAS,KAAK;AAC5B,SAAK,QAAQ,EAAE,UAAUA,EAAM,UAAU,KAAKA,EAAM,KAAK,MAAMA,EAAM,MAAM,OAAOA,EAAM,OAAO,OAAOA,EAAM,OAAO,UAAUA,EAAM,SAAA,GACnI,KAAK,UAAU,OAAO,SACtB,KAAK,UAAU,OAAO,SACtB,OAAO,OAAOA,GAAO,EAAE,UAAU,SAAS,KAAK,IAAI,KAAK,OAAO,MAAM,MAAM,IAAI,KAAK,OAAO,MAAM,OAAO,KAAK,OAAO,QAAQ,UAAU,SAAA,CAAU;AAAA,EAClJ;AAAA,EAEA,SAAe;AACb,IAAK,KAAK,UACV,OAAO,OAAO,SAAS,KAAK,OAAO,KAAK,KAAK,GAC7C,KAAK,QAAQ,QACb,OAAO,SAAS,KAAK,SAAS,KAAK,OAAO;AAAA,EAC5C;AACF;ACtBO,MAAMC,EAAiB;AAAA,EAE5B,YAAYC,GAAgBC,GAAqB;AADxC,IAAApB,EAAA;AAEP,SAAK,UAAU,SAAS,cAAc,QAAQ,GAC9C,KAAK,QAAQ,QAAQ,gBAAgB,IACrC,KAAK,QAAQ,QAAQ,yBACrB,KAAK,QAAQ,MAAMmB,GACnB,KAAK,QAAQ,iBAAiB,SAASC,GAAS,EAAE,MAAM,IAAM;AAAA,EAChE;AAAA,EACA,UAAgB;AAAE,SAAK,QAAQ,OAAA;AAAA,EAAU;AAC3C;ACVO,MAAMC,IAAc,WAEdC,IAAa;AAAA,mFACyDD,CAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASvF,SAASE,IAAiC;AAC/C,QAAMC,IAAW,SAAS,KAAK,cAAgC,0BAA0B;AACzF,MAAIA,EAAU,QAAOA;AACrB,QAAMP,IAAQ,SAAS,cAAc,OAAO;AAC5C,SAAAA,EAAM,QAAQ,cAAc,IAC5BA,EAAM,cAAcK,GACpB,SAAS,KAAK,OAAOL,CAAK,GACnBA;AACT;ACjBO,MAAMQ,EAAkB;AAAA,EAM7B,YAAYN,GAAgBO,GAAqBC,GAA0B;AALlE,IAAA3B,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACQ,IAAAA,EAAA,eAAQ,IAAI,gBAAA;AAG3B,IAAAuB,EAAA,GACA,KAAK,OAAO,SAAS,cAAc,KAAK,GACxC,KAAK,KAAK,QAAQ,sBAAsB,IACxC,KAAK,KAAK,aAAa,QAAQ,QAAQ,GACvC,KAAK,KAAK,aAAa,cAAc,MAAM,GAC3C,KAAK,KAAK,aAAa,cAAc,uBAAuB;AAC5D,UAAMK,IAAQ,SAAS,cAAc,KAAK;AAC1C,IAAAA,EAAM,QAAQ,gBAAgB;AAC9B,UAAMC,IAAQ,SAAS,cAAc,KAAK;AAC1C,IAAAA,EAAM,QAAQ,gBAAgB,IAC9B,KAAK,cAAc,SAAS,cAAc,QAAQ,GAClD,KAAK,YAAY,OAAO,UACxB,KAAK,YAAY,QAAQ,gBAAgB,IACzC,KAAK,YAAY,aAAa,cAAc,gBAAgB,GAC5D,KAAK,YAAY,cAAc,KAC/B,KAAK,SAAS,IAAIX,EAAiBC,GAAQQ,CAAY,GACvDE,EAAM,OAAO,KAAK,aAAa,KAAK,OAAO,OAAO,GAClD,KAAK,KAAK,OAAOD,GAAOC,CAAK;AAC7B,UAAMrD,IAAS,KAAK,MAAM;AAC1B,IAAAoD,EAAM,iBAAiB,SAASF,GAAS,EAAE,QAAAlD,GAAQ,GACnD,KAAK,YAAY,iBAAiB,SAASkD,GAAS,EAAE,QAAAlD,GAAQ,GAC9D,SAAS,iBAAiB,WAAW,CAACyB,MAAU;AAAE,MAAIA,EAAM,QAAQ,YAAUyB,EAAA;AAAA,IAAW,GAAG,EAAE,QAAAlD,GAAQ;AAAA,EACxG;AAAA,EAEA,QAAc;AAAE,aAAS,KAAK,OAAO,KAAK,IAAI;AAAA,EAAG;AAAA,EACjD,UAAgB;AVjClB,QAAAqC;AUkCI,SAAK,MAAM,MAAA,GACX,KAAK,OAAO,QAAA,GACZ,KAAK,KAAK,OAAA,GACL,SAAS,cAAc,8BAA8B,MACxDA,IAAA,SAAS,KAAK,cAAc,0BAA0B,MAAtD,QAAAA,EAAyD;AAAA,EAE7D;AACF;AC3CO,MAAMiB,IAA6B,sCAE7BC,IAAS,CAAC7D,MACrB,OAAOA,KAAU,YACd,6EAA6E,KAAKA,CAAK;AAU5F,SAAS8D,IAA4C;AACnD,MAAI;AAAE,WAAO,WAAW;AAAA,EAAc,QAAQ;AAAE;AAAA,EAAkB;AACpE;AAEO,SAASC,EAAoBC,IAAqCF,KAAiC;AACxG,QAAMG,IAAQ,MAAY;AACxB,QAAI;AAAE,MAAAD,KAAA,QAAAA,EAAS,WAAWJ;AAAA,IAA6B,QAAQ;AAAA,IAA6B;AAAA,EAC9F;AACA,SAAO;AAAA,IACL,OAAO;AACL,UAAI5D;AACJ,UAAI;AAAE,QAAAA,KAAQgE,KAAA,gBAAAA,EAAS,QAAQJ,OAA+B;AAAA,MAAM,QAAQ;AAAE;AAAA,MAAkB;AAChG,UAAI5D,MAAU,MACd;AAAA,YAAI,CAAC6D,EAAO7D,CAAK,GAAG;AAAE,UAAAiE,EAAA;AAAS;AAAA,QAAkB;AACjD,eAAOjE;AAAA;AAAA,IACT;AAAA,IACA,MAAMkC,GAAW;AACf,UAAK2B,EAAO3B,CAAS;AACrB,YAAI;AAAE,UAAA8B,KAAA,QAAAA,EAAS,QAAQJ,GAA4B1B;AAAA,QAAY,QAAQ;AAAA,QAA2C;AAAA,IACpH;AAAA,IACA,OAAA+B;AAAA,EAAA;AAEJ;AClCA,MAAMC,IAAkB,sFAClBC,IAAiB,qFAEjB/C,IAAgB,CAACpB,MAAqD;AAC1E,MAAIA,MAAU,QAAQ,OAAOA,KAAU,SAAU,QAAO;AACxD,QAAMqB,IAAY,OAAO,eAAerB,CAAK;AAC7C,SAAOqB,MAAc,OAAO,aAAaA,MAAc;AACzD,GACM+C,IAAS,CAACpE,MAAoC,OAAOA,KAAU,YAAYA,EAAM,KAAA,MAAW,MAAM,CAAC,OAAO,MAAM,KAAK,MAAMA,CAAK,CAAC,GACjIsC,IAAU,CAAC+B,GAAc/D,OAAuC;AAAA,EACpE,QAAQ;AAAA,EAAQ,SAAS,EAAE,gBAAgB,mBAAA;AAAA,EAAsB,MAAM,KAAK,UAAU+D,CAAI;AAAA,EAC1F,aAAa;AAAA,EAAQ,OAAO;AAAA,EAAY,QAAA/D;AAC1C;AAEA,eAAsBgE,EAAqBC,GAAoBjE,GAAuC;AACpG,QAAMC,IAAW,MAAM,MAAM2D,GAAiB5B,EAAQ,EAAE,YAAAiC,GAAY,SAAS,kBAAkBjE,CAAM,CAAC;AACtG,MAAIC,EAAS,WAAW,IAAK,OAAM,IAAI,MAAM,4CAA4C;AACzF,QAAMP,IAAiB,MAAMO,EAAS,KAAA;AACtC,MAAI,CAACa,EAAcpB,CAAK,KAAK,CAAC6D,EAAO7D,EAAM,SAAS,KAAK,CAACoE,EAAOpE,EAAM,SAAS,EAAG,OAAM,IAAI,MAAM,mCAAmC;AACtI,SAAOA,EAAM;AACf;AAIA,eAAsBwE,EAAoBD,GAAoBrC,GAAyC;AACrG,QAAM3B,IAAW,MAAM,MAAM4D,GAAgB7B,EAAQ,EAAE,YAAAiC,GAAY,SAAS,gBAAgB,WAAArC,EAAA,CAAW,CAAC,GAClGlC,IAAiB,MAAMO,EAAS,KAAA;AACtC,MAAI,CAACa,EAAcpB,CAAK,EAAG,OAAM,IAAI,MAAM,yCAAyC;AACpF,MAAIO,EAAS,WAAW,OAAOP,EAAM,WAAW,eAAeA,EAAM,cAAckC,KAAakC,EAAOpE,EAAM,SAAS;AACpH,WAAO,EAAE,QAAQ,aAAa,WAAAkC,EAAA;AAEhC,MAAI3B,EAAS,WAAW,OAAOP,EAAM,WAAW,aAAaA,EAAM,SAAS,kBAAmB,QAAO,EAAE,QAAQ,UAAA;AAChH,MAAIO,EAAS,WAAW,OAAOP,EAAM,WAAW,aAAaA,EAAM,SAAS,kBAAmB,QAAO,EAAE,QAAQ,UAAA;AAChH,QAAM,IAAI,MAAM,yCAAyC;AAC3D;AC1BO,MAAMyE,EAAkB;AAAA,EAI7B,YAA6BF,GAAqCG,IAAwBX,KAAuB;AAHzG,IAAAjC,EAAA,eAAe,EAAE,MAAM,OAAA;AACvB,IAAAA,EAAA;AAEqB,SAAA,aAAAyC,GAAqC,KAAA,SAAAG;AAChE,UAAMxC,IAAYwC,EAAO,KAAA;AACzB,QAAI,CAACxC,EAAW;AAChB,UAAMyC,IAAa,KAAK,MAAMzC,CAAS;AACvC,SAAK,QAAQ,EAAE,MAAM,WAAW,YAAAyC,EAAA;AAAA,EAClC;AAAA,EAEA,MAAM,eAAerE,GAAsC;AAEzD,QADI,KAAK,MAAM,SAAS,aAAW,MAAM,KAAK,MAAM,YAChD,KAAK,MAAM,SAAS,eAAgB,OAAM,IAAI,MAAM,oDAAoD;AAC5G,QAAI,KAAK,MAAM,SAAS,YAAY,KAAK,MAAM,SAAS,UAAW,QAAO,KAAK,MAAM;AACrF,UAAM4B,IAAY,MAAMoC,EAAqB,KAAK,YAAYhE,CAAM;AACpE,gBAAK,OAAO,MAAM4B,CAAS,GAC3B,KAAK,QAAQ,EAAE,MAAM,UAAU,WAAAA,EAAA,GACxBA;AAAA,EACT;AAAA,EAEA,eAAe5B,GAAkD;AAC/D,QAAI,KAAK,MAAM,SAAS,UAAW;AACnC,QAAI,KAAK,QAAS,QAAO,KAAK;AAC9B,UAAMsE,IAAYN,EAAqB,KAAK,YAAYhE,CAAM,EAAE,KAAK,CAAC4B,OACpE,KAAK,OAAO,MAAMA,CAAS,GAC3B,KAAK,QAAQ,EAAE,MAAM,UAAU,WAAAA,EAAA,GACxBA,EACR,EAAE,QAAQ,MAAM;AAAE,MAAI,KAAK,YAAY0C,MAAW,KAAK,UAAU;AAAA,IAAW,CAAC;AAC9E,gBAAK,UAAUA,GACRA;AAAA,EACT;AAAA,EAEA,MAAc,MAAM1C,GAAkC;AACpD,QAAI;AACF,YAAM2C,IAAS,MAAML,EAAoB,KAAK,YAAYtC,CAAS;AACnE,MAAI2C,EAAO,WAAW,cAAa,KAAK,QAAQ,EAAE,MAAM,UAAU,WAAA3C,EAAA,IACzD2C,EAAO,WAAW,aAAa,KAAK,OAAO,MAAA,GAAS,KAAK,QAAQ,EAAE,MAAM,WAAW,WAAA3C,EAAA,MACtF,KAAK,OAAO,MAAA,GAAS,KAAK,QAAQ,EAAE,MAAM,OAAA;AAAA,IACnD,QAAQ;AAAE,WAAK,QAAQ,EAAE,MAAM,eAAA;AAAA,IAAkB;AAAA,EACnD;AACF;AC5BA,MAAM4C,EAA6C;AAAA,EAajD,YAA6BC,GAAsC;AAZlD,IAAAjD,EAAA,gBAAS,IAAIS,EAAA;AACb,IAAAT,EAAA,gBAAS,IAAIgB,EAAA;AACb,IAAAhB,EAAA,eAAQ,IAAIc,EAAA;AACrB,IAAAd,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,iBAA2B,CAAA;AAC3B,IAAAA,EAAA,mBAAY;AACZ,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACS,IAAAA,EAAA;AAEY,SAAA,SAAAiD,GAC3B,KAAK,UAAU,IAAIN,EAAkBM,EAAO,UAAU;AAAA,EACxD;AAAA,EAEA,MAAM,KAAKzC,GAAqC;AAE9C,QADA,KAAK,aAAA,GACD,CAACA,KAAWA,EAAQ,YAAY,eAAgB,OAAM,KAAK,KAAK,mBAAmB,+CAA+C;AACtI,QAAI,KAAK,QAAS;AAClB,QAAI,KAAK,QAAS,QAAO,KAAK;AAC9B,SAAK,UAAUvB,EAAYuB,EAAQ,OAAO;AAC1C,UAAM0C,IAAQ,IAAI,gBAAA;AAClB,SAAK,iBAAiBA;AACtB,UAAMJ,IAAY,KAAK,YAAYtC,EAAQ,SAAS0C,CAAK;AACzD,gBAAK,UAAUJ,GACRA;AAAA,EACT;AAAA,EAEA,cAAchE,GAAqC;AdnDrD,QAAA+B;AcoDI,SAAK,aAAA,GACL,KAAK,UAAUjC,EAAa,KAAK,SAASE,CAAM,IAChD+B,IAAA,KAAK,WAAL,QAAAA,EAAa,eAAe,KAAK;AAAA,EACnC;AAAA,EAEA,QAAc;AdzDhB,QAAAA,GAAAsC;AckEI,IARA,KAAK,aAAA,GACD,KAAK,mBACP,KAAK,eAAe,MAAA,GACpB,KAAK,iBAAiB,QACtB,KAAK,UAAU,UAEjBtC,IAAA,KAAK,iBAAL,QAAAA,EAAmB,SACnB,KAAK,eAAe,QACf,KAAK,aACVsC,IAAA,KAAK,WAAL,QAAAA,EAAa,WACb,KAAK,SAAS,QACd,KAAK,QAAQ,QAAA,GACb,KAAK,UAAU,QACf,KAAK,OAAO,OAAA,GACZ,KAAK,MAAM,QAAA,GACX,KAAK,OAAO,KAAK,UAAU,MAAS;AAAA,EACtC;AAAA,EAEA,GAAmClD,GAAUS,GAA2D;AACtG,gBAAK,aAAA,GACE,KAAK,OAAO,GAAGT,GAAOS,CAAO;AAAA,EACtC;AAAA,EAEA,UAAgB;AACd,IAAI,KAAK,cACT,KAAK,MAAA,GACL,KAAK,OAAO,MAAA,GACZ,KAAK,UAAU,CAAA,GACf,KAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAc,YAAY0C,GAA0BF,GAAuC;AdzF7F,QAAArC,GAAAsC;Ac0FI,QAAI;AACF,YAAM,CAACE,GAAWjD,CAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC/C9B,EAAiB,EAAE,YAAY,KAAK,OAAO,YAAY,SAAA8E,EAAA,GAAWF,EAAM,MAAM;AAAA,QAC9E,KAAK,QAAQ,eAAeA,EAAM,MAAM;AAAA,MAAA,CACzC,GACK,EAAE,WAAA/E,MAAckF;AACtB,UAAIH,EAAM,OAAO,WAAW,KAAK,aAAa,KAAK,mBAAmBA,EAAO;AAC7E,WAAK,MAAM,QAAA;AACX,UAAI;AACF,aAAK,UAAU,IAAIzB,EAAkBtD,GAAW,MAAM,KAAK,MAAA,GAAS,MAAM,KAAK,KAAK,sBAAsB,yCAAyC,CAAC,GACpJ,KAAK,SAAS,IAAIuB;AAAA,UAChB,KAAK,QAAQ,OAAO;AAAA,UACpBN,EAA2BjB,CAAS;AAAA,UACpC,MAAMc,EAAY,KAAK,OAAO;AAAA,UAC9B,MAAMmB;AAAA,UACN,MAAM,KAAK,sBAAsB,KAAK,MAAM;AAAA,QAAA,GAE9C,KAAK,OAAO,MAAA,GACZ,KAAK,QAAQ,MAAA,GACb,KAAK,OAAO,KAAA,GACZ,KAAK,MAAM,OAAO,KAAK,QAAQ,WAAW,GAC1C,KAAK,OAAO,KAAK,UAAU,MAAS;AAAA,MACtC,SAASkD,GAAO;AACd,eAAAzC,IAAA,KAAK,WAAL,QAAAA,EAAa,WACb,KAAK,SAAS,SACdsC,IAAA,KAAK,YAAL,QAAAA,EAAc,WACd,KAAK,UAAU,QACf,KAAK,OAAO,OAAA,GACZ,KAAK,MAAM,QAAA,GACL,KAAK,KAAK,2BAA2B,8CAA8CG,CAAK;AAAA,MAChG;AAAA,IACF,SAASA,GAAO;AACd,UAAIJ,EAAM,OAAO,QAAS;AAC1B,YAAII,aAAiBhD,IAAqBgD,IACpC,KAAK,KAAK,oBAAoB,0DAA0DA,CAAK;AAAA,IACrG,UAAA;AACE,MAAI,KAAK,mBAAmBJ,MAC1B,KAAK,iBAAiB,QACtB,KAAK,UAAU;AAAA,IAEnB;AAAA,EACF;AAAA,EAEQ,sBAAsBK,GAA4C;AACxE,QAAI,KAAK,aAAaA,MAAW,UAAaA,MAAW,KAAK,UAAU,KAAK,aAAc;AAC3F,UAAMC,IAAe,IAAI,gBAAA;AACzB,SAAK,eAAeA;AACpB,UAAMV,IAAY,KAAK,QAAQ,eAAeU,EAAa,MAAM;AACjE,QAAI,CAACV,GAAW;AAAE,WAAK,eAAe;AAAW;AAAA,IAAQ;AACzD,IAAKA,EAAU,KAAK,CAAC1C,MAAc;AACjC,MAAI,CAAC,KAAK,aAAa,CAACoD,EAAa,OAAO,WAAW,KAAK,WAAWD,KAAQA,EAAO,mBAAmBnD,CAAS;AAAA,IACpH,CAAC,EAAE,MAAM,MAAM;AAAA,IAAsD,CAAC,EAAE,QAAQ,MAAM;AACpF,MAAI,KAAK,iBAAiBoD,MAAc,KAAK,eAAe;AAAA,IAC9D,CAAC;AAAA,EACH;AAAA,EAEQ,eAAqB;AAAE,QAAI,KAAK,UAAW,OAAM,IAAIlD,EAAc,aAAa,gDAAgD;AAAA,EAAG;AAAA,EACnI,KAAKC,GAAsDF,GAAiBiD,GAAgC;AAClH,UAAMG,IAAQ,IAAInD,EAAcC,GAAMF,GAASiD,MAAU,SAAY,SAAY,EAAE,OAAAA,GAAO;AAC1F,gBAAK,OAAO,KAAK,SAASG,CAAK,GACxBA;AAAA,EACT;AACF;AAEO,SAASC,EAAqBT,GAAsD;AACzF,SAAO,IAAID,EAAmBC,CAAM;AACtC;ACrJO,MAAMU,EAAS;AAAA,EACpB,OAAO,KAAKV,GAA4C;AACtD,QAAI,CAACA,KAAU,OAAOA,EAAO,cAAe,YAAYA,EAAO,WAAW,KAAA,MAAW;AACnF,YAAM,IAAI3C,EAAc,0BAA0B,wCAAwC;AAE5F,WAAOoD,EAAqB,EAAE,YAAYT,EAAO,YAAY;AAAA,EAC/D;AACF;"}
1
+ {"version":3,"file":"index.js","sources":["../src/bootstrap/bootstrapClient.ts","../src/context/mergeContext.ts","../src/bridge/protocol.ts","../src/bridge/BridgeController.ts","../src/errors/YourRoadError.ts","../src/events/EventEmitter.ts","../src/lifecycle/focus.ts","../src/lifecycle/scrollLock.ts","../src/iframe/IframeController.ts","../src/overlay/styles.ts","../src/overlay/OverlayController.ts","../src/session/sessionMarker.ts","../src/session/sessionClient.ts","../src/session/SessionController.ts","../src/client/YourRoadClient.ts","../src/index.ts"],"sourcesContent":["import type { YourRoadSurface } from '../config/types';\n\nconst BOOTSTRAP_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/bootstrap-embed-access';\n\ninterface BootstrapRequest {\n partnerKey: string;\n surface: YourRoadSurface;\n}\n\nexport interface BootstrapResult {\n iframeUrl: string;\n expiresAt: string;\n}\n\nfunction validateResponse(value: unknown): BootstrapResult {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new Error('Invalid bootstrap response.');\n const { iframeUrl, expiresAt } = value as Record<string, unknown>;\n if (typeof iframeUrl !== 'string' || iframeUrl.trim() === '') throw new Error('Invalid bootstrap response.');\n let parsedUrl: URL;\n try { parsedUrl = new URL(iframeUrl); } catch { throw new Error('Invalid bootstrap response.'); }\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') throw new Error('Invalid bootstrap response.');\n if (typeof expiresAt !== 'string' || expiresAt.trim() === '' || Number.isNaN(Date.parse(expiresAt))) {\n throw new Error('Invalid bootstrap response.');\n }\n return { iframeUrl, expiresAt };\n}\n\nexport async function requestBootstrap(request: BootstrapRequest, signal: AbortSignal): Promise<BootstrapResult> {\n const response = await fetch(BOOTSTRAP_ENDPOINT, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n credentials: 'omit',\n cache: 'no-store',\n signal,\n });\n if (!response.ok) throw new Error('Bootstrap request was unsuccessful.');\n return validateResponse(await response.json());\n}\n","import type { YourRoadContext, YourRoadContextUpdate } from './types';\n\nconst defined = <T extends object>(value: T | undefined): Partial<T> =>\n Object.fromEntries(Object.entries(value ?? {}).filter(([, item]) => item !== undefined)) as Partial<T>;\n\n/** Merges known context sections. Explicit `undefined` values are ignored. */\nexport function mergeContext(current: YourRoadContext, update: YourRoadContextUpdate): YourRoadContext {\n const next: YourRoadContext = { ...current, ...defined(update) };\n for (const key of ['vehicle', 'dealer', 'page'] as const) {\n if (update[key] !== undefined) next[key] = { ...current[key], ...defined(update[key]) };\n }\n return next;\n}\n\nexport const copyContext = (context?: YourRoadContext): YourRoadContext => mergeContext({}, context ?? {});\n","import type { YourRoadContext } from '../context/types';\n\nexport const BRIDGE_VERSION = 1 as const;\n\nexport type BridgeMessage<T = unknown> = {\n source: 'yourroad.sdk' | 'yourroad.embed';\n version: typeof BRIDGE_VERSION;\n type: string;\n requestId?: string;\n payload?: T;\n};\n\nexport type SdkBridgeMessage =\n | BridgeMessage & { source: 'yourroad.sdk'; type: 'ack' }\n | BridgeMessage<YourRoadContext> & { source: 'yourroad.sdk'; type: 'context' | 'context_updated'; payload: YourRoadContext }\n | BridgeMessage<{ sessionId: string }> & { source: 'yourroad.sdk'; type: 'journey_session'; payload: { sessionId: string } };\n","import { copyContext } from '../context/mergeContext';\nimport type { YourRoadContext } from '../context/types';\nimport { BRIDGE_VERSION, type SdkBridgeMessage } from './protocol';\n\nexport function runtimeOriginFromIframeUrl(iframeUrl: string): string {\n const url = new URL(iframeUrl);\n if (url.protocol !== 'https:' && url.protocol !== 'http:') throw new TypeError('The iframe URL must use HTTP(S).');\n return url.origin;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object') return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\nconst isReadyMessage = (value: unknown): boolean => {\n if (!isPlainObject(value)) return false;\n return value.source === 'yourroad.embed'\n && value.version === BRIDGE_VERSION\n && value.type === 'ready'\n && value.payload === undefined\n && (value.requestId === undefined || typeof value.requestId === 'string');\n};\n\nconst isRestartMessage = (value: unknown): boolean => isPlainObject(value)\n && Object.keys(value).length === 3\n && value.source === 'yourroad.embed'\n && value.version === BRIDGE_VERSION\n && value.type === 'journey_session_restart';\n\nexport class BridgeController {\n private ready = false;\n private started = false;\n\n constructor(\n private readonly iframe: HTMLIFrameElement,\n private readonly trustedRuntimeOrigin: string,\n private readonly getCurrentContext: () => YourRoadContext,\n private readonly getJourneySessionId: () => string,\n private readonly onJourneySessionRestart: () => void,\n ) {}\n\n start(): void {\n if (this.started) return;\n window.addEventListener('message', this.handleMessage);\n this.started = true;\n }\n\n contextUpdated(currentContext: YourRoadContext): void {\n if (!this.ready) return;\n this.post({\n source: 'yourroad.sdk',\n version: BRIDGE_VERSION,\n type: 'context_updated',\n payload: copyContext(currentContext),\n });\n }\n\n destroy(): void {\n if (this.started) window.removeEventListener('message', this.handleMessage);\n this.started = false;\n this.ready = false;\n }\n\n private readonly handleMessage = (event: MessageEvent): void => {\n if (event.origin !== this.trustedRuntimeOrigin) return;\n const iframeWindow = this.iframe.contentWindow;\n if (iframeWindow === null || event.source !== iframeWindow) return;\n if (this.ready) {\n if (isRestartMessage(event.data)) this.onJourneySessionRestart();\n return;\n }\n if (!isReadyMessage(event.data)) return;\n this.ready = true;\n this.post({ source: 'yourroad.sdk', version: BRIDGE_VERSION, type: 'ack' });\n this.post({\n source: 'yourroad.sdk',\n version: BRIDGE_VERSION,\n type: 'context',\n payload: copyContext(this.getCurrentContext()),\n });\n this.sendJourneySession(this.getJourneySessionId());\n };\n\n sendJourneySession(sessionId: string): void {\n if (!this.ready) return;\n this.post({ source: 'yourroad.sdk', version: BRIDGE_VERSION, type: 'journey_session', payload: { sessionId } });\n }\n\n private post(message: SdkBridgeMessage): void {\n const iframeWindow = this.iframe.contentWindow;\n if (iframeWindow === null) return;\n try {\n iframeWindow.postMessage(message, this.trustedRuntimeOrigin);\n } catch {\n // The iframe may be removed concurrently; bridge delivery is best-effort.\n }\n }\n}\n","export type YourRoadErrorCode = 'INVALID_INITIALISATION' | 'INVALID_SURFACE' | 'DESTROYED' | 'BOOTSTRAP_FAILED' | 'OVERLAY_CREATION_FAILED' | 'IFRAME_LOAD_FAILED';\n\nexport class YourRoadError extends Error {\n readonly name = 'YourRoadError';\n constructor(public readonly code: YourRoadErrorCode, message: string, options?: ErrorOptions) {\n super(message, options);\n }\n}\n","export type Handler<T> = (payload: T) => void;\n\nexport class EventEmitter<Events extends object> {\n private listeners = new Map<keyof Events, Set<Handler<never>>>();\n\n on<K extends keyof Events>(event: K, handler: Handler<Events[K]>): () => void {\n const handlers = this.listeners.get(event) ?? new Set();\n handlers.add(handler as Handler<never>);\n this.listeners.set(event, handlers);\n return () => handlers.delete(handler as Handler<never>);\n }\n\n emit<K extends keyof Events>(event: K, payload: Events[K]): void {\n this.listeners.get(event)?.forEach((handler) => handler(payload as never));\n }\n\n clear(): void { this.listeners.clear(); }\n}\n","export class FocusLifecycle {\n private previous: HTMLElement | null = null;\n capture(): void { this.previous = document.activeElement instanceof HTMLElement ? document.activeElement : null; }\n moveTo(element: HTMLElement): void { element.focus(); }\n restore(): void {\n if (this.previous?.isConnected) this.previous.focus();\n this.previous = null;\n }\n}\n","interface SavedStyles { position: string; top: string; left: string; right: string; width: string; overflow: string }\n\nexport class ScrollLock {\n private saved?: SavedStyles;\n private scrollX = 0;\n private scrollY = 0;\n\n lock(): void {\n if (this.saved) return;\n const style = document.body.style;\n this.saved = { position: style.position, top: style.top, left: style.left, right: style.right, width: style.width, overflow: style.overflow };\n this.scrollX = window.scrollX;\n this.scrollY = window.scrollY;\n Object.assign(style, { position: 'fixed', top: `-${this.scrollY}px`, left: `-${this.scrollX}px`, right: '0', width: '100%', overflow: 'hidden' });\n }\n\n unlock(): void {\n if (!this.saved) return;\n Object.assign(document.body.style, this.saved);\n this.saved = undefined;\n window.scrollTo(this.scrollX, this.scrollY);\n }\n}\n","export class IframeController {\n readonly element: HTMLIFrameElement;\n constructor(source: string, onError: () => void) {\n this.element = document.createElement('iframe');\n this.element.dataset.yourroadFrame = '';\n this.element.title = 'YourRoad pre-approval';\n this.element.src = source;\n this.element.addEventListener('error', onError, { once: true });\n }\n destroy(): void { this.element.remove(); }\n}\n","export const SDK_Z_INDEX = 2147483000;\n\nexport const SDK_STYLES = `\n[data-yourroad-overlay-root] { all: initial; position: fixed; inset: 0; z-index: ${SDK_Z_INDEX}; display: block; font-family: system-ui, sans-serif; color: #111; }\n[data-yourroad-scrim] { all: initial; position: absolute; inset: 0; display: block; background: rgba(0, 0, 0, .55); }\n[data-yourroad-panel] { all: initial; box-sizing: border-box; position: absolute; inset-block: 0; inset-inline-end: 0; display: flex; flex-direction: column; width: min(520px, 92vw); height: 100vh; height: 100dvh; padding-block-start: calc(max(12px, env(safe-area-inset-top)) + 56px); overflow: hidden; border-radius: 24px 0 0 24px; background: #fff; box-shadow: -8px 0 30px rgba(0,0,0,.2); }\n[data-yourroad-close] { all: unset; box-sizing: border-box; position: absolute; z-index: 1; inset-block-start: max(12px, env(safe-area-inset-top)); inset-inline-end: max(12px, env(safe-area-inset-right)); width: 44px; height: 44px; display: grid; place-items: center; border-radius: 999px; background: #fff; color: #111; box-shadow: 0 1px 8px rgba(0,0,0,.25); cursor: pointer; font: 28px/1 system-ui, sans-serif; }\n[data-yourroad-close]:focus-visible { outline: 3px solid #1769e0; outline-offset: 2px; }\n[data-yourroad-frame] { all: initial; box-sizing: border-box; display: block; flex: 1 1 auto; min-height: 0; width: 100%; border: 0; background: #fff; }\n@media (max-width: 600px) { [data-yourroad-panel] { inset-block-start: auto; inset-block-end: 0; inset-inline-end: 0; width: 100vw; max-width: none; height: 92vh; height: 92dvh; border-radius: 24px 24px 0 0; box-shadow: 0 -8px 30px rgba(0,0,0,.2); } }\n`;\n\nexport function ensureStyles(): HTMLStyleElement {\n const existing = document.head.querySelector<HTMLStyleElement>('style[data-yourroad-sdk]');\n if (existing) return existing;\n const style = document.createElement('style');\n style.dataset.yourroadSdk = '';\n style.textContent = SDK_STYLES;\n document.head.append(style);\n return style;\n}\n","import { IframeController } from '../iframe/IframeController';\nimport { ensureStyles } from './styles';\n\nexport class OverlayController {\n readonly root: HTMLDivElement;\n readonly closeButton: HTMLButtonElement;\n readonly iframe: IframeController;\n private readonly abort = new AbortController();\n\n constructor(source: string, onClose: () => void, onFrameError: () => void) {\n ensureStyles();\n this.root = document.createElement('div');\n this.root.dataset.yourroadOverlayRoot = '';\n this.root.setAttribute('role', 'dialog');\n this.root.setAttribute('aria-modal', 'true');\n this.root.setAttribute('aria-label', 'YourRoad pre-approval');\n const scrim = document.createElement('div');\n scrim.dataset.yourroadScrim = '';\n const panel = document.createElement('div');\n panel.dataset.yourroadPanel = '';\n this.closeButton = document.createElement('button');\n this.closeButton.type = 'button';\n this.closeButton.dataset.yourroadClose = '';\n this.closeButton.setAttribute('aria-label', 'Close YourRoad');\n const closeIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n closeIcon.setAttribute('viewBox', '0 0 24 24');\n closeIcon.setAttribute('width', '24');\n closeIcon.setAttribute('height', '24');\n closeIcon.setAttribute('fill', 'none');\n closeIcon.setAttribute('stroke', 'currentColor');\n closeIcon.setAttribute('stroke-width', '2');\n closeIcon.setAttribute('stroke-linecap', 'round');\n closeIcon.setAttribute('aria-hidden', 'true');\n const closeIconPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n closeIconPath.setAttribute('d', 'M6 6l12 12M18 6L6 18');\n closeIcon.append(closeIconPath);\n this.closeButton.append(closeIcon);\n this.iframe = new IframeController(source, onFrameError);\n panel.append(this.closeButton, this.iframe.element);\n this.root.append(scrim, panel);\n const signal = this.abort.signal;\n scrim.addEventListener('click', onClose, { signal });\n this.closeButton.addEventListener('click', onClose, { signal });\n document.addEventListener('keydown', (event) => { if (event.key === 'Escape') onClose(); }, { signal });\n }\n\n mount(): void { document.body.append(this.root); }\n destroy(): void {\n this.abort.abort();\n this.iframe.destroy();\n this.root.remove();\n if (!document.querySelector('[data-yourroad-overlay-root]')) {\n document.head.querySelector('style[data-yourroad-sdk]')?.remove();\n }\n }\n}\n","export const JOURNEY_SESSION_MARKER_KEY = 'yr_journey_session_pre_approval_v1';\n\nexport const isUuid = (value: unknown): value is string =>\n typeof value === 'string'\n && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n\nexport interface SessionMarker {\n read(): string | undefined;\n write(sessionId: string): void;\n clear(): void;\n}\n\ntype MarkerStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;\n\nfunction resolveStorage(): MarkerStorage | undefined {\n try { return globalThis.localStorage; } catch { return undefined; }\n}\n\nexport function createSessionMarker(storage: MarkerStorage | undefined = resolveStorage()): SessionMarker {\n const clear = (): void => {\n try { storage?.removeItem(JOURNEY_SESSION_MARKER_KEY); } catch { /* Storage is optional. */ }\n };\n return {\n read() {\n let value: string | null;\n try { value = storage?.getItem(JOURNEY_SESSION_MARKER_KEY) ?? null; } catch { return undefined; }\n if (value === null) return undefined;\n if (!isUuid(value)) { clear(); return undefined; }\n return value;\n },\n write(sessionId) {\n if (!isUuid(sessionId)) return;\n try { storage?.setItem(JOURNEY_SESSION_MARKER_KEY, sessionId); } catch { /* Keep the in-memory session usable. */ }\n },\n clear,\n };\n}\n","import { isUuid } from './sessionMarker';\n\nconst CREATE_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/create-embed-journey-session';\nconst PROBE_ENDPOINT = 'https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/probe-embed-journey-session';\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object') return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\nconst isDate = (value: unknown): value is string => typeof value === 'string' && value.trim() !== '' && !Number.isNaN(Date.parse(value));\nconst options = (body: object, signal?: AbortSignal): RequestInit => ({\n method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body),\n credentials: 'omit', cache: 'no-store', signal,\n});\n\nexport async function createJourneySession(partnerKey: string, signal?: AbortSignal): Promise<string> {\n const response = await fetch(CREATE_ENDPOINT, options({ partnerKey, surface: 'pre-approval' }, signal));\n if (response.status !== 201) throw new Error('Journey session creation was unsuccessful.');\n const value: unknown = await response.json();\n if (!isPlainObject(value) || !isUuid(value.sessionId) || !isDate(value.expiresAt)) throw new Error('Invalid journey session response.');\n return value.sessionId;\n}\n\nexport type ProbeResult = { status: 'resumable'; sessionId: string } | { status: 'expired' } | { status: 'invalid' };\n\nexport async function probeJourneySession(partnerKey: string, sessionId: string): Promise<ProbeResult> {\n const response = await fetch(PROBE_ENDPOINT, options({ partnerKey, surface: 'pre-approval', sessionId }));\n const value: unknown = await response.json();\n if (!isPlainObject(value)) throw new Error('Invalid journey session probe response.');\n if (response.status === 200 && value.status === 'resumable' && value.sessionId === sessionId && isDate(value.expiresAt)) {\n return { status: 'resumable', sessionId };\n }\n if (response.status === 410 && value.status === 'expired' && value.code === 'SESSION_EXPIRED') return { status: 'expired' };\n if (response.status === 404 && value.status === 'invalid' && value.code === 'SESSION_INVALID') return { status: 'invalid' };\n throw new Error('Journey session probe was unsuccessful.');\n}\n","import { createJourneySession, probeJourneySession } from './sessionClient';\nimport { createSessionMarker, type SessionMarker } from './sessionMarker';\n\ntype State =\n | { kind: 'cold' }\n | { kind: 'probing'; completion: Promise<void> }\n | { kind: 'active'; sessionId: string }\n | { kind: 'expired'; sessionId: string }\n | { kind: 'probe_failed' };\n\nexport class SessionController {\n private state: State = { kind: 'cold' };\n private restart?: Promise<string>;\n\n constructor(private readonly partnerKey: string, private readonly marker: SessionMarker = createSessionMarker()) {\n const sessionId = marker.read();\n if (!sessionId) return;\n const completion = this.probe(sessionId);\n this.state = { kind: 'probing', completion };\n }\n\n async resolveForOpen(signal: AbortSignal): Promise<string> {\n if (this.state.kind === 'probing') await this.state.completion;\n if (this.state.kind === 'probe_failed') throw new Error('Journey session validity could not be established.');\n if (this.state.kind === 'active' || this.state.kind === 'expired') return this.state.sessionId;\n const sessionId = await createJourneySession(this.partnerKey, signal);\n this.marker.write(sessionId);\n this.state = { kind: 'active', sessionId };\n return sessionId;\n }\n\n restartExpired(signal: AbortSignal): Promise<string> | undefined {\n if (this.state.kind !== 'expired') return undefined;\n if (this.restart) return this.restart;\n const operation = createJourneySession(this.partnerKey, signal).then((sessionId) => {\n this.marker.write(sessionId);\n this.state = { kind: 'active', sessionId };\n return sessionId;\n }).finally(() => { if (this.restart === operation) this.restart = undefined; });\n this.restart = operation;\n return operation;\n }\n\n private async probe(sessionId: string): Promise<void> {\n try {\n const result = await probeJourneySession(this.partnerKey, sessionId);\n if (result.status === 'resumable') this.state = { kind: 'active', sessionId };\n else if (result.status === 'expired') { this.marker.clear(); this.state = { kind: 'expired', sessionId }; }\n else { this.marker.clear(); this.state = { kind: 'cold' }; }\n } catch { this.state = { kind: 'probe_failed' }; }\n }\n}\n","import type { YourRoadInitConfig, YourRoadSurface } from '../config/types';\nimport { requestBootstrap } from '../bootstrap/bootstrapClient';\nimport { BridgeController, runtimeOriginFromIframeUrl } from '../bridge/BridgeController';\nimport { copyContext, mergeContext } from '../context/mergeContext';\nimport type { YourRoadContext, YourRoadContextUpdate } from '../context/types';\nimport { YourRoadError } from '../errors/YourRoadError';\nimport { EventEmitter } from '../events/EventEmitter';\nimport { FocusLifecycle } from '../lifecycle/focus';\nimport { ScrollLock } from '../lifecycle/scrollLock';\nimport { OverlayController } from '../overlay/OverlayController';\nimport { SessionController } from '../session/SessionController';\n\nexport interface OpenOptions { surface: YourRoadSurface; context?: YourRoadContext }\nexport interface YourRoadEvents { opened: undefined; closed: undefined; error: YourRoadError }\n\nexport interface YourRoadClient {\n open(options: OpenOptions): Promise<void>;\n updateContext(update: YourRoadContextUpdate): void;\n close(): void;\n on<K extends keyof YourRoadEvents>(event: K, handler: (payload: YourRoadEvents[K]) => void): () => void;\n destroy(): void;\n}\n\nclass YourRoadClientImpl implements YourRoadClient {\n private readonly events = new EventEmitter<YourRoadEvents>();\n private readonly scroll = new ScrollLock();\n private readonly focus = new FocusLifecycle();\n private overlay?: OverlayController;\n private bridge?: BridgeController;\n private context: YourRoadContext = {};\n private destroyed = false;\n private opening?: Promise<void>;\n private bootstrapAbort?: AbortController;\n private restartAbort?: AbortController;\n private readonly session: SessionController;\n\n constructor(private readonly config: Readonly<YourRoadInitConfig>) {\n this.session = new SessionController(config.partnerKey);\n }\n\n async open(options: OpenOptions): Promise<void> {\n this.assertUsable();\n if (!options || options.surface !== 'pre-approval') throw this.fail('INVALID_SURFACE', 'The only supported surface is \"pre-approval\".');\n if (this.overlay) return;\n if (this.opening) return this.opening;\n this.context = copyContext(options.context);\n const abort = new AbortController();\n this.bootstrapAbort = abort;\n const operation = this.performOpen(options.surface, abort);\n this.opening = operation;\n return operation;\n }\n\n updateContext(update: YourRoadContextUpdate): void {\n this.assertUsable();\n this.context = mergeContext(this.context, update);\n this.bridge?.contextUpdated(this.context);\n }\n\n close(): void {\n this.assertUsable();\n if (this.bootstrapAbort) {\n this.bootstrapAbort.abort();\n this.bootstrapAbort = undefined;\n this.opening = undefined;\n }\n this.restartAbort?.abort();\n this.restartAbort = undefined;\n if (!this.overlay) return;\n this.bridge?.destroy();\n this.bridge = undefined;\n this.overlay.destroy();\n this.overlay = undefined;\n this.scroll.unlock();\n this.focus.restore();\n this.events.emit('closed', undefined);\n }\n\n on<K extends keyof YourRoadEvents>(event: K, handler: (payload: YourRoadEvents[K]) => void): () => void {\n this.assertUsable();\n return this.events.on(event, handler);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.close();\n this.events.clear();\n this.context = {};\n this.destroyed = true;\n }\n\n private async performOpen(surface: YourRoadSurface, abort: AbortController): Promise<void> {\n try {\n const [bootstrap, sessionId] = await Promise.all([\n requestBootstrap({ partnerKey: this.config.partnerKey, surface }, abort.signal),\n this.session.resolveForOpen(abort.signal),\n ]);\n const { iframeUrl } = bootstrap;\n if (abort.signal.aborted || this.destroyed || this.bootstrapAbort !== abort) return;\n this.focus.capture();\n try {\n this.overlay = new OverlayController(iframeUrl, () => this.close(), () => this.fail('IFRAME_LOAD_FAILED', 'The embedded experience failed to load.'));\n this.bridge = new BridgeController(\n this.overlay.iframe.element,\n runtimeOriginFromIframeUrl(iframeUrl),\n () => copyContext(this.context),\n () => sessionId,\n () => this.restartExpiredSession(this.bridge),\n );\n this.bridge.start();\n this.overlay.mount();\n this.scroll.lock();\n this.focus.moveTo(this.overlay.closeButton);\n this.events.emit('opened', undefined);\n } catch (cause) {\n this.bridge?.destroy();\n this.bridge = undefined;\n this.overlay?.destroy();\n this.overlay = undefined;\n this.scroll.unlock();\n this.focus.restore();\n throw this.fail('OVERLAY_CREATION_FAILED', 'The YourRoad overlay could not be created.', cause);\n }\n } catch (cause) {\n if (abort.signal.aborted) return;\n if (cause instanceof YourRoadError) throw cause;\n throw this.fail('BOOTSTRAP_FAILED', 'The YourRoad experience could not be started securely.', cause);\n } finally {\n if (this.bootstrapAbort === abort) {\n this.bootstrapAbort = undefined;\n this.opening = undefined;\n }\n }\n }\n\n private restartExpiredSession(bridge: BridgeController | undefined): void {\n if (this.destroyed || bridge === undefined || bridge !== this.bridge || this.restartAbort) return;\n const restartAbort = new AbortController();\n this.restartAbort = restartAbort;\n const operation = this.session.restartExpired(restartAbort.signal);\n if (!operation) { this.restartAbort = undefined; return; }\n void operation.then((sessionId) => {\n if (!this.destroyed && !restartAbort.signal.aborted && this.bridge === bridge) bridge.sendJourneySession(sessionId);\n }).catch(() => { /* The runtime may offer a later explicit retry. */ }).finally(() => {\n if (this.restartAbort === restartAbort) this.restartAbort = undefined;\n });\n }\n\n private assertUsable(): void { if (this.destroyed) throw new YourRoadError('DESTROYED', 'This YourRoad SDK instance has been destroyed.'); }\n private fail(code: ConstructorParameters<typeof YourRoadError>[0], message: string, cause?: unknown): YourRoadError {\n const error = new YourRoadError(code, message, cause === undefined ? undefined : { cause });\n this.events.emit('error', error);\n return error;\n }\n}\n\nexport function createYourRoadClient(config: Readonly<YourRoadInitConfig>): YourRoadClient {\n return new YourRoadClientImpl(config);\n}\n","import { createYourRoadClient, type YourRoadClient } from './client/YourRoadClient';\nimport type { YourRoadInitConfig } from './config/types';\nimport { YourRoadError } from './errors/YourRoadError';\n\nexport type { OpenOptions, YourRoadClient, YourRoadEvents } from './client/YourRoadClient';\nexport type { YourRoadInitConfig, YourRoadSurface } from './config/types';\nexport type { DealerContext, PageContext, VehicleContext, YourRoadContext, YourRoadContextUpdate } from './context/types';\nexport { YourRoadError };\n\nexport class YourRoad {\n static init(config: YourRoadInitConfig): YourRoadClient {\n if (!config || typeof config.partnerKey !== 'string' || config.partnerKey.trim() === '') {\n throw new YourRoadError('INVALID_INITIALISATION', 'partnerKey must be a non-empty string.');\n }\n return createYourRoadClient({ partnerKey: config.partnerKey });\n }\n}\n"],"names":["BOOTSTRAP_ENDPOINT","validateResponse","value","iframeUrl","expiresAt","parsedUrl","requestBootstrap","request","signal","response","defined","item","mergeContext","current","update","next","key","copyContext","context","BRIDGE_VERSION","runtimeOriginFromIframeUrl","url","isPlainObject","prototype","isReadyMessage","isRestartMessage","BridgeController","iframe","trustedRuntimeOrigin","getCurrentContext","getJourneySessionId","onJourneySessionRestart","__publicField","event","iframeWindow","currentContext","sessionId","message","YourRoadError","code","options","EventEmitter","handler","handlers","payload","_a","FocusLifecycle","element","ScrollLock","style","IframeController","source","onError","SDK_Z_INDEX","SDK_STYLES","ensureStyles","existing","OverlayController","onClose","onFrameError","scrim","panel","closeIcon","closeIconPath","JOURNEY_SESSION_MARKER_KEY","isUuid","resolveStorage","createSessionMarker","storage","clear","CREATE_ENDPOINT","PROBE_ENDPOINT","isDate","body","createJourneySession","partnerKey","probeJourneySession","SessionController","marker","completion","operation","result","YourRoadClientImpl","config","abort","_b","surface","bootstrap","cause","bridge","restartAbort","error","createYourRoadClient","YourRoad"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yourroad/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Framework-independent browser SDK for hosting YourRoad embedded experiences",
5
5
  "publishConfig": {
6
6
  "access": "public",