@yourroad/sdk 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,10 +16,13 @@ import { YourRoad } from '@yourroad/sdk';
16
16
  const yourRoad = YourRoad.init({ partnerKey: 'yr_test_example' });
17
17
 
18
18
  const unsubscribe = yourRoad.on('closed', () => console.log('closed'));
19
- await yourRoad.open({
19
+ await yourRoad.prepare({
20
20
  surface: 'pre-approval',
21
21
  context: { vehicle: { id: 'abc', price: 24_495 }, page: { type: 'vehicle-detail' } },
22
22
  });
23
+ await yourRoad.open({
24
+ surface: 'pre-approval',
25
+ });
23
26
  yourRoad.updateContext({ vehicle: { price: 23_995 } });
24
27
  yourRoad.close();
25
28
  unsubscribe();
@@ -28,9 +31,9 @@ yourRoad.destroy();
28
31
 
29
32
  ### Bootstrap and lifecycle
30
33
 
31
- `init()` validates local configuration. With no journey marker it makes no session-state network request; with a valid marker it makes one conditional probe. The `partnerKey` is publishable rather than secret. On an explicit cold `open()`, the SDK creates a journey session and asks the YourRoad bootstrap service to authorize that partner key together with the browser-supplied Origin and the requested surface. Both must succeed before the overlay mounts. Bootstrap itself creates no customer, finance, journey, or resumable session state.
34
+ `init()` validates local configuration. With no journey marker it makes no session-state network request; with a valid marker it makes one conditional probe. It does not create an iframe or a new journey session. The `partnerKey` is publishable rather than secret. On an explicit cold `prepare()` or `open()`, the SDK creates or resolves a journey session and asks the YourRoad bootstrap service to authorize that partner key together with the browser-supplied Origin and the requested surface. Bootstrap itself creates no customer, finance, journey, or resumable session state.
32
35
 
33
- Each initialization is independent. Concurrent calls share one opening operation, and repeated `open()` on an already-open instance is an idempotent no-op. `close()` cancels a pending bootstrap or closes an open overlay while keeping the instance reusable. `destroy()` is idempotent and all other later operations throw `YourRoadError` with code `DESTROYED`.
36
+ Each initialization is independent. `prepare()` prewarms one hidden iframe and resolves only after the trusted bridge handshake; it does not focus, lock scrolling, or emit `opened`. Concurrent preparation/opening calls share that runtime. `open()` reveals it (or performs the same cold setup if needed), and repeated `open()` while visible is an idempotent no-op. `close()` only hides the overlay: the iframe, bridge, in-memory context, and iframe-owned runtime credential remain alive for reuse. `destroy()` is the sole hard teardown, is idempotent, and makes all other later operations throw `YourRoadError` with code `DESTROYED`.
34
37
 
35
38
  Context objects are copied at entry. Updates shallow-merge the top level and each known nested section; properties explicitly set to `undefined` are ignored rather than deleting existing values. Context is retained only in memory and is never sent during bootstrap. The iframe URL remains server-authoritative, and the SDK derives the trusted runtime origin from that authorised URL. It accepts the runtime's `ready` message only from the exact iframe window and origin, then replies with an acknowledgement, the full current context, and the opaque journey session UUID in that order. After that handshake, `updateContext()` sends the newly merged full context snapshot.
36
39
 
package/dist/index.cjs CHANGED
@@ -1,10 +1,11 @@
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; }
1
+ "use strict";var k=Object.defineProperty;var S=(s,t,e)=>t in s?k(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var i=(s,t,e)=>S(s,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const O="https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/bootstrap-embed-access";function I(s){if(typeof s!="object"||s===null||Array.isArray(s))throw new Error("Invalid bootstrap response.");const{iframeUrl:t,expiresAt:e}=s;if(typeof t!="string"||t.trim()==="")throw new Error("Invalid bootstrap response.");let r;try{r=new URL(t)}catch{throw new Error("Invalid bootstrap response.")}if(r.protocol!=="http:"&&r.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 j(s,t){const e=await fetch(O,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s),credentials:"omit",cache:"no-store",signal:t});if(!e.ok)throw new Error("Bootstrap request was unsuccessful.");return I(await e.json())}const v=s=>Object.fromEntries(Object.entries(s??{}).filter(([,t])=>t!==void 0));function g(s,t){const e={...s,...v(t)};for(const r of["vehicle","dealer","page"])t[r]!==void 0&&(e[r]={...s[r],...v(t[r])});return e}const f=s=>g({},s??{}),u=1;function T(s){const t=new URL(s);if(t.protocol!=="https:"&&t.protocol!=="http:")throw new TypeError("The iframe URL must use HTTP(S).");return t.origin}const x=s=>{if(s===null||typeof s!="object")return!1;const t=Object.getPrototypeOf(s);return t===Object.prototype||t===null},_=s=>x(s)?s.source==="yourroad.embed"&&s.version===u&&s.type==="ready"&&s.payload===void 0&&(s.requestId===void 0||typeof s.requestId=="string"):!1,m=(s,t)=>x(s)&&Object.keys(s).length===3&&s.source==="yourroad.embed"&&s.version===u&&s.type===t;class N{constructor(t,e,r,o,a,n=()=>{}){i(this,"ready",!1);i(this,"started",!1);i(this,"readinessSettled",!1);i(this,"readiness");i(this,"resolveReadiness");i(this,"rejectReadiness");i(this,"handleMessage",t=>{if(t.origin!==this.trustedRuntimeOrigin)return;const e=this.iframe.contentWindow;if(!(e===null||t.source!==e)){if(this.ready){m(t.data,"journey_session_restart")?this.onJourneySessionRestart():m(t.data,"journey_reset")&&this.onJourneyReset();return}_(t.data)&&(this.ready=!0,this.post({source:"yourroad.sdk",version:u,type:"ack"}),this.post({source:"yourroad.sdk",version:u,type:"context",payload:f(this.getCurrentContext())}),this.sendJourneySession(this.getJourneySessionId()),this.readinessSettled=!0,this.resolveReadiness())}});this.iframe=t,this.trustedRuntimeOrigin=e,this.getCurrentContext=r,this.getJourneySessionId=o,this.onJourneySessionRestart=a,this.onJourneyReset=n,this.readiness=new Promise((l,d)=>{this.resolveReadiness=l,this.rejectReadiness=d}),this.readiness.catch(()=>{})}start(){this.started||(window.addEventListener("message",this.handleMessage),this.started=!0)}contextUpdated(t){this.ready&&this.post({source:"yourroad.sdk",version:u,type:"context_updated",payload:f(t)})}whenReady(){return this.readiness}failReadiness(t){this.readinessSettled||(this.readinessSettled=!0,this.rejectReadiness(t))}destroy(){this.started&&window.removeEventListener("message",this.handleMessage),this.started=!1,this.ready=!1,this.failReadiness(new Error("The runtime bridge was destroyed before it became ready."))}sendJourneySession(t){this.ready&&this.post({source:"yourroad.sdk",version:u,type:"journey_session",payload:{sessionId:t}})}post(t){const e=this.iframe.contentWindow;if(e!==null)try{e.postMessage(t,this.trustedRuntimeOrigin)}catch{}}}class p extends Error{constructor(e,r,o){super(r,o);i(this,"name","YourRoadError");this.code=e}}class C{constructor(){i(this,"listeners",new Map)}on(t,e){const r=this.listeners.get(t)??new Set;return r.add(e),this.listeners.set(t,r),()=>r.delete(e)}emit(t,e){var r;(r=this.listeners.get(t))==null||r.forEach(o=>o(e))}clear(){this.listeners.clear()}}class J{constructor(){i(this,"previous",null)}capture(){var t;(t=this.previous)!=null&&t.isConnected||(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(){i(this,"saved");i(this,"scrollX",0);i(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 P{constructor(t,e){i(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 Y=2147483e3,q=`
2
+ [data-yourroad-overlay-root] { all: initial; position: fixed; inset: 0; z-index: ${Y}; display: block; font-family: system-ui, sans-serif; color: #111; }
3
+ [data-yourroad-overlay-root][hidden] { display: none; pointer-events: none; }
3
4
  [data-yourroad-scrim] { all: initial; position: absolute; inset: 0; display: block; background: rgba(0, 0, 0, .55); }
4
5
  [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
6
  [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
7
  [data-yourroad-close]:focus-visible { outline: 3px solid #1769e0; outline-offset: 2px; }
7
8
  [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
9
  @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
+ `;function D(){const s=document.head.querySelector("style[data-yourroad-sdk]");if(s)return s;const t=document.createElement("style");return t.dataset.yourroadSdk="",t.textContent=q,document.head.append(t),t}class M{constructor(t,e,r){i(this,"root");i(this,"closeButton");i(this,"iframe");i(this,"abort",new AbortController);i(this,"visible",!1);D(),this.root=document.createElement("div"),this.root.dataset.yourroadOverlayRoot="",this.root.setAttribute("aria-label","YourRoad pre-approval"),this.hide();const o=document.createElement("div");o.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 l=document.createElementNS("http://www.w3.org/2000/svg","path");l.setAttribute("d","M6 6l12 12M18 6L6 18"),n.append(l),this.closeButton.append(n),this.iframe=new P(t,r),a.append(this.closeButton,this.iframe.element),this.root.append(o,a);const d=this.abort.signal;o.addEventListener("click",e,{signal:d}),this.closeButton.addEventListener("click",e,{signal:d}),document.addEventListener("keydown",h=>{this.visible&&h.key==="Escape"&&e()},{signal:d})}mount(){document.body.append(this.root)}show(){return this.visible?!1:(this.visible=!0,this.root.hidden=!1,this.root.inert=!1,this.root.removeAttribute("aria-hidden"),this.root.setAttribute("role","dialog"),this.root.setAttribute("aria-modal","true"),!0)}hide(){if(!this.visible&&this.root.hidden)return!1;const t=this.visible;return this.visible=!1,this.root.hidden=!0,this.root.inert=!0,this.root.setAttribute("aria-hidden","true"),this.root.removeAttribute("role"),this.root.removeAttribute("aria-modal"),t}isVisible(){return this.visible}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 y="yr_journey_session_pre_approval_v1",b=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);function U(){try{return globalThis.localStorage}catch{return}}function B(s=U()){const t=()=>{try{s==null||s.removeItem(y)}catch{}};return{read(){let e;try{e=(s==null?void 0:s.getItem(y))??null}catch{return}if(e!==null){if(!b(e)){t();return}return e}},write(e){if(b(e))try{s==null||s.setItem(y,e)}catch{}},clear:t}}const K="https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/create-embed-journey-session",V="https://tsajlkcfcvjqqjxfigbw.supabase.co/functions/v1/probe-embed-journey-session",E=s=>{if(s===null||typeof s!="object")return!1;const t=Object.getPrototypeOf(s);return t===Object.prototype||t===null},R=s=>typeof s=="string"&&s.trim()!==""&&!Number.isNaN(Date.parse(s)),A=(s,t)=>({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s),credentials:"omit",cache:"no-store",signal:t});async function w(s,t){const e=await fetch(K,A({partnerKey:s,surface:"pre-approval"},t));if(e.status!==201)throw new Error("Journey session creation was unsuccessful.");const r=await e.json();if(!E(r)||!b(r.sessionId)||!R(r.expiresAt))throw new Error("Invalid journey session response.");return r.sessionId}async function F(s,t){const e=await fetch(V,A({partnerKey:s,surface:"pre-approval",sessionId:t})),r=await e.json();if(!E(r))throw new Error("Invalid journey session probe response.");if(e.status===200&&r.status==="resumable"&&r.sessionId===t&&R(r.expiresAt))return{status:"resumable",sessionId:t};if(e.status===410&&r.status==="expired"&&r.code==="SESSION_EXPIRED")return{status:"expired"};if(e.status===404&&r.status==="invalid"&&r.code==="SESSION_INVALID")return{status:"invalid"};throw new Error("Journey session probe was unsuccessful.")}class X{constructor(t,e=B()){i(this,"state",{kind:"cold"});i(this,"restart");i(this,"generation",0);this.partnerKey=t,this.marker=e;const r=e.read();if(!r)return;const o=this.probe(r,this.generation);this.state={kind:"probing",completion:o}}async resolveForOpen(t){const e=this.generation;if(this.state.kind==="probing"&&await this.state.completion,e!==this.generation)throw new Error("Journey session operation was superseded.");if(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 r=await w(this.partnerKey,t);if(e!==this.generation)throw new Error("Journey session operation was superseded.");return this.marker.write(r),this.state={kind:"active",sessionId:r},r}restartExpired(t){if(this.state.kind!=="expired")return;if(this.restart)return this.restart;const e=this.generation,r=w(this.partnerKey,t).then(o=>{if(e!==this.generation)throw new Error("Journey session operation was superseded.");return this.marker.write(o),this.state={kind:"active",sessionId:o},o}).finally(()=>{this.restart===r&&(this.restart=void 0)});return this.restart=r,r}resetForNewJourney(){this.generation+=1,this.restart=void 0,this.marker.clear(),this.state={kind:"cold"}}invalidatePendingOperations(){this.generation+=1,this.restart=void 0}async probe(t,e){try{const r=await F(this.partnerKey,t);if(e!==this.generation)return;r.status==="resumable"?this.state={kind:"active",sessionId:t}:r.status==="expired"?(this.marker.clear(),this.state={kind:"expired",sessionId:t}):(this.marker.clear(),this.state={kind:"cold"})}catch{e===this.generation&&(this.state={kind:"probe_failed"})}}}class z{constructor(t){i(this,"events",new C);i(this,"scroll",new L);i(this,"focus",new J);i(this,"overlay");i(this,"bridge");i(this,"context",{});i(this,"destroyed",!1);i(this,"preparing");i(this,"mounting");i(this,"wantsVisible",!1);i(this,"visibilityRequest",0);i(this,"bootstrapAbort");i(this,"restartAbort");i(this,"resetting");i(this,"session");this.config=t,this.session=new X(t.partnerKey)}async open(t){this.assertUsable(),this.validateOptions(t),this.adoptContext(t);const e=++this.visibilityRequest;if(this.wantsVisible=!0,this.overlay){this.show();return}try{await this.ensureMounted(t.surface)}catch(r){throw this.visibilityRequest===e&&(this.wantsVisible=!1),r}}async prepare(t){if(this.assertUsable(),this.validateOptions(t),this.adoptContext(t),this.bridge)return this.bridge.whenReady();if(this.preparing)return this.preparing;const e=this.performPrepare(t.surface);return this.preparing=e,e}async ensureMounted(t){if(this.overlay){this.wantsVisible&&this.show();return}if(this.mounting)return this.mounting;const e=new AbortController;this.bootstrapAbort=e;const r=this.performMount(t,e);return this.mounting=r,r}updateContext(t){var e;this.assertUsable(),this.context=g(this.context,t),(e=this.bridge)==null||e.contextUpdated(this.context)}close(){var t;this.assertUsable(),this.visibilityRequest+=1,this.wantsVisible=!1,(t=this.overlay)!=null&&t.hide()&&(this.scroll.unlock(),this.focus.restore(),this.events.emit("closed",void 0))}on(t,e){return this.assertUsable(),this.events.on(t,e)}destroy(){var t,e,r,o;this.destroyed||(this.visibilityRequest+=1,this.wantsVisible=!1,(t=this.bootstrapAbort)==null||t.abort(),this.bootstrapAbort=void 0,(e=this.restartAbort)==null||e.abort(),this.restartAbort=void 0,this.session.invalidatePendingOperations(),(r=this.bridge)==null||r.destroy(),this.bridge=void 0,(o=this.overlay)==null||o.destroy(),this.overlay=void 0,this.scroll.unlock(),this.focus.restore(),this.events.clear(),this.context={},this.destroyed=!0)}async performPrepare(t){var e;try{await this.ensureMounted(t),await((e=this.bridge)==null?void 0:e.whenReady())}catch(r){if(!this.destroyed)throw r}finally{this.preparing=void 0}}async performMount(t,e,r){var o,a;try{const[n,l]=await Promise.all([j({partnerKey:this.config.partnerKey,surface:t},e.signal),this.session.resolveForOpen(e.signal)]),{iframeUrl:d}=n;if(e.signal.aborted||this.destroyed||this.bootstrapAbort!==e)return;try{const h=new M(d,()=>this.close(),()=>this.runtimeFailed());this.overlay=h;const c=new N(h.iframe.element,T(d),()=>f(this.context),()=>l,()=>this.restartExpiredSession(c),()=>this.resetJourneyRuntime(c,t));this.bridge=c,c.start(),h.mount(),this.wantsVisible&&this.show(r===void 0||this.visibilityRequest!==r)}catch(h){throw(o=this.bridge)==null||o.destroy(),this.bridge=void 0,(a=this.overlay)==null||a.destroy(),this.overlay=void 0,this.scroll.unlock(),this.focus.restore(),this.fail("OVERLAY_CREATION_FAILED","The YourRoad overlay could not be created.",h)}}catch(n){if(e.signal.aborted)return;throw n instanceof p?n:this.fail("BOOTSTRAP_FAILED","The YourRoad experience could not be started securely.",n)}finally{this.bootstrapAbort===e&&(this.bootstrapAbort=void 0,this.mounting=void 0)}}show(t=!0){var e;(e=this.overlay)!=null&&e.show()&&(this.focus.capture(),this.scroll.lock(),this.focus.moveTo(this.overlay.closeButton),t&&this.events.emit("opened",void 0))}runtimeFailed(){var r,o,a,n;const t=this.fail("IFRAME_LOAD_FAILED","The embedded experience failed to load.");(r=this.bridge)==null||r.failReadiness(t),(o=this.bridge)==null||o.destroy(),this.bridge=void 0;const e=((a=this.overlay)==null?void 0:a.isVisible())??!1;(n=this.overlay)==null||n.destroy(),this.overlay=void 0,e&&(this.scroll.unlock(),this.focus.restore())}validateOptions(t){if(!t||t.surface!=="pre-approval")throw this.fail("INVALID_SURFACE",'The only supported surface is "pre-approval".')}adoptContext(t){var e;t.context!==void 0&&(this.context=f(t.context),(e=this.bridge)==null||e.contextUpdated(this.context))}restartExpiredSession(t){if(this.destroyed||t===void 0||t!==this.bridge||this.restartAbort)return;const e=new AbortController;this.restartAbort=e;const r=this.session.restartExpired(e.signal);if(!r){this.restartAbort=void 0;return}r.then(o=>{!this.destroyed&&!e.signal.aborted&&this.bridge===t&&t.sendJourneySession(o)}).catch(()=>{}).finally(()=>{this.restartAbort===e&&(this.restartAbort=void 0)})}resetJourneyRuntime(t,e){if(this.destroyed||t!==this.bridge||this.resetting)return;const r=this.performJourneyReset(e);this.resetting=r,r.catch(()=>{}).finally(()=>{this.resetting===r&&(this.resetting=void 0)})}async performJourneyReset(t){var a,n,l,d,h;const e=(a=this.overlay)!=null&&a.isVisible()?this.visibilityRequest:void 0;if((n=this.bootstrapAbort)==null||n.abort(),this.bootstrapAbort=void 0,this.mounting=void 0,(l=this.restartAbort)==null||l.abort(),this.restartAbort=void 0,this.session.resetForNewJourney(),(d=this.bridge)==null||d.destroy(),this.bridge=void 0,(h=this.overlay)==null||h.destroy(),this.overlay=void 0,this.destroyed)return;const r=new AbortController;this.bootstrapAbort=r;const o=this.performMount(t,r,e);this.mounting=o;try{await o}catch(c){throw!this.destroyed&&!this.overlay&&(this.scroll.unlock(),this.focus.restore()),c}}assertUsable(){if(this.destroyed)throw new p("DESTROYED","This YourRoad SDK instance has been destroyed.")}fail(t,e,r){const o=new p(t,e,r===void 0?void 0:{cause:r});return this.events.emit("error",o),o}}function $(s){return new z(s)}class W{static init(t){if(!t||typeof t.partnerKey!="string"||t.partnerKey.trim()==="")throw new p("INVALID_INITIALISATION","partnerKey must be a non-empty string.");return $({partnerKey:t.partnerKey})}}exports.YourRoad=W;exports.YourRoadError=p;
10
11
  //# 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; 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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"}
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\n/** Identity-free, exact-shape lifecycle messages accepted from a trusted runtime. */\nexport type RuntimeLifecycleMessage =\n | { source: 'yourroad.embed'; version: typeof BRIDGE_VERSION; type: 'journey_session_restart' }\n | { source: 'yourroad.embed'; version: typeof BRIDGE_VERSION; type: 'journey_reset' };\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 isLifecycleMessage = (value: unknown, type: 'journey_session_restart' | 'journey_reset'): boolean => isPlainObject(value)\n && Object.keys(value).length === 3\n && value.source === 'yourroad.embed'\n && value.version === BRIDGE_VERSION\n && value.type === type;\n\nexport class BridgeController {\n private ready = false;\n private started = false;\n private readinessSettled = false;\n private readonly readiness: Promise<void>;\n private resolveReadiness!: () => void;\n private rejectReadiness!: (reason: unknown) => void;\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 private readonly onJourneyReset: () => void = () => undefined,\n ) {\n this.readiness = new Promise<void>((resolve, reject) => {\n this.resolveReadiness = resolve;\n this.rejectReadiness = reject;\n });\n // A client that only calls open() need not observe readiness. Keep teardown\n // rejection handled while preserving the original promise for prepare().\n void this.readiness.catch(() => undefined);\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 whenReady(): Promise<void> { return this.readiness; }\n\n failReadiness(reason: unknown): void {\n if (this.readinessSettled) return;\n this.readinessSettled = true;\n this.rejectReadiness(reason);\n }\n\n destroy(): void {\n if (this.started) window.removeEventListener('message', this.handleMessage);\n this.started = false;\n this.ready = false;\n this.failReadiness(new Error('The runtime bridge was destroyed before it became ready.'));\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 (isLifecycleMessage(event.data, 'journey_session_restart')) this.onJourneySessionRestart();\n else if (isLifecycleMessage(event.data, 'journey_reset')) this.onJourneyReset();\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 this.readinessSettled = true;\n this.resolveReadiness();\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 {\n // A secure runtime replacement is one continuous visible interaction.\n if (this.previous?.isConnected) return;\n this.previous = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n }\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-overlay-root][hidden] { display: none; pointer-events: none; }\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 private visible = false;\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('aria-label', 'YourRoad pre-approval');\n this.hide();\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 (this.visible && event.key === 'Escape') onClose(); }, { signal });\n }\n\n mount(): void { document.body.append(this.root); }\n show(): boolean {\n if (this.visible) return false;\n this.visible = true;\n this.root.hidden = false;\n this.root.inert = false;\n this.root.removeAttribute('aria-hidden');\n this.root.setAttribute('role', 'dialog');\n this.root.setAttribute('aria-modal', 'true');\n return true;\n }\n hide(): boolean {\n if (!this.visible && this.root.hidden) return false;\n const wasVisible = this.visible;\n this.visible = false;\n this.root.hidden = true;\n this.root.inert = true;\n this.root.setAttribute('aria-hidden', 'true');\n this.root.removeAttribute('role');\n this.root.removeAttribute('aria-modal');\n return wasVisible;\n }\n isVisible(): boolean { return this.visible; }\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 private generation = 0;\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, this.generation);\n this.state = { kind: 'probing', completion };\n }\n\n async resolveForOpen(signal: AbortSignal): Promise<string> {\n const generation = this.generation;\n if (this.state.kind === 'probing') await this.state.completion;\n if (generation !== this.generation) throw new Error('Journey session operation was superseded.');\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 if (generation !== this.generation) throw new Error('Journey session operation was superseded.');\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 generation = this.generation;\n const operation = createJourneySession(this.partnerKey, signal).then((sessionId) => {\n if (generation !== this.generation) throw new Error('Journey session operation was superseded.');\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 resetForNewJourney(): void {\n this.generation += 1;\n this.restart = undefined;\n this.marker.clear();\n this.state = { kind: 'cold' };\n }\n\n invalidatePendingOperations(): void {\n this.generation += 1;\n this.restart = undefined;\n }\n\n private async probe(sessionId: string, generation: number): Promise<void> {\n try {\n const result = await probeJourneySession(this.partnerKey, sessionId);\n if (generation !== this.generation) return;\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 { if (generation === this.generation) 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 prepare(options: OpenOptions): Promise<void>;\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 preparing?: Promise<void>;\n private mounting?: Promise<void>;\n private wantsVisible = false;\n private visibilityRequest = 0;\n private bootstrapAbort?: AbortController;\n private restartAbort?: AbortController;\n private resetting?: Promise<void>;\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 this.validateOptions(options);\n this.adoptContext(options);\n const visibilityRequest = ++this.visibilityRequest;\n this.wantsVisible = true;\n if (this.overlay) { this.show(); return; }\n try {\n await this.ensureMounted(options.surface);\n } catch (cause) {\n if (this.visibilityRequest === visibilityRequest) this.wantsVisible = false;\n throw cause;\n }\n }\n\n async prepare(options: OpenOptions): Promise<void> {\n this.assertUsable();\n this.validateOptions(options);\n this.adoptContext(options);\n if (this.bridge) return this.bridge.whenReady();\n if (this.preparing) return this.preparing;\n const operation = this.performPrepare(options.surface);\n this.preparing = operation;\n return operation;\n }\n\n private async ensureMounted(surface: YourRoadSurface): Promise<void> {\n if (this.overlay) { if (this.wantsVisible) this.show(); return; }\n if (this.mounting) return this.mounting;\n const abort = new AbortController();\n this.bootstrapAbort = abort;\n const operation = this.performMount(surface, abort);\n this.mounting = 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 this.visibilityRequest += 1;\n this.wantsVisible = false;\n if (!this.overlay?.hide()) return;\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.visibilityRequest += 1;\n this.wantsVisible = false;\n this.bootstrapAbort?.abort();\n this.bootstrapAbort = undefined;\n this.restartAbort?.abort();\n this.restartAbort = undefined;\n this.session.invalidatePendingOperations();\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.clear();\n this.context = {};\n this.destroyed = true;\n }\n\n private async performPrepare(surface: YourRoadSurface): Promise<void> {\n try {\n await this.ensureMounted(surface);\n await this.bridge?.whenReady();\n } catch (cause) {\n if (!this.destroyed) throw cause;\n } finally {\n this.preparing = undefined;\n }\n }\n\n private async performMount(surface: YourRoadSurface, abort: AbortController, continuousVisibilityRequest?: number): 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 try {\n const overlay = new OverlayController(iframeUrl, () => this.close(), () => this.runtimeFailed());\n this.overlay = overlay;\n const bridge = new BridgeController(\n overlay.iframe.element,\n runtimeOriginFromIframeUrl(iframeUrl),\n () => copyContext(this.context),\n () => sessionId,\n () => this.restartExpiredSession(bridge),\n () => this.resetJourneyRuntime(bridge, surface),\n );\n this.bridge = bridge;\n bridge.start();\n overlay.mount();\n if (this.wantsVisible) {\n this.show(continuousVisibilityRequest === undefined || this.visibilityRequest !== continuousVisibilityRequest);\n }\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.mounting = undefined;\n }\n }\n }\n\n private show(emitEvent = true): void {\n if (!this.overlay?.show()) return;\n this.focus.capture();\n this.scroll.lock();\n this.focus.moveTo(this.overlay.closeButton);\n if (emitEvent) this.events.emit('opened', undefined);\n }\n\n private runtimeFailed(): void {\n const error = this.fail('IFRAME_LOAD_FAILED', 'The embedded experience failed to load.');\n this.bridge?.failReadiness(error);\n this.bridge?.destroy();\n this.bridge = undefined;\n const wasVisible = this.overlay?.isVisible() ?? false;\n this.overlay?.destroy();\n this.overlay = undefined;\n if (wasVisible) { this.scroll.unlock(); this.focus.restore(); }\n }\n\n private validateOptions(options: OpenOptions): void {\n if (!options || options.surface !== 'pre-approval') throw this.fail('INVALID_SURFACE', 'The only supported surface is \"pre-approval\".');\n }\n\n private adoptContext(options: OpenOptions): void {\n if (options.context !== undefined) {\n this.context = copyContext(options.context);\n this.bridge?.contextUpdated(this.context);\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 resetJourneyRuntime(bridge: BridgeController, surface: YourRoadSurface): void {\n if (this.destroyed || bridge !== this.bridge || this.resetting) return;\n const operation = this.performJourneyReset(surface);\n this.resetting = operation;\n void operation.catch(() => { /* Normal SDK error reporting is performed by the mount path. */ }).finally(() => {\n if (this.resetting === operation) this.resetting = undefined;\n });\n }\n\n private async performJourneyReset(surface: YourRoadSurface): Promise<void> {\n const continuousVisibilityRequest = this.overlay?.isVisible() ? this.visibilityRequest : undefined;\n this.bootstrapAbort?.abort();\n this.bootstrapAbort = undefined;\n this.mounting = undefined;\n this.restartAbort?.abort();\n this.restartAbort = undefined;\n this.session.resetForNewJourney();\n\n this.bridge?.destroy();\n this.bridge = undefined;\n this.overlay?.destroy();\n this.overlay = undefined;\n\n if (this.destroyed) return;\n const abort = new AbortController();\n this.bootstrapAbort = abort;\n const operation = this.performMount(surface, abort, continuousVisibilityRequest);\n this.mounting = operation;\n try {\n await operation;\n } catch (cause) {\n if (!this.destroyed && !this.overlay) {\n this.scroll.unlock();\n this.focus.restore();\n }\n throw cause;\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","isLifecycleMessage","type","BridgeController","iframe","trustedRuntimeOrigin","getCurrentContext","getJourneySessionId","onJourneySessionRestart","onJourneyReset","__publicField","event","iframeWindow","resolve","reject","currentContext","reason","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","wasVisible","JOURNEY_SESSION_MARKER_KEY","isUuid","resolveStorage","createSessionMarker","storage","clear","CREATE_ENDPOINT","PROBE_ENDPOINT","isDate","body","createJourneySession","partnerKey","probeJourneySession","SessionController","marker","completion","generation","operation","result","YourRoadClientImpl","config","visibilityRequest","cause","surface","abort","_b","_c","_d","continuousVisibilityRequest","bootstrap","overlay","bridge","emitEvent","error","restartAbort","_e","createYourRoadClient","YourRoad"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -37,6 +37,7 @@ export declare class YourRoad {
37
37
  }
38
38
 
39
39
  export declare interface YourRoadClient {
40
+ prepare(options: OpenOptions): Promise<void>;
40
41
  open(options: OpenOptions): Promise<void>;
41
42
  updateContext(update: YourRoadContextUpdate): void;
42
43
  close(): void;