forgeframe 0.0.12 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- (function(l,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(l=typeof globalThis<"u"?globalThis:l||self,d(l.ForgeFrame={}))})(this,(function(l){"use strict";const d={IFRAME:"iframe",POPUP:"popup"},g={RENDER:"render",RENDERED:"rendered",PRERENDER:"prerender",PRERENDERED:"prerendered",DISPLAY:"display",ERROR:"error",CLOSE:"close",DESTROY:"destroy",PROPS:"props",RESIZE:"resize",FOCUS:"focus"},v={JSON:"json",BASE64:"base64",DOTIFY:"dotify"},z={REQUEST:"request",RESPONSE:"response"},h={INIT:"forgeframe_init",PROPS:"forgeframe_props",CLOSE:"forgeframe_close",RESIZE:"forgeframe_resize",FOCUS:"forgeframe_focus",SHOW:"forgeframe_show",HIDE:"forgeframe_hide",ERROR:"forgeframe_error",EXPORT:"forgeframe_export",CALL:"forgeframe_call",CONSUMER_EXPORT:"forgeframe_consumer_export",GET_SIBLINGS:"forgeframe_get_siblings"},k="__forgeframe__",W=(()=>{if("0.0.12".trim().length===0)throw new Error("ForgeFrame VERSION injection is missing. Configure __FORGEFRAME_VERSION__ in build/test tooling.");return"0.0.12"})();class Oe{listeners=new Map;on(e,n){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(n),()=>this.off(e,n)}once(e,n){const s=r=>(this.off(e,s),n(r));return this.on(e,s)}emit(e,n){const s=this.listeners.get(e);if(s)for(const r of s)try{const i=r(n);i&&typeof i=="object"&&"catch"in i&&typeof i.catch=="function"&&i.catch(o=>{console.error(`Error in async event handler for "${e}":`,o)})}catch(i){console.error(`Error in event handler for "${e}":`,i)}}off(e,n){if(!n){this.listeners.delete(e);return}const s=this.listeners.get(e);s&&(s.delete(n),s.size===0&&this.listeners.delete(e))}removeAllListeners(){this.listeners.clear()}listenerCount(e){return this.listeners.get(e)?.size??0}}function ut(){const t=Date.now().toString(36),e=Math.random().toString(36).slice(2,11);return`${t}_${e}`}function j(){return Math.random().toString(36).slice(2,11)}class lt{tasks=[];cleaned=!1;register(e){if(this.cleaned){Promise.resolve().then(()=>e()).catch(n=>{console.error("Error in cleanup task:",n)});return}this.tasks.push(e)}async cleanup(){if(this.cleaned)return;this.cleaned=!0;const e=this.tasks.reverse();this.tasks=[];for(const n of e)try{await n()}catch(s){console.error("Error in cleanup task:",s)}}isCleaned(){return this.cleaned}reset(){this.tasks=[],this.cleaned=!1}}function Ce(){let t,e;return{promise:new Promise((s,r)=>{t=s,e=r}),resolve:t,reject:e}}function ht(t,e,n="Operation timed out"){return new Promise((s,r)=>{const i=setTimeout(()=>{r(new Error(`${n} (${e}ms)`))},e);t.then(o=>{clearTimeout(i),s(o)}).catch(o=>{clearTimeout(i),r(o)})})}const x=new Map,dt=200;function ft(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function pt(t){if(!t.includes("*"))return null;const e=x.get(t);if(e)return e;const n=t.split("*").map(r=>ft(r)).join(".*"),s=new RegExp(`^${n}$`);if(x.size>=dt){const r=x.keys().next().value;r&&x.delete(r)}return x.set(t,s),s}function mt(t,e){return t.global||t.sticky?new RegExp(t.source,t.flags.replace(/[gy]/g,"")).test(e):t.test(e)}function B(t=window){try{return t.location.origin}catch{return""}}function Se(t,e=window){try{return t.location.origin===e.location.origin}catch{return!1}}function T(t,e){if(typeof t=="string"){if(t==="*")return!0;const n=pt(t);return n?n.test(e):t===e}return t instanceof RegExp?mt(t,e):Array.isArray(t)?t.some(n=>T(n,e)):!1}function oe(t){if(!t)return!0;try{return t.closed}catch{return!0}}function gt(t=window){try{return t.opener}catch{return null}}function yt(t=window){try{const e=t.parent;return e&&e!==t?e:null}catch{return null}}function wt(t=window){try{return t.parent!==t}catch{return!0}}function _t(t=window){try{return t.opener!==null&&t.opener!==void 0}catch{return!1}}const Re=100,b=new Map;function Pt(){const t=[];for(const[e,n]of b.entries())oe(n)&&t.push(e);for(const e of t)b.delete(e)}function Et(t,e){if(b.size>=Re&&Pt(),b.size>=Re){const n=b.keys().next().value;n&&b.delete(n)}b.set(t,e)}function bt(t){b.delete(t)}function Ot(t,e){return t.global||t.sticky?new RegExp(t.source,t.flags.replace(/[gy]/g,"")).test(e):t.test(e)}class _{_optional=!1;_nullable=!1;_default;"~standard"={version:1,vendor:"forgeframe",validate:e=>e===null?this._nullable?{value:null}:{issues:[{message:"Expected a value, got null"}]}:e===void 0?this._default!==void 0?{value:typeof this._default=="function"?this._default():this._default}:this._optional?{value:void 0}:{issues:[{message:"Required"}]}:this._validate(e)};optional(){const e=this._clone();return e._optional=!0,e}nullable(){const e=this._clone();return e._nullable=!0,e}default(e){const n=this._clone();return n._default=e,n}}class V extends _{_minLength;_maxLength;_pattern;_patternMessage;_trim=!1;_validate(e){if(typeof e!="string")return{issues:[{message:`Expected string, got ${typeof e}`}]};const n=this._trim?e.trim():e;return this._minLength!==void 0&&n.length<this._minLength?{issues:[{message:`String must be at least ${this._minLength} characters`}]}:this._maxLength!==void 0&&n.length>this._maxLength?{issues:[{message:`String must be at most ${this._maxLength} characters`}]}:this._pattern&&!Ot(this._pattern,n)?{issues:[{message:this._patternMessage||`String must match pattern ${this._pattern}`}]}:{value:n}}_clone(){const e=new V;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._minLength=this._minLength,e._maxLength=this._maxLength,e._pattern=this._pattern,e._patternMessage=this._patternMessage,e._trim=this._trim,e}min(e){const n=this._clone();return n._minLength=e,n}max(e){const n=this._clone();return n._maxLength=e,n}length(e){const n=this._clone();return n._minLength=e,n._maxLength=e,n}pattern(e,n){const s=this._clone();return s._pattern=e,s._patternMessage=n,s}email(){return this.pattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/,"Invalid email address")}url(){return this.pattern(/^https?:\/\/.+/,"Invalid URL")}uuid(){return this.pattern(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,"Invalid UUID")}trim(){const e=this._clone();return e._trim=!0,e}nonempty(){const e=this._clone();return e._minLength=1,e}}class Y extends _{_min;_max;_int=!1;_validate(e){return typeof e!="number"||Number.isNaN(e)?{issues:[{message:`Expected number, got ${typeof e}`}]}:this._int&&!Number.isInteger(e)?{issues:[{message:"Expected integer"}]}:this._min!==void 0&&e<this._min?{issues:[{message:`Number must be >= ${this._min}`}]}:this._max!==void 0&&e>this._max?{issues:[{message:`Number must be <= ${this._max}`}]}:{value:e}}_clone(){const e=new Y;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._min=this._min,e._max=this._max,e._int=this._int,e}min(e){const n=this._clone();return n._min=e,n}max(e){const n=this._clone();return n._max=e,n}int(){const e=this._clone();return e._int=!0,e}positive(){const e=this._clone();return e._min=Number.MIN_VALUE,e}nonnegative(){const e=this._clone();return e._min=0,e}negative(){const e=this._clone();return e._max=-Number.MIN_VALUE,e}}class J extends _{_validate(e){return typeof e!="boolean"?{issues:[{message:`Expected boolean, got ${typeof e}`}]}:{value:e}}_clone(){const e=new J;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class q extends _{_validate(e){return typeof e!="function"?{issues:[{message:`Expected function, got ${typeof e}`}]}:{value:e}}_clone(){const e=new q;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class U extends _{_itemSchema;_minLength;_maxLength;_validate(e){if(!Array.isArray(e))return{issues:[{message:`Expected array, got ${typeof e}`}]};if(this._minLength!==void 0&&e.length<this._minLength)return{issues:[{message:`Array must have at least ${this._minLength} items`}]};if(this._maxLength!==void 0&&e.length>this._maxLength)return{issues:[{message:`Array must have at most ${this._maxLength} items`}]};if(this._itemSchema){const n=[];for(let s=0;s<e.length;s++){const r=this._itemSchema["~standard"].validate(e[s]);if(r instanceof Promise)throw new Error("Async schema validation is not supported. Use synchronous schemas.");if(r.issues)return{issues:r.issues.map(i=>({...i,path:[s,...i.path||[]]}))};n.push(r.value)}return{value:n}}return{value:e}}_clone(){const e=new U;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._itemSchema=this._itemSchema,e._minLength=this._minLength,e._maxLength=this._maxLength,e}of(e){const n=new U;return n._optional=this._optional,n._nullable=this._nullable,n._itemSchema=e,n._minLength=this._minLength,n._maxLength=this._maxLength,n}min(e){const n=this._clone();return n._minLength=e,n}max(e){const n=this._clone();return n._maxLength=e,n}nonempty(){return this.min(1)}}class H extends _{_shape;_strict=!1;_validate(e){if(typeof e!="object"||e===null||Array.isArray(e))return{issues:[{message:`Expected object, got ${Array.isArray(e)?"array":typeof e}`}]};const n=e,s={};if(this._shape){if(this._strict){const r=new Set(Object.keys(this._shape));for(const i of Object.keys(n))if(!r.has(i))return{issues:[{message:`Unknown key: ${i}`,path:[i]}]}}for(const[r,i]of Object.entries(this._shape)){const o=i["~standard"].validate(n[r]);if(o instanceof Promise)throw new Error("Async schema validation is not supported. Use synchronous schemas.");if(o.issues)return{issues:o.issues.map(a=>({...a,path:[r,...a.path||[]]}))};s[r]=o.value}if(!this._strict)for(const r of Object.keys(n))r in this._shape||(s[r]=n[r]);return{value:s}}return{value:e}}_clone(){const e=new H;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._shape=this._shape,e._strict=this._strict,e}shape(e){const n=new H;return n._optional=this._optional,n._nullable=this._nullable,n._shape=e,n._strict=this._strict,n}strict(){const e=this._clone();return e._strict=!0,e}}class K extends _{_value;constructor(e){super(),this._value=e}_validate(e){return e!==this._value?{issues:[{message:`Expected ${JSON.stringify(this._value)}, got ${JSON.stringify(e)}`}]}:{value:e}}_clone(){const e=new K(this._value);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class X extends _{_values;_valueSet;constructor(e){super(),this._values=e,this._valueSet=new Set(e)}_validate(e){return this._valueSet.has(e)?{value:e}:{issues:[{message:`Expected one of [${this._values.map(n=>JSON.stringify(n)).join(", ")}], got ${JSON.stringify(e)}`}]}}_clone(){const e=new X(this._values);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class G extends _{constructor(){super(),this._nullable=!0}_validate(e){return{value:e}}_clone(){const e=new G;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}const m={string:()=>new V,number:()=>new Y,boolean:()=>new J,function:()=>new q,array:()=>new U,object:()=>new H,literal:t=>new K(t),enum:t=>new X(t),any:()=>new G},C={uid:{schema:m.string().optional(),sendToHost:!0},tag:{schema:m.string().optional(),sendToHost:!0},dimensions:{schema:m.object().default(()=>({width:"100%",height:"100%"})),sendToHost:!1},timeout:{schema:m.number().default(1e4),sendToHost:!1},cspNonce:{schema:m.string().optional(),sendToHost:!0},onDisplay:{schema:m.function().optional(),sendToHost:!1},onRendered:{schema:m.function().optional(),sendToHost:!1},onRender:{schema:m.function().optional(),sendToHost:!1},onPrerendered:{schema:m.function().optional(),sendToHost:!1},onPrerender:{schema:m.function().optional(),sendToHost:!1},onClose:{schema:m.function().optional(),sendToHost:!1},onDestroy:{schema:m.function().optional(),sendToHost:!1},onResize:{schema:m.function().optional(),sendToHost:!1},onFocus:{schema:m.function().optional(),sendToHost:!1},onError:{schema:m.function().optional(),sendToHost:!1},onProps:{schema:m.function().optional(),sendToHost:!1}};function S(t){return typeof t=="object"&&t!==null&&"~standard"in t&&typeof t["~standard"]=="object"&&t["~standard"]!==null&&t["~standard"].version===1&&typeof t["~standard"].vendor=="string"&&typeof t["~standard"].validate=="function"}function Ct(t,e,n){const s=t["~standard"].validate(e);if(s instanceof Promise)throw new Error(`Prop "${n}" uses an async schema. ForgeFrame only supports synchronous schema validation. Please use a synchronous schema or remove async operations (like database lookups) from your schema definition.`);if(s.issues){const r=s.issues.map(i=>`${St(i.path,n)}: ${i.message}`);throw new Error(`Validation failed: ${r.join("; ")}`)}return s.value}function St(t,e){if(!t||t.length===0)return e;const n=t.map(s=>{if(typeof s=="object"&&s!==null){if("key"in s&&s.key!==void 0)return String(s.key);if("index"in s&&typeof s.index=="number")return String(s.index)}return String(s)});return`${e}.${n.join(".")}`}function N(t){const e=S(t);return{isDirectSchema:e,definition:e?{schema:t}:t}}function De(t,e,n){const s={...C,...e},r={};for(const[i,o]of Object.entries(s)){const{definition:a}=N(o);let c;const u=a.alias,p=i in t,y=u&&u in t;if(p)c=t[i];else if(y)c=t[u];else if(a.value)c=a.value(n);else if(a.default!==void 0)c=typeof a.default=="function"?a.default(n):a.default;else if(a.schema&&S(a.schema)){const f=a.schema["~standard"].validate(void 0);!(f instanceof Promise)&&!f.issues&&(c=f.value)}c!==void 0&&a.decorate&&(c=a.decorate({value:c,props:r})),r[i]=c}return r}function F(t,e){const n={...C,...e};for(const[s,r]of Object.entries(n)){const{isDirectSchema:i,definition:o}=N(r);let a=t[s];if(o.required&&a===void 0)throw new Error(`Prop "${s}" is required but was not provided`);if(o.schema&&S(o.schema))(a!==void 0||i)&&(a=Ct(o.schema,a,s),t[s]=a);else if(a===void 0)continue;o.validate&&o.validate({value:a,props:t})}}function Ie(t,e,n,s){const r={...C,...e},i={};for(const[o,a]of Object.entries(r)){const{definition:c}=N(a),u=t[o];if(c.sendToHost===!1||c.sameDomain&&!s)continue;if(c.trustedDomains){const y=c.trustedDomains;if(!T(y,n))continue}let p=u;c.hostDecorate&&u!==void 0&&(p=c.hostDecorate({value:u,props:t})),i[o]=p}return i}function Rt(t,e){const n=new URLSearchParams,s={...C,...e};for(const[r,i]of Object.entries(s)){const{definition:o}=N(i),a=t[r];if(a===void 0||typeof a=="function"||!o.queryParam)continue;const c=typeof o.queryParam=="string"?o.queryParam:r;let u;typeof o.queryParam=="function"?u=o.queryParam({value:a}):typeof a=="object"?u=JSON.stringify(a):u=String(a),n.set(c,u)}return n}function Dt(t,e){const n=new URLSearchParams,s={...C,...e};for(const[r,i]of Object.entries(s)){const{definition:o}=N(i),a=t[r];if(a===void 0||typeof a=="function"||!o.bodyParam)continue;const c=typeof o.bodyParam=="string"?o.bodyParam:r;let u;typeof o.bodyParam=="function"?u=o.bodyParam({value:a}):typeof a=="object"?u=JSON.stringify(a):u=String(a),n.set(c,u)}return n}const ve=500,It=new Set(["__proto__"]);function xe(t){return!It.has(t)}class ae{constructor(e){this.messenger=e,this.setupCallHandler()}localFunctions=new Map;remoteFunctions=new Map;currentBatchIds=new Set;serialize(e,n){if(this.localFunctions.size>=ve){const r=this.localFunctions.keys().next().value;r&&this.localFunctions.delete(r)}const s=j();return this.localFunctions.set(s,e),this.currentBatchIds.add(s),{__type__:"function",__id__:s,__name__:n||e.name||"anonymous"}}deserialize(e,n,s){const r=`${e.__id__}`,i=this.remoteFunctions.get(r);if(i)return i;if(this.remoteFunctions.size>=ve){const a=this.remoteFunctions.keys().next().value;a&&this.remoteFunctions.delete(a)}const o=async(...a)=>this.messenger.send(n,s,h.CALL,{id:e.__id__,args:a});return Object.defineProperty(o,"name",{value:e.__name__,configurable:!0}),this.remoteFunctions.set(r,o),o}static isFunctionRef(e){return typeof e=="object"&&e!==null&&e.__type__==="function"&&typeof e.__id__=="string"}setupCallHandler(){this.messenger.on(h.CALL,async({id:e,args:n})=>{const s=this.localFunctions.get(e);if(!s)throw new Error(`Function with id "${e}" not found`);return s(...n)})}removeLocal(e){this.localFunctions.delete(e)}startBatch(){this.currentBatchIds.clear()}finishBatch(e=!1){if(e){this.currentBatchIds.clear();return}for(const n of this.localFunctions.keys())this.currentBatchIds.has(n)||this.localFunctions.delete(n);this.currentBatchIds.clear()}clearRemote(){this.remoteFunctions.clear()}get localFunctionCount(){return this.localFunctions.size}get remoteFunctionCount(){return this.remoteFunctions.size}destroy(){this.localFunctions.clear(),this.remoteFunctions.clear(),this.currentBatchIds.clear()}}function ce(t,e,n=new WeakSet){if(typeof t=="function")return e.serialize(t);if(Array.isArray(t)){if(n.has(t))throw new Error("Circular reference detected in props - arrays cannot contain circular references");n.add(t);try{return t.map(s=>ce(s,e,n))}finally{n.delete(t)}}if(typeof t=="object"&&t!==null){if(n.has(t))throw new Error("Circular reference detected in props - objects cannot contain circular references");n.add(t);try{const s={};for(const[r,i]of Object.entries(t))xe(r)&&(s[r]=ce(i,e,n));return s}finally{n.delete(t)}}return t}function ue(t,e,n,s,r=new WeakSet){if(ae.isFunctionRef(t))return e.deserialize(t,n,s);if(Array.isArray(t)){if(r.has(t))throw new Error("Circular reference detected in serialized props");r.add(t);try{return t.map(i=>ue(i,e,n,s,r))}finally{r.delete(t)}}if(typeof t=="object"&&t!==null){if(r.has(t))throw new Error("Circular reference detected in serialized props");r.add(t);try{const i={};for(const[o,a]of Object.entries(t))xe(o)&&(i[o]=ue(a,e,n,s,r));return i}finally{r.delete(t)}}return t}const vt=new Set(["__proto__"]),Te="__forgeframe.dotify_path__:",Z="__forgeframe.dotify_empty_object_path__:",Ue="__forgeframe.dotify_empty_object__";function He(t){return!vt.has(t)}function Ne(t){if(t===null||typeof t!="object"||Array.isArray(t))return!1;const e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}function Fe(t,e=Te){return`${e}${encodeURIComponent(JSON.stringify(t))}`}function xt(t){return encodeURIComponent(JSON.stringify(t))}function Tt(t,e){return`${Fe(t)}=${xt(e)}`}function Ut(t){return`${Fe(t,Z)}=1`}function Ht(t,e,n){Object.defineProperty(t,e,{configurable:!0,enumerable:!0,writable:!0,value:n})}function $e(t,e=[]){const n=Object.entries(t);if(n.length===0&&Ne(t))return e.length===0?Ue:Ut(e);const s=[];for(const[r,i]of n){if(i===void 0)continue;const o=[...e,r];Ne(i)?s.push($e(i,o)):s.push(Tt(o,i))}return s.filter(Boolean).join("&")}function Nt(t){const e={};if(!t||t===Ue)return e;const n=t.split("&");for(const s of n){const r=s.indexOf("=");if(r===-1)continue;const i=s.slice(0,r),o=s.slice(r+1);if(!i||o===void 0)continue;const a=i.startsWith(Z);let c;if(a){if(o!=="1")throw new Error("Invalid empty-object DOTIFY entry");c={}}else try{c=JSON.parse(decodeURIComponent(o))}catch{c=decodeURIComponent(o)}const u=Ft(i);if(u.some(f=>!He(f)))continue;let p=e;for(let f=0;f<u.length-1;f++){const O=u[f],D=p[O];(!Object.prototype.hasOwnProperty.call(p,O)||typeof D!="object"||D===null||Array.isArray(D))&&(p[O]={}),p=p[O]}const y=u[u.length-1];Ht(p,y,c)}return e}function Ft(t){const e=t.startsWith(Z)?Z:Te;if(!t.startsWith(e))throw new Error("Invalid DOTIFY path framing");const n=decodeURIComponent(t.slice(e.length)),s=JSON.parse(n);if(Array.isArray(s)&&s.length>0&&s.every(r=>typeof r=="string"))return s;throw new Error("Invalid DOTIFY path framing")}function $t(t){return typeof t=="object"&&t!==null&&t.__type__==="dotify"&&typeof t.__value__=="string"}function At(t,e,n){const s={...C,...e},r={};for(const[i,o]of Object.entries(t)){if(o===void 0)continue;const a=s[i];r[i]=Lt(o,a,n)}return r}function Lt(t,e,n){if(typeof t=="function")return n.serialize(t);const s=e?.serialization??v.JSON;if(s===v.BASE64&&typeof t=="object"){const r=JSON.stringify(t);return{__type__:"base64",__value__:btoa(encodeURIComponent(r))}}return s===v.DOTIFY&&typeof t=="object"&&t!==null&&!Array.isArray(t)?{__type__:"dotify",__value__:$e(t)}:ce(t,n)}function Ae(t,e,n,s,r,i){const o={...C,...e},a={};for(const[c,u]of Object.entries(t)){if(!He(c))continue;const p=o[c];a[c]=Mt(u,p,n,s,r,i)}return a}function Mt(t,e,n,s,r,i){if(zt(t))try{const o=decodeURIComponent(atob(t.__value__));return JSON.parse(o)}catch{return t}if($t(t))try{return Nt(t.__value__)}catch{return t}return ue(t,s,r,i)}function zt(t){return typeof t=="object"&&t!==null&&t.__type__==="base64"&&typeof t.__value__=="string"}class kt{constructor(e,n,s){this.options=e,this.createPropContext=s,this.inputProps={...n};const r=this.inputProps,i=this.createPropContext(r);this.props=De(r,this.options.props,i)}props;inputProps;pendingPropsUpdate=null;buildNextProps(e){const n={...this.inputProps,...e},s={...this.props,...e},r=this.createPropContext(s),i=De(s,this.options.props,r);return F(i,this.options.props),this.options.validate?.({props:i}),{nextInputProps:n,nextProps:i}}updateProps(e,n){return this.queuePropsUpdate(async()=>{const{nextInputProps:s,nextProps:r}=this.buildNextProps(e),i=n.resolveUrl(r),o=n.resolveUrlOrigin(i);n.assertStableRenderedOrigin(o),this.inputProps=s,this.props=r,n.isRendered()||n.syncTrustedDomainForUrl(i),n.shouldSendPropsToHost()&&await n.sendPropsUpdateToHost(r),n.emitPropsUpdated(r)},n.shouldSendPropsToHost)}syncCurrentPropsToHost(e){return this.queuePropsUpdate(async()=>{e.shouldSendPropsToHost()&&await e.sendPropsUpdateToHost(this.props)},e.shouldSendPropsToHost)}queuePropsUpdate(e,n){if(!this.pendingPropsUpdate){const r=e();return n()&&this.trackPendingUpdate(r),r}const s=this.pendingPropsUpdate.then(e,e);return this.trackPendingUpdate(s),s}trackPendingUpdate(e){const n=e.then(()=>{},()=>{});this.pendingPropsUpdate=n,n.finally(()=>{this.pendingPropsUpdate===n&&(this.pendingPropsUpdate=null)})}}function I(t,e="100%"){return t===void 0?e:typeof t=="number"?`${t}px`:t}function Q(t,e){if(t===void 0)return e;if(typeof t=="number")return t;const n=parseInt(t,10);return isNaN(n)?e:n}function Wt(t){const{name:e,dimensions:n,attributes:s={},style:r={}}=t,i=document.createElement("iframe");return i.name=e,i.setAttribute("frameborder","0"),i.setAttribute("allowtransparency","true"),i.setAttribute("scrolling","auto"),Me(i,n),qt(i,s),Jt(i,r),Kt(i,s),i}function jt(t){try{t.src="about:blank",t.parentNode?.removeChild(t)}catch{}}function Bt(t,e){Me(t,e)}function Vt(t){t.style.display="",t.style.visibility="visible"}function Le(t){t.style.display="none",t.style.visibility="hidden"}function Yt(t){try{t.focus(),t.contentWindow?.focus()}catch{}}function Me(t,e){e.width!==void 0&&(t.style.width=I(e.width)),e.height!==void 0&&(t.style.height=I(e.height))}function Jt(t,e){for(const[n,s]of Object.entries(e)){if(s===void 0)continue;const r=typeof s=="number"?`${s}px`:s;t.style.setProperty(n.replace(/([A-Z])/g,"-$1").toLowerCase(),r)}}function qt(t,e){for(const[n,s]of Object.entries(e))if(s!==void 0){if(typeof s=="boolean"){s&&t.setAttribute(n,"");continue}t.setAttribute(n,s)}}function Kt(t,e){e.sandbox===void 0&&t.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups")}class le extends Error{constructor(e="Popup blocked by browser"){super(e),this.name="PopupOpenError"}}function Xt(t){const{url:e,name:n,dimensions:s}=t,r=Q(s.width,500),i=Q(s.height,500),o=Math.floor(window.screenX+(window.outerWidth-r)/2),a=Math.floor(window.screenY+(window.outerHeight-i)/2),c=[`width=${r}`,`height=${i}`,`left=${o}`,`top=${a}`,"menubar=no","toolbar=no","location=yes","status=no","resizable=yes","scrollbars=yes"].join(","),u=window.open(e,n,c);if(!u||Qt(u))throw new le;return u}function Gt(t){try{t.closed||t.close()}catch{}}function Zt(t){try{t.closed||t.focus()}catch{}}function Qt(t){if(!t)return!0;try{return!!(t.closed||t.innerHeight===0||t.innerWidth===0)}catch{return!0}}function en(t,e,n={}){const{initialInterval:s=100,maxInterval:r=2e3,multiplier:i=1.5}=n;let o=s,a,c=!1;const u=()=>{try{e()}catch(y){console.error("Error in popup close callback:",y)}},p=()=>{if(!c){try{if(t.closed){u();return}}catch{u();return}o=Math.min(o*i,r),a=setTimeout(p,o)}};return a=setTimeout(p,o),()=>{c=!0,clearTimeout(a)}}function tn(t,e){try{const n=Q(e.width,t.outerWidth),s=Q(e.height,t.outerHeight);t.resizeTo(n,s)}catch{}}const ze="forgeframe-spinner-style";function nn(t,e){const n=t.getElementById(ze);if(n){const r=n.getAttribute("nonce");if(!e||r===e)return;n.remove()}const s=t.createElement("style");s.id=ze,e&&s.setAttribute("nonce",e),s.textContent=`
1
+ (function(l,R){typeof exports=="object"&&typeof module<"u"?R(exports):typeof define=="function"&&define.amd?define(["exports"],R):(l=typeof globalThis<"u"?globalThis:l||self,R(l.ForgeFrame={}))})(this,(function(l){"use strict";function R(){return typeof window<"u"&&typeof window.location<"u"}const f={IFRAME:"iframe",POPUP:"popup"},g={RENDER:"render",RENDERED:"rendered",PRERENDER:"prerender",PRERENDERED:"prerendered",DISPLAY:"display",ERROR:"error",CLOSE:"close",DESTROY:"destroy",PROPS:"props",RESIZE:"resize",FOCUS:"focus"},T={JSON:"json",BASE64:"base64",DOTIFY:"dotify"},k={REQUEST:"request",RESPONSE:"response"},d={INIT:"forgeframe_init",PROPS:"forgeframe_props",CLOSE:"forgeframe_close",RESIZE:"forgeframe_resize",FOCUS:"forgeframe_focus",SHOW:"forgeframe_show",HIDE:"forgeframe_hide",ERROR:"forgeframe_error",EXPORT:"forgeframe_export",CALL:"forgeframe_call",CONSUMER_EXPORT:"forgeframe_consumer_export",GET_SIBLINGS:"forgeframe_get_siblings"},W="__forgeframe__",j=(()=>{if("0.0.13".trim().length===0)throw new Error("ForgeFrame VERSION injection is missing. Configure __FORGEFRAME_VERSION__ in build/test tooling.");return"0.0.13"})(),ft=["init","close","resize","show","hide","onError","updateProps","export"],Se=32*1024;function mt(t){const e=bt(t);return`${W}${e}`}function De(t){if(!t||!t.startsWith(W))return null;const e=t.slice(W.length);return Ct(e)}function S(t){return typeof t=="object"&&t!==null}function gt(t){return S(t)}function yt(t){return S(t)&&ft.every(e=>typeof t[e]=="string"&&t[e].length>0)}function wt(t){if(!S(t)||typeof t.tag!="string"||t.tag.length===0||typeof t.url!="string"||t.url.length===0||t.props!==void 0&&!S(t.props)||t.defaultContext!==void 0&&t.defaultContext!==f.IFRAME&&t.defaultContext!==f.POPUP)return!1;if(t.dimensions!==void 0){if(!S(t.dimensions))return!1;const{width:e,height:n}=t.dimensions;if(e!==void 0&&typeof e!="string"&&typeof e!="number"||n!==void 0&&typeof n!="string"&&typeof n!="number")return!1}return!0}function _t(t){return S(t)?Object.values(t).every(e=>wt(e)):!1}function Pt(t){return!(!S(t)||typeof t.uid!="string"||t.uid.length===0||typeof t.tag!="string"||t.tag.length===0||typeof t.version!="string"||t.version.length===0||t.version!==j||t.context!==f.IFRAME&&t.context!==f.POPUP||typeof t.consumerDomain!="string"||t.consumerDomain.length===0||!gt(t.props)||!yt(t.exports)||t.children!==void 0&&!_t(t.children))}function ue(t=window){try{return t.name.startsWith(W)}catch{return!1}}function Et(t,e=window){return De(e.name)?.tag===t}function bt(t){try{const e=JSON.stringify(t),n=btoa(encodeURIComponent(e)),s=n.length;if(s>Se)throw new Error(`Payload size (${Math.round(s/1024)}KB) exceeds maximum allowed size (${Se/1024}KB). Consider reducing the amount of data passed via props.`);return n}catch(e){throw e instanceof Error&&e.message.includes("Payload size")?e:new Error(`Failed to encode payload: ${e}`)}}function Ct(t){try{const e=decodeURIComponent(atob(t)),n=JSON.parse(e);return Pt(n)?n:null}catch{return null}}function Ot(t){return{uid:t.uid,tag:t.tag,version:j,context:t.context,consumerDomain:t.consumerDomain,props:t.props,exports:t.exports,children:t.children}}function Rt(t=window){return De(t.name)}class Ie{listeners=new Map;on(e,n){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(n),()=>this.off(e,n)}once(e,n){const s=r=>(this.off(e,s),n(r));return this.on(e,s)}emit(e,n){const s=this.listeners.get(e);if(s)for(const r of s)try{const i=r(n);i&&typeof i=="object"&&"catch"in i&&typeof i.catch=="function"&&i.catch(o=>{console.error(`Error in async event handler for "${e}":`,o)})}catch(i){console.error(`Error in event handler for "${e}":`,i)}}off(e,n){if(!n){this.listeners.delete(e);return}const s=this.listeners.get(e);s&&(s.delete(n),s.size===0&&this.listeners.delete(e))}removeAllListeners(){this.listeners.clear()}listenerCount(e){return this.listeners.get(e)?.size??0}}function St(){const t=Date.now().toString(36),e=Math.random().toString(36).slice(2,11);return`${t}_${e}`}function B(){return Math.random().toString(36).slice(2,11)}const ve=500,Dt=new Set(["__proto__"]);function xe(t){return!Dt.has(t)}class le{constructor(e){this.messenger=e,this.setupCallHandler()}localFunctions=new Map;remoteFunctions=new Map;currentBatchIds=new Set;serialize(e,n){if(this.localFunctions.size>=ve){const r=this.localFunctions.keys().next().value;r&&this.localFunctions.delete(r)}const s=B();return this.localFunctions.set(s,e),this.currentBatchIds.add(s),{__type__:"function",__id__:s,__name__:n||e.name||"anonymous"}}deserialize(e,n,s){const r=`${e.__id__}`,i=this.remoteFunctions.get(r);if(i)return i;if(this.remoteFunctions.size>=ve){const a=this.remoteFunctions.keys().next().value;a&&this.remoteFunctions.delete(a)}const o=async(...a)=>this.messenger.send(n,s,d.CALL,{id:e.__id__,args:a});return Object.defineProperty(o,"name",{value:e.__name__,configurable:!0}),this.remoteFunctions.set(r,o),o}static isFunctionRef(e){return typeof e=="object"&&e!==null&&e.__type__==="function"&&typeof e.__id__=="string"}setupCallHandler(){this.messenger.on(d.CALL,async({id:e,args:n})=>{const s=this.localFunctions.get(e);if(!s)throw new Error(`Function with id "${e}" not found`);return s(...n)})}removeLocal(e){this.localFunctions.delete(e)}startBatch(){this.currentBatchIds.clear()}finishBatch(e=!1){if(e){this.currentBatchIds.clear();return}for(const n of this.localFunctions.keys())this.currentBatchIds.has(n)||this.localFunctions.delete(n);this.currentBatchIds.clear()}clearRemote(){this.remoteFunctions.clear()}get localFunctionCount(){return this.localFunctions.size}get remoteFunctionCount(){return this.remoteFunctions.size}destroy(){this.localFunctions.clear(),this.remoteFunctions.clear(),this.currentBatchIds.clear()}}function de(t,e,n=new WeakSet){if(typeof t=="function")return e.serialize(t);if(Array.isArray(t)){if(n.has(t))throw new Error("Circular reference detected in props - arrays cannot contain circular references");n.add(t);try{return t.map(s=>de(s,e,n))}finally{n.delete(t)}}if(typeof t=="object"&&t!==null){if(n.has(t))throw new Error("Circular reference detected in props - objects cannot contain circular references");n.add(t);try{const s={};for(const[r,i]of Object.entries(t))xe(r)&&(s[r]=de(i,e,n));return s}finally{n.delete(t)}}return t}function he(t,e,n,s,r=new WeakSet){if(le.isFunctionRef(t))return e.deserialize(t,n,s);if(Array.isArray(t)){if(r.has(t))throw new Error("Circular reference detected in serialized props");r.add(t);try{return t.map(i=>he(i,e,n,s,r))}finally{r.delete(t)}}if(typeof t=="object"&&t!==null){if(r.has(t))throw new Error("Circular reference detected in serialized props");r.add(t);try{const i={};for(const[o,a]of Object.entries(t))xe(o)&&(i[o]=he(a,e,n,s,r));return i}finally{r.delete(t)}}return t}function It(t,e){return t.global||t.sticky?new RegExp(t.source,t.flags.replace(/[gy]/g,"")).test(e):t.test(e)}class P{_optional=!1;_nullable=!1;_default;"~standard"={version:1,vendor:"forgeframe",validate:e=>e===null?this._nullable?{value:null}:{issues:[{message:"Expected a value, got null"}]}:e===void 0?this._default!==void 0?{value:typeof this._default=="function"?this._default():this._default}:this._optional?{value:void 0}:{issues:[{message:"Required"}]}:this._validate(e)};optional(){const e=this._clone();return e._optional=!0,e}nullable(){const e=this._clone();return e._nullable=!0,e}default(e){const n=this._clone();return n._default=e,n}}class V extends P{_minLength;_maxLength;_pattern;_patternMessage;_trim=!1;_validate(e){if(typeof e!="string")return{issues:[{message:`Expected string, got ${typeof e}`}]};const n=this._trim?e.trim():e;return this._minLength!==void 0&&n.length<this._minLength?{issues:[{message:`String must be at least ${this._minLength} characters`}]}:this._maxLength!==void 0&&n.length>this._maxLength?{issues:[{message:`String must be at most ${this._maxLength} characters`}]}:this._pattern&&!It(this._pattern,n)?{issues:[{message:this._patternMessage||`String must match pattern ${this._pattern}`}]}:{value:n}}_clone(){const e=new V;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._minLength=this._minLength,e._maxLength=this._maxLength,e._pattern=this._pattern,e._patternMessage=this._patternMessage,e._trim=this._trim,e}min(e){const n=this._clone();return n._minLength=e,n}max(e){const n=this._clone();return n._maxLength=e,n}length(e){const n=this._clone();return n._minLength=e,n._maxLength=e,n}pattern(e,n){const s=this._clone();return s._pattern=e,s._patternMessage=n,s}email(){return this.pattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/,"Invalid email address")}url(){return this.pattern(/^https?:\/\/.+/,"Invalid URL")}uuid(){return this.pattern(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,"Invalid UUID")}trim(){const e=this._clone();return e._trim=!0,e}nonempty(){const e=this._clone();return e._minLength=1,e}}class Y extends P{_min;_max;_int=!1;_validate(e){return typeof e!="number"||Number.isNaN(e)?{issues:[{message:`Expected number, got ${typeof e}`}]}:this._int&&!Number.isInteger(e)?{issues:[{message:"Expected integer"}]}:this._min!==void 0&&e<this._min?{issues:[{message:`Number must be >= ${this._min}`}]}:this._max!==void 0&&e>this._max?{issues:[{message:`Number must be <= ${this._max}`}]}:{value:e}}_clone(){const e=new Y;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._min=this._min,e._max=this._max,e._int=this._int,e}min(e){const n=this._clone();return n._min=e,n}max(e){const n=this._clone();return n._max=e,n}int(){const e=this._clone();return e._int=!0,e}positive(){const e=this._clone();return e._min=Number.MIN_VALUE,e}nonnegative(){const e=this._clone();return e._min=0,e}negative(){const e=this._clone();return e._max=-Number.MIN_VALUE,e}}class J extends P{_validate(e){return typeof e!="boolean"?{issues:[{message:`Expected boolean, got ${typeof e}`}]}:{value:e}}_clone(){const e=new J;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class q extends P{_validate(e){return typeof e!="function"?{issues:[{message:`Expected function, got ${typeof e}`}]}:{value:e}}_clone(){const e=new q;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class H extends P{_itemSchema;_minLength;_maxLength;_validate(e){if(!Array.isArray(e))return{issues:[{message:`Expected array, got ${typeof e}`}]};if(this._minLength!==void 0&&e.length<this._minLength)return{issues:[{message:`Array must have at least ${this._minLength} items`}]};if(this._maxLength!==void 0&&e.length>this._maxLength)return{issues:[{message:`Array must have at most ${this._maxLength} items`}]};if(this._itemSchema){const n=[];for(let s=0;s<e.length;s++){const r=this._itemSchema["~standard"].validate(e[s]);if(r instanceof Promise)throw new Error("Async schema validation is not supported. Use synchronous schemas.");if(r.issues)return{issues:r.issues.map(i=>({...i,path:[s,...i.path||[]]}))};n.push(r.value)}return{value:n}}return{value:e}}_clone(){const e=new H;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._itemSchema=this._itemSchema,e._minLength=this._minLength,e._maxLength=this._maxLength,e}of(e){const n=new H;return n._optional=this._optional,n._nullable=this._nullable,n._itemSchema=e,n._minLength=this._minLength,n._maxLength=this._maxLength,n}min(e){const n=this._clone();return n._minLength=e,n}max(e){const n=this._clone();return n._maxLength=e,n}nonempty(){return this.min(1)}}class U extends P{_shape;_strict=!1;_validate(e){if(typeof e!="object"||e===null||Array.isArray(e))return{issues:[{message:`Expected object, got ${Array.isArray(e)?"array":typeof e}`}]};const n=e,s={};if(this._shape){if(this._strict){const r=new Set(Object.keys(this._shape));for(const i of Object.keys(n))if(!r.has(i))return{issues:[{message:`Unknown key: ${i}`,path:[i]}]}}for(const[r,i]of Object.entries(this._shape)){const o=i["~standard"].validate(n[r]);if(o instanceof Promise)throw new Error("Async schema validation is not supported. Use synchronous schemas.");if(o.issues)return{issues:o.issues.map(a=>({...a,path:[r,...a.path||[]]}))};s[r]=o.value}if(!this._strict)for(const r of Object.keys(n))r in this._shape||(s[r]=n[r]);return{value:s}}return{value:e}}_clone(){const e=new U;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._shape=this._shape,e._strict=this._strict,e}shape(e){const n=new U;return n._optional=this._optional,n._nullable=this._nullable,n._shape=e,n._strict=this._strict,n}strict(){const e=this._clone();return e._strict=!0,e}}class K extends P{_value;constructor(e){super(),this._value=e}_validate(e){return e!==this._value?{issues:[{message:`Expected ${JSON.stringify(this._value)}, got ${JSON.stringify(e)}`}]}:{value:e}}_clone(){const e=new K(this._value);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class X extends P{_values;_valueSet;constructor(e){super(),this._values=e,this._valueSet=new Set(e)}_validate(e){return this._valueSet.has(e)?{value:e}:{issues:[{message:`Expected one of [${this._values.map(n=>JSON.stringify(n)).join(", ")}], got ${JSON.stringify(e)}`}]}}_clone(){const e=new X(this._values);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class G extends P{constructor(){super(),this._nullable=!0}_validate(e){return{value:e}}_clone(){const e=new G;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}const m={string:()=>new V,number:()=>new Y,boolean:()=>new J,function:()=>new q,array:()=>new H,object:()=>new U,literal:t=>new K(t),enum:t=>new X(t),any:()=>new G},D={uid:{schema:m.string().optional(),sendToHost:!0},tag:{schema:m.string().optional(),sendToHost:!0},dimensions:{schema:m.object().default(()=>({width:"100%",height:"100%"})),sendToHost:!1},timeout:{schema:m.number().default(1e4),sendToHost:!1},cspNonce:{schema:m.string().optional(),sendToHost:!0},onDisplay:{schema:m.function().optional(),sendToHost:!1},onRendered:{schema:m.function().optional(),sendToHost:!1},onRender:{schema:m.function().optional(),sendToHost:!1},onPrerendered:{schema:m.function().optional(),sendToHost:!1},onPrerender:{schema:m.function().optional(),sendToHost:!1},onClose:{schema:m.function().optional(),sendToHost:!1},onDestroy:{schema:m.function().optional(),sendToHost:!1},onResize:{schema:m.function().optional(),sendToHost:!1},onFocus:{schema:m.function().optional(),sendToHost:!1},onError:{schema:m.function().optional(),sendToHost:!1},onProps:{schema:m.function().optional(),sendToHost:!1}},vt=new Set(["__proto__"]),Te="__forgeframe.dotify_path__:",Z="__forgeframe.dotify_empty_object_path__:",He="__forgeframe.dotify_empty_object__";function Ue(t){return!vt.has(t)}function Fe(t){if(t===null||typeof t!="object"||Array.isArray(t))return!1;const e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}function Ne(t,e=Te){return`${e}${encodeURIComponent(JSON.stringify(t))}`}function xt(t){return encodeURIComponent(JSON.stringify(t))}function Tt(t,e){return`${Ne(t)}=${xt(e)}`}function Ht(t){return`${Ne(t,Z)}=1`}function Ut(t,e,n){Object.defineProperty(t,e,{configurable:!0,enumerable:!0,writable:!0,value:n})}function Ae(t,e=[]){const n=Object.entries(t);if(n.length===0&&Fe(t))return e.length===0?He:Ht(e);const s=[];for(const[r,i]of n){if(i===void 0)continue;const o=[...e,r];Fe(i)?s.push(Ae(i,o)):s.push(Tt(o,i))}return s.filter(Boolean).join("&")}function Ft(t){const e={};if(!t||t===He)return e;const n=t.split("&");for(const s of n){const r=s.indexOf("=");if(r===-1)continue;const i=s.slice(0,r),o=s.slice(r+1);if(!i||o===void 0)continue;const a=i.startsWith(Z);let c;if(a){if(o!=="1")throw new Error("Invalid empty-object DOTIFY entry");c={}}else try{c=JSON.parse(decodeURIComponent(o))}catch{c=decodeURIComponent(o)}const u=Nt(i);if(u.some(p=>!Ue(p)))continue;let h=e;for(let p=0;p<u.length-1;p++){const O=u[p],v=h[O];(!Object.prototype.hasOwnProperty.call(h,O)||typeof v!="object"||v===null||Array.isArray(v))&&(h[O]={}),h=h[O]}const y=u[u.length-1];Ut(h,y,c)}return e}function Nt(t){const e=t.startsWith(Z)?Z:Te;if(!t.startsWith(e))throw new Error("Invalid DOTIFY path framing");const n=decodeURIComponent(t.slice(e.length)),s=JSON.parse(n);if(Array.isArray(s)&&s.length>0&&s.every(r=>typeof r=="string"))return s;throw new Error("Invalid DOTIFY path framing")}function At(t){return typeof t=="object"&&t!==null&&t.__type__==="dotify"&&typeof t.__value__=="string"}function Mt(t,e,n){const s={...D,...e},r={};for(const[i,o]of Object.entries(t)){if(o===void 0)continue;const a=s[i];r[i]=$t(o,a,n)}return r}function $t(t,e,n){if(typeof t=="function")return n.serialize(t);const s=e?.serialization??T.JSON;if(s===T.BASE64&&typeof t=="object"){const r=JSON.stringify(t);return{__type__:"base64",__value__:btoa(encodeURIComponent(r))}}return s===T.DOTIFY&&typeof t=="object"&&t!==null&&!Array.isArray(t)?{__type__:"dotify",__value__:Ae(t)}:de(t,n)}function Lt(t,e,n,s,r,i){const o={...D,...e},a={};for(const[c,u]of Object.entries(t)){if(!Ue(c))continue;const h=o[c];a[c]=zt(u,h,n,s,r,i)}return a}function zt(t,e,n,s,r,i){if(kt(t))try{const o=decodeURIComponent(atob(t.__value__));return JSON.parse(o)}catch{return t}if(At(t))try{return Ft(t.__value__)}catch{return t}return he(t,s,r,i)}function kt(t){return typeof t=="object"&&t!==null&&t.__type__==="base64"&&typeof t.__value__=="string"}const F=new Map,Wt=200;function jt(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Me(t){if(!t.includes("*"))return null;const e=F.get(t);if(e)return e;const n=t.split("*").map(r=>jt(r)).join(".*"),s=new RegExp(`^${n}$`);if(F.size>=Wt){const r=F.keys().next().value;r&&F.delete(r)}return F.set(t,s),s}function pe(t,e){return t.global||t.sticky?new RegExp(t.source,t.flags.replace(/[gy]/g,"")).test(e):t.test(e)}function Q(t=window){try{return t.location.origin}catch{return""}}function $e(t,e=window){try{return t.location.origin===e.location.origin}catch{return!1}}function ee(t,e){if(typeof t=="string"){if(t==="*")return!0;const n=Me(t);return n?pe(n,e):t===e}return t instanceof RegExp?pe(t,e):Array.isArray(t)?t.some(n=>ee(n,e)):!1}function fe(t){if(!t)return!0;try{return t.closed}catch{return!0}}function Bt(t=window){try{return t.opener}catch{return null}}function Vt(t=window){try{const e=t.parent;return e&&e!==t?e:null}catch{return null}}function Yt(t=window){try{return t.parent!==t}catch{return!0}}function Jt(t=window){try{return t.opener!==null&&t.opener!==void 0}catch{return!1}}function I(t){return typeof t=="object"&&t!==null&&"~standard"in t&&typeof t["~standard"]=="object"&&t["~standard"]!==null&&t["~standard"].version===1&&typeof t["~standard"].vendor=="string"&&typeof t["~standard"].validate=="function"}function qt(t,e,n){const s=t["~standard"].validate(e);if(s instanceof Promise)throw new Error(`Prop "${n}" uses an async schema. ForgeFrame only supports synchronous schema validation. Please use a synchronous schema or remove async operations (like database lookups) from your schema definition.`);if(s.issues){const r=s.issues.map(i=>`${Kt(i.path,n)}: ${i.message}`);throw new Error(`Validation failed: ${r.join("; ")}`)}return s.value}function Kt(t,e){if(!t||t.length===0)return e;const n=t.map(s=>{if(typeof s=="object"&&s!==null){if("key"in s&&s.key!==void 0)return String(s.key);if("index"in s&&typeof s.index=="number")return String(s.index)}return String(s)});return`${e}.${n.join(".")}`}function N(t){const e=I(t);return{isDirectSchema:e,definition:e?{schema:t}:t}}function Le(t,e,n){const s={...D,...e},r={};for(const[i,o]of Object.entries(s)){const{definition:a}=N(o);let c;const u=a.alias,h=i in t,y=u&&u in t;if(h)c=t[i];else if(y)c=t[u];else if(a.value)c=a.value(n);else if(a.default!==void 0)c=typeof a.default=="function"?a.default(n):a.default;else if(a.schema&&I(a.schema)){const p=a.schema["~standard"].validate(void 0);!(p instanceof Promise)&&!p.issues&&(c=p.value)}c!==void 0&&a.decorate&&(c=a.decorate({value:c,props:r})),r[i]=c}return r}function A(t,e){const n={...D,...e};for(const[s,r]of Object.entries(n)){const{isDirectSchema:i,definition:o}=N(r);let a=t[s];if(o.required&&a===void 0)throw new Error(`Prop "${s}" is required but was not provided`);if(o.schema&&I(o.schema))(a!==void 0||i)&&(a=qt(o.schema,a,s),t[s]=a);else if(a===void 0)continue;o.validate&&o.validate({value:a,props:t})}}function ze(t,e,n,s){const r={...D,...e},i={};for(const[o,a]of Object.entries(r)){const{definition:c}=N(a),u=t[o];if(c.sendToHost===!1||c.sameDomain&&!s)continue;if(c.trustedDomains){const y=c.trustedDomains;if(!ee(y,n))continue}let h=u;c.hostDecorate&&u!==void 0&&(h=c.hostDecorate({value:u,props:t})),i[o]=h}return i}function Xt(t,e){const n=new URLSearchParams,s={...D,...e};for(const[r,i]of Object.entries(s)){const{definition:o}=N(i),a=t[r];if(a===void 0||typeof a=="function"||!o.queryParam)continue;const c=typeof o.queryParam=="string"?o.queryParam:r;let u;typeof o.queryParam=="function"?u=o.queryParam({value:a}):typeof a=="object"?u=JSON.stringify(a):u=String(a),n.set(c,u)}return n}function Gt(t,e){const n=new URLSearchParams,s={...D,...e};for(const[r,i]of Object.entries(s)){const{definition:o}=N(i),a=t[r];if(a===void 0||typeof a=="function"||!o.bodyParam)continue;const c=typeof o.bodyParam=="string"?o.bodyParam:r;let u;typeof o.bodyParam=="function"?u=o.bodyParam({value:a}):typeof a=="object"?u=JSON.stringify(a):u=String(a),n.set(c,u)}return n}class Zt{tasks=[];cleaned=!1;register(e){if(this.cleaned){Promise.resolve().then(()=>e()).catch(n=>{console.error("Error in cleanup task:",n)});return}this.tasks.push(e)}async cleanup(){if(this.cleaned)return;this.cleaned=!0;const e=this.tasks.reverse();this.tasks=[];for(const n of e)try{await n()}catch(s){console.error("Error in cleanup task:",s)}}isCleaned(){return this.cleaned}reset(){this.tasks=[],this.cleaned=!1}}const ke=100,C=new Map;function Qt(){const t=[];for(const[e,n]of C.entries())fe(n)&&t.push(e);for(const e of t)C.delete(e)}function en(t,e){if(C.size>=ke&&Qt(),C.size>=ke){const n=C.keys().next().value;n&&C.delete(n)}C.set(t,e)}function tn(t){C.delete(t)}function w(t,e,...n){const s=t[e];if(typeof s=="function")try{const r=s(...n);r&&typeof r=="object"&&"catch"in r&&typeof r.catch=="function"&&r.catch(i=>{console.error(`Error in async ${e} callback:`,i)})}catch(r){console.error(`Error in ${e} callback:`,r)}}function te(t,e,n){t.emit(g.ERROR,n),w(e,"onError",n)}function nn(t,e){if(!t.children)return;const n=t.children({props:e}),s={};for(const[r,i]of Object.entries(n)){const o=Ln(i);if(!o)throw new Error(`Nested component "${r}" is missing component metadata`);if(typeof o.url!="string")throw new Error(`Nested component "${r}" must use a static string URL. Function URLs are not supported in children.`);s[r]={tag:o.tag,url:o.url,props:o.props,dimensions:typeof o.dimensions=="function"?void 0:o.dimensions,defaultContext:o.defaultContext}}return Object.keys(s).length>0?s:void 0}class sn{constructor(e,n,s){this.options=e,this.createPropContext=s,this.inputProps={...n};const r=this.inputProps,i=this.createPropContext(r);this.props=Le(r,this.options.props,i)}props;inputProps;pendingPropsUpdate=null;buildNextProps(e){const n={...this.inputProps,...e},s={...this.props,...e},r=this.createPropContext(s),i=Le(s,this.options.props,r);return A(i,this.options.props),this.options.validate?.({props:i}),{nextInputProps:n,nextProps:i}}updateProps(e,n){return this.queuePropsUpdate(async()=>{const{nextInputProps:s,nextProps:r}=this.buildNextProps(e),i=n.resolveUrl(r),o=n.resolveUrlOrigin(i);n.assertStableRenderedOrigin(o),this.inputProps=s,this.props=r,n.isRendered()||n.syncTrustedDomainForUrl(i),n.shouldSendPropsToHost()&&await n.sendPropsUpdateToHost(r),n.emitPropsUpdated(r)},n.shouldSendPropsToHost)}syncCurrentPropsToHost(e){return this.queuePropsUpdate(async()=>{e.shouldSendPropsToHost()&&await e.sendPropsUpdateToHost(this.props)},e.shouldSendPropsToHost)}queuePropsUpdate(e,n){if(!this.pendingPropsUpdate){const r=e();return n()&&this.trackPendingUpdate(r),r}const s=this.pendingPropsUpdate.then(e,e);return this.trackPendingUpdate(s),s}trackPendingUpdate(e){const n=e.then(()=>{},()=>{});this.pendingPropsUpdate=n,n.finally(()=>{this.pendingPropsUpdate===n&&(this.pendingPropsUpdate=null)})}}function x(t,e="100%"){return t===void 0?e:typeof t=="number"?`${t}px`:t}function ne(t,e){if(t===void 0)return e;if(typeof t=="number")return t;const n=parseInt(t,10);return isNaN(n)?e:n}function rn(t){const{name:e,dimensions:n,attributes:s={},style:r={}}=t,i=document.createElement("iframe");return i.name=e,i.setAttribute("frameborder","0"),i.setAttribute("allowtransparency","true"),i.setAttribute("scrolling","auto"),je(i,n),dn(i,s),ln(i,r),hn(i,s),i}function on(t){try{t.src="about:blank",t.parentNode?.removeChild(t)}catch{}}function an(t,e){je(t,e)}function cn(t){t.style.display="",t.style.visibility="visible"}function We(t){t.style.display="none",t.style.visibility="hidden"}function un(t){try{t.focus(),t.contentWindow?.focus()}catch{}}function je(t,e){e.width!==void 0&&(t.style.width=x(e.width)),e.height!==void 0&&(t.style.height=x(e.height))}function ln(t,e){for(const[n,s]of Object.entries(e)){if(s===void 0)continue;const r=typeof s=="number"?`${s}px`:s;t.style.setProperty(n.replace(/([A-Z])/g,"-$1").toLowerCase(),r)}}function dn(t,e){for(const[n,s]of Object.entries(e))if(s!==void 0){if(typeof s=="boolean"){s&&t.setAttribute(n,"");continue}t.setAttribute(n,s)}}function hn(t,e){e.sandbox===void 0&&t.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups")}class me extends Error{constructor(e="Popup blocked by browser"){super(e),this.name="PopupOpenError"}}function pn(t){const{url:e,name:n,dimensions:s}=t,r=ne(s.width,500),i=ne(s.height,500),o=Math.floor(window.screenX+(window.outerWidth-r)/2),a=Math.floor(window.screenY+(window.outerHeight-i)/2),c=[`width=${r}`,`height=${i}`,`left=${o}`,`top=${a}`,"menubar=no","toolbar=no","location=yes","status=no","resizable=yes","scrollbars=yes"].join(","),u=window.open(e,n,c);if(!u||gn(u))throw new me;return u}function fn(t){try{t.closed||t.close()}catch{}}function mn(t){try{t.closed||t.focus()}catch{}}function gn(t){if(!t)return!0;try{return!!(t.closed||t.innerHeight===0||t.innerWidth===0)}catch{return!0}}function yn(t,e,n={}){const{initialInterval:s=100,maxInterval:r=2e3,multiplier:i=1.5}=n;let o=s,a,c=!1;const u=()=>{try{e()}catch(y){console.error("Error in popup close callback:",y)}},h=()=>{if(!c){try{if(t.closed){u();return}}catch{u();return}o=Math.min(o*i,r),a=setTimeout(h,o)}};return a=setTimeout(h,o),()=>{c=!0,clearTimeout(a)}}function wn(t,e){try{const n=ne(e.width,t.outerWidth),s=ne(e.height,t.outerHeight);t.resizeTo(n,s)}catch{}}const Be="forgeframe-spinner-style";function _n(t,e){const n=t.getElementById(Be);if(n){const r=n.getAttribute("nonce");if(!e||r===e)return;n.remove()}const s=t.createElement("style");s.id=Be,e&&s.setAttribute("nonce",e),s.textContent=`
2
2
  @keyframes forgeframe-spin {
3
3
  to { transform: rotate(360deg); }
4
4
  }
5
- `,(t.head??t.documentElement).appendChild(s)}function sn(t){const{doc:e,dimensions:n,uid:s,tag:r}=t,i=e.createElement("div");return i.id=`forgeframe-container-${s}`,i.setAttribute("data-forgeframe-tag",r),Object.assign(i.style,{display:"inline-block",position:"relative",width:I(n.width),height:I(n.height),overflow:"hidden"}),i}function rn(t){const{doc:e,dimensions:n,cspNonce:s}=t;nn(e,s);const r=e.createElement("div");Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",width:I(n.width),height:I(n.height),backgroundColor:"#f5f5f5",position:"absolute",top:"0",left:"0",zIndex:"100"});const i=e.createElement("div");return Object.assign(i.style,{width:"40px",height:"40px",border:"3px solid #e0e0e0",borderTopColor:"#3498db",borderRadius:"50%",animation:"forgeframe-spin 1s linear infinite"}),r.appendChild(i),r}function on(t,e=200){return new Promise(n=>{t.style.opacity="0",t.style.transition=`opacity ${e}ms ease-in`,t.offsetHeight,t.style.opacity="1",setTimeout(n,e)})}function an(t,e=200){return new Promise(n=>{t.style.transition=`opacity ${e}ms ease-out`,t.style.opacity="0",setTimeout(n,e)})}async function cn(t,e,n){e&&(await an(e,150),e.remove()),n.style.display="",n.style.visibility="visible",n.style.opacity="0",await on(n,150)}class un{constructor(e,n,s,r,i){this.options=e,this.uid=n,this.getProps=s,this.resolveDimensions=r,this.callbacks=i,this.context=this.options.defaultContext}context;iframe=null;container=null;prerenderElement=null;ownedContainer=null;resolveContainer(e){if(!e)throw new Error("Container is required for rendering");if(typeof e=="string"){const n=document.querySelector(e);if(!n)throw new Error(`Container "${e}" not found`);return n}return e}async prerender(e,n){if(!this.container)return;const s=this.container;this.ownedContainer=null;const r=this.getProps(),i=this.options.prerenderTemplate??rn,o=this.options.containerTemplate??sn,a=this.resolveDimensions(),c=r.cspNonce;if(this.context===d.IFRAME){const f=n();this.iframe=e(f),Le(this.iframe)}const u={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:a,props:r,doc:document,container:s,frame:this.iframe,prerenderFrame:null,close:()=>this.callbacks.close(),focus:()=>this.callbacks.focus(),cspNonce:c};this.prerenderElement=i(u);const p={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:a,props:r,doc:document,container:s,frame:this.iframe,prerenderFrame:this.prerenderElement,close:()=>this.callbacks.close(),focus:()=>this.callbacks.focus(),cspNonce:c},y=o(p);if(y){if(y!==s){const f=!y.parentNode;s.appendChild(y),f&&(this.ownedContainer=y)}this.container=y}this.prerenderElement&&!this.prerenderElement.parentNode&&this.container.appendChild(this.prerenderElement),this.iframe&&!this.iframe.parentNode&&this.container.appendChild(this.iframe)}createIframeElement(e){const n=this.resolveDimensions(),s=this.getProps(),r=typeof this.options.attributes=="function"?this.options.attributes(s):this.options.attributes??{},i=typeof this.options.style=="function"?this.options.style(s):this.options.style??{};return Wt({name:e,dimensions:n,attributes:r,style:i})}open(e){const n=e.buildUrl(e.baseUrl),s=e.buildBodyParams(),r=s.toString().length>0;if(this.context===d.IFRAME){if(!this.iframe)throw new Error("Iframe not created during prerender");return r?e.submitBodyForm(this.iframe.name,n,s):this.iframe.src=n,this.iframe.contentWindow}const i=e.buildWindowName(),o=Xt({url:r?"about:blank":n,name:i,dimensions:this.resolveDimensions()});r&&e.submitBodyForm(i,n,s);const a=en(o,()=>{e.onPopupClose()});return e.registerCleanup(a),o}async swapPrerenderContentIfNeeded(){this.context===d.IFRAME&&this.iframe&&this.container&&(await cn(this.container,this.prerenderElement,this.iframe),this.prerenderElement=null)}submitBodyForm(e,n,s){const r=this.container?.ownerDocument??document,i=r.body??r.documentElement;if(!i)throw new Error("Document root is unavailable for bodyParam form submission");const o=r.createElement("form");o.method="POST",o.action=n,o.target=e,o.style.display="none";for(const[a,c]of s.entries()){const u=r.createElement("input");u.type="hidden",u.name=a,u.value=c,o.appendChild(u)}i.appendChild(o);try{o.submit()}finally{o.remove()}}focus(e){this.context===d.IFRAME&&this.iframe?Yt(this.iframe):this.context===d.POPUP&&e&&Zt(e)}resize(e,n){this.context===d.IFRAME&&this.iframe?Bt(this.iframe,e):this.context===d.POPUP&&n&&tn(n,e)}show(){this.context===d.IFRAME&&this.iframe&&Vt(this.iframe)}hide(){this.context===d.IFRAME&&this.iframe&&Le(this.iframe)}destroy(e){this.iframe&&(jt(this.iframe),this.iframe=null),this.context===d.POPUP&&e&&Gt(e),this.prerenderElement&&(this.prerenderElement.remove(),this.prerenderElement=null),this.ownedContainer&&(this.ownedContainer.remove(),this.ownedContainer=null),this.container=null}}const he="forgeframe:";function de(t){return he+JSON.stringify(t)}function ln(t){if(typeof t!="string"||!t.startsWith(he))return null;try{const e=t.slice(he.length),n=JSON.parse(e);return!n.id||!n.type||!n.name||!n.source?null:n}catch{return null}}function ke(t,e,n,s){return{id:t,type:z.REQUEST,name:e,data:n,source:s}}function hn(t,e,n,s){return{id:t,type:z.RESPONSE,name:"response",data:e,source:n,error:s?{message:s.message,stack:s.stack}:void 0}}function dn(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function fn(t){if(!t.includes("*"))return null;const e=t.split("*").map(n=>dn(n)).join(".*");return new RegExp(`^${e}$`)}function pn(t,e){return t.global||t.sticky?new RegExp(t.source,t.flags.replace(/[gy]/g,"")).test(e):t.test(e)}function mn(t,e,n){return e!==t.targetWin?!1:t.expectedOrigin==="*"?!0:n===t.expectedOrigin}function gn(t,e){if(t==="*")return"*";if(t==="/")return e;try{return new URL(t,e).origin}catch{return t}}class We{constructor(e,n=window,s=window.location.origin,r){this.uid=e,this.win=n,this.domain=s,this.allowedOrigins.add(s),r&&this.addTrustedDomain(r),this.setupListener()}pending=new Map;handlers=new Map;listener=null;destroyed=!1;allowedOrigins=new Set;allowedOriginPatterns=[];wildcardPatternRegistry=new Map;sourceUidRegistry=new WeakMap;addTrustedDomain(e){if(Array.isArray(e))for(const n of e)this.addTrustedDomain(n);else if(e instanceof RegExp)this.allowedOriginPatterns.push(e);else{const n=fn(e);n?this.wildcardPatternRegistry.has(e)||(this.wildcardPatternRegistry.set(e,n),this.allowedOriginPatterns.push(n)):this.allowedOrigins.add(e)}}removeTrustedDomain(e){if(Array.isArray(e))for(const n of e)this.removeTrustedDomain(n);else if(e instanceof RegExp)this.allowedOriginPatterns=this.allowedOriginPatterns.filter(n=>n!==e);else{const n=this.wildcardPatternRegistry.get(e);n&&(this.allowedOriginPatterns=this.allowedOriginPatterns.filter(s=>s!==n),this.wildcardPatternRegistry.delete(e)),this.allowedOrigins.delete(e)}}isOriginTrusted(e){if(this.allowedOrigins.has(e))return!0;for(const n of this.allowedOriginPatterns)if(pn(n,e))return!0;return!1}resolveVerifiedSource(e,n,s){const r=e,i=this.sourceUidRegistry.get(r);if(i)return{uid:i,domain:n,window:e};const o=s&&typeof s.uid=="string"&&s.uid.length>0?s.uid:j();return this.sourceUidRegistry.set(r,o),{uid:o,domain:n,window:e}}async send(e,n,s,r,i=1e4){if(this.destroyed)throw new Error("Messenger has been destroyed");const o=j(),a=ke(o,s,r,{uid:this.uid,domain:this.domain}),c=Ce(),u=setTimeout(()=>{this.pending.delete(o),c.reject(new Error(`Message "${s}" timed out after ${i}ms`))},i);this.pending.set(o,{deferred:c,timeout:u,targetWin:e,expectedOrigin:gn(n,this.domain)});try{e.postMessage(de(a),n)}catch(p){throw this.pending.delete(o),clearTimeout(u),p}return c.promise}post(e,n,s,r){if(this.destroyed)throw new Error("Messenger has been destroyed");const i=j(),o=ke(i,s,r,{uid:this.uid,domain:this.domain});e.postMessage(de(o),n)}on(e,n){return this.handlers.set(e,n),()=>this.handlers.delete(e)}setupListener(){this.listener=e=>{if(e.source===this.win||!this.isOriginTrusted(e.origin))return;const n=ln(e.data);if(!n)return;const s=e.source;!s||typeof s.postMessage!="function"||this.handleMessage(n,s,e.origin)},this.win.addEventListener("message",this.listener)}async handleMessage(e,n,s){if(e.type===z.RESPONSE){const r=this.pending.get(e.id);if(r){if(!mn(r,n,s))return;if(this.pending.delete(e.id),clearTimeout(r.timeout),e.error){const i=new Error(e.error.message);i.stack=e.error.stack,r.deferred.reject(i)}else r.deferred.resolve(e.data)}return}if(e.type===z.REQUEST){const r=this.handlers.get(e.name);if(!r)return;let i,o;try{const c=this.resolveVerifiedSource(n,s,e.source);i=await r(e.data,c)}catch(c){o=c instanceof Error?c:new Error(String(c))}const a=hn(e.id,i,{uid:this.uid,domain:this.domain},o);try{n.postMessage(de(a),s)}catch{}}}destroy(){if(!this.destroyed){this.destroyed=!0,this.listener&&(this.win.removeEventListener("message",this.listener),this.listener=null);for(const e of this.pending.values())clearTimeout(e.timeout),e.deferred.reject(new Error("Messenger destroyed"));this.pending.clear(),this.handlers.clear()}}isDestroyed(){return this.destroyed}}const yn=["init","close","resize","show","hide","onError","updateProps","export"],je=32*1024;function wn(t){const e=Sn(t);return`${k}${e}`}function Be(t){if(!t||!t.startsWith(k))return null;const e=t.slice(k.length);return Rn(e)}function R(t){return typeof t=="object"&&t!==null}function _n(t){return R(t)}function Pn(t){return R(t)&&yn.every(e=>typeof t[e]=="string"&&t[e].length>0)}function En(t){if(!R(t)||typeof t.tag!="string"||t.tag.length===0||typeof t.url!="string"||t.url.length===0||t.props!==void 0&&!R(t.props)||t.defaultContext!==void 0&&t.defaultContext!==d.IFRAME&&t.defaultContext!==d.POPUP)return!1;if(t.dimensions!==void 0){if(!R(t.dimensions))return!1;const{width:e,height:n}=t.dimensions;if(e!==void 0&&typeof e!="string"&&typeof e!="number"||n!==void 0&&typeof n!="string"&&typeof n!="number")return!1}return!0}function bn(t){return R(t)?Object.values(t).every(e=>En(e)):!1}function On(t){return!(!R(t)||typeof t.uid!="string"||t.uid.length===0||typeof t.tag!="string"||t.tag.length===0||typeof t.version!="string"||t.version.length===0||t.version!==W||t.context!==d.IFRAME&&t.context!==d.POPUP||typeof t.consumerDomain!="string"||t.consumerDomain.length===0||!_n(t.props)||!Pn(t.exports)||t.children!==void 0&&!bn(t.children))}function fe(t=window){try{return t.name.startsWith(k)}catch{return!1}}function Cn(t,e=window){return Be(e.name)?.tag===t}function Sn(t){try{const e=JSON.stringify(t),n=btoa(encodeURIComponent(e)),s=n.length;if(s>je)throw new Error(`Payload size (${Math.round(s/1024)}KB) exceeds maximum allowed size (${je/1024}KB). Consider reducing the amount of data passed via props.`);return n}catch(e){throw e instanceof Error&&e.message.includes("Payload size")?e:new Error(`Failed to encode payload: ${e}`)}}function Rn(t){try{const e=decodeURIComponent(atob(t)),n=JSON.parse(e);return On(n)?n:null}catch{return null}}function Dn(t){return{uid:t.uid,tag:t.tag,version:W,context:t.context,consumerDomain:t.consumerDomain,props:t.props,exports:t.exports,children:t.children}}function In(t=window){return Be(t.name)}class vn{constructor(e,n,s,r){this.uid=e,this.options=n,this.resolveUrl=s,this.resolveUrlOrigin=r;const i=this.buildTrustedDomains();this.messenger=new We(this.uid,window,B(),i),this.bridge=new ae(this.messenger)}messenger;bridge;hostWindow=null;openedHostDomain=null;dynamicUrlTrustedOrigin=null;initPromise=null;hostInitialized=!1;buildTrustedDomains(){const e=[],n=this.resolveUrlOrigin(this.resolveUrl());if(n&&(e.push(n),this.dynamicUrlTrustedOrigin=n),this.options.domain&&(typeof this.options.domain=="string"?e.push(this.options.domain):Array.isArray(this.options.domain)?e.push(...this.options.domain):this.options.domain instanceof RegExp&&e.push(this.options.domain)),e.length!==0)return e.length===1?e[0]:e}isExplicitDomainTrust(e){return this.options.domain?T(this.options.domain,e):!1}syncTrustedDomainForUrl(e){const n=this.resolveUrlOrigin(e);if(!n)return;const s=this.dynamicUrlTrustedOrigin;s&&s!==n&&!this.isExplicitDomainTrust(s)&&this.messenger.removeTrustedDomain(s),this.messenger.addTrustedDomain(n),this.dynamicUrlTrustedOrigin=n}getHostDomain(){return this.openedHostDomain?this.openedHostDomain:this.resolveUrlOrigin(this.resolveUrl())??"*"}isHostConnected(){return!!(this.hostWindow&&!oe(this.hostWindow))}serializePropsForHost(e,n,s){this.bridge.startBatch();const r=s?.finishBatch??!0;try{const i=At(e,n,this.bridge);return r&&this.bridge.finishBatch(),i}catch(i){throw this.bridge.finishBatch(!0),i}}async sendPropsUpdateToHost(e,n){if(!this.hostWindow||oe(this.hostWindow))return;const s=this.getHostDomain(),r=Ie(e,n,s,Se(this.hostWindow)),i=this.serializePropsForHost(r,n,{finishBatch:!1});try{await this.messenger.send(this.hostWindow,s,h.PROPS,i),this.bridge.finishBatch()}catch(o){throw this.bridge.finishBatch(!0),o}}buildWindowName(e){const n=e.hostDomain??this.getHostDomain(),s=Ie(e.props,e.propDefinitions,n,!1),r=this.serializePropsForHost(s,e.propDefinitions),i=Dn({uid:this.uid,tag:e.tag,context:e.context,consumerDomain:B(),props:r,exports:e.exports,children:e.children});return wn(i)}async waitForHost(e,n,s){if(this.hostInitialized)return;const r=Ce();this.initPromise=r;try{await ht(r.promise,e,`Host component "${n}" (uid: ${this.uid}) did not initialize within ${e}ms. Check that the host page loads correctly and calls the initialization code.`)}catch(i){throw s(i),i}finally{this.initPromise===r&&(this.initPromise=null)}}setupMessageHandlers(e){this.messenger.on(h.INIT,(n,s)=>this.isHostControlSource(s)?(this.hostInitialized=!0,this.initPromise&&this.initPromise.resolve(),e.onInit&&queueMicrotask(()=>{Promise.resolve(e.onInit?.()).catch(r=>{e.onError(r)})}),{success:!0}):{success:!1}),this.messenger.on(h.CLOSE,async(n,s)=>this.isHostControlSource(s)?(await e.onClose(),{success:!0}):{success:!1}),this.messenger.on(h.RESIZE,async(n,s)=>this.isHostControlSource(s)?(await e.onResize(n),{success:!0}):{success:!1}),this.messenger.on(h.FOCUS,async(n,s)=>this.isHostControlSource(s)?(await e.onFocus(),{success:!0}):{success:!1}),this.messenger.on(h.SHOW,async(n,s)=>this.isHostControlSource(s)?(await e.onShow(),{success:!0}):{success:!1}),this.messenger.on(h.HIDE,async(n,s)=>this.isHostControlSource(s)?(await e.onHide(),{success:!0}):{success:!1}),this.messenger.on(h.ERROR,async(n,s)=>{if(!this.isHostControlSource(s))return{success:!1};const r=new Error(n.message);return r.stack=n.stack,e.onError(r),{success:!0}}),this.messenger.on(h.EXPORT,async(n,s)=>this.isHostControlSource(s)?(e.onExport(n),{success:!0}):{success:!1}),this.messenger.on(h.CONSUMER_EXPORT,async(n,s)=>this.isHostControlSource(s)?(e.onConsumerExport(n),{success:!0}):{success:!1}),this.messenger.on(h.GET_SIBLINGS,async(n,s)=>this.isHostControlSource(s)?e.onGetSiblings(n):{success:!1})}isHostControlSource(e){return!!(this.hostWindow&&e.window===this.hostWindow)}destroy(){this.messenger.destroy(),this.bridge.destroy()}}class pe{event;state={};exports;consumerExports;_uid;get uid(){return this._uid}options;cleanup;transport;renderer;propsPipeline;rendered=!1;destroyed=!1;closing=!1;get props(){return this.propsPipeline?this.propsPipeline.props:{}}set props(e){this.propsPipeline&&(this.propsPipeline.props=e)}get inputProps(){return this.propsPipeline?this.propsPipeline.inputProps:{}}set inputProps(e){this.propsPipeline&&(this.propsPipeline.inputProps=e)}get pendingPropsUpdate(){return this.propsPipeline?this.propsPipeline.pendingPropsUpdate:null}set pendingPropsUpdate(e){this.propsPipeline&&(this.propsPipeline.pendingPropsUpdate=e)}get context(){return this.renderer?this.renderer.context:this.options.defaultContext}set context(e){this.renderer&&(this.renderer.context=e)}get hostWindow(){return this.transport?this.transport.hostWindow:null}set hostWindow(e){this.transport&&(this.transport.hostWindow=e)}get openedHostDomain(){return this.transport?this.transport.openedHostDomain:null}set openedHostDomain(e){this.transport&&(this.transport.openedHostDomain=e)}get dynamicUrlTrustedOrigin(){return this.transport?this.transport.dynamicUrlTrustedOrigin:null}set dynamicUrlTrustedOrigin(e){this.transport&&(this.transport.dynamicUrlTrustedOrigin=e)}get iframe(){return this.renderer?this.renderer.iframe:null}set iframe(e){this.renderer&&(this.renderer.iframe=e)}get container(){return this.renderer?this.renderer.container:null}set container(e){this.renderer&&(this.renderer.container=e)}get initPromise(){return this.transport?this.transport.initPromise:null}set initPromise(e){this.transport&&(this.transport.initPromise=e)}get hostInitialized(){return this.transport?this.transport.hostInitialized:!1}set hostInitialized(e){this.transport&&(this.transport.hostInitialized=e)}get messenger(){if(!this.transport)throw new Error("Consumer transport is not initialized");return this.transport.messenger}get bridge(){if(!this.transport)throw new Error("Consumer transport is not initialized");return this.transport.bridge}constructor(e,n={}){this._uid=ut(),this.options=this.normalizeOptions(e),this.event=new Oe,this.cleanup=new lt,this.renderer=new un(this.options,this.uid,()=>this.props,()=>this.resolveDimensions(),{close:()=>this.close(),focus:()=>this.focus()}),this.propsPipeline=new kt(this.options,{...n},s=>this.createPropContext(s)),this.transport=new vn(this.uid,this.options,()=>this.resolveUrl(),s=>this.resolveUrlOrigin(s)),this.setupMessageHandlers(),this.setupCleanup()}async render(e,n){if(this.destroyed)throw new Error("Component has been destroyed");if(this.rendered)throw new Error("Component has already been rendered");this.context=n??this.options.defaultContext,this.checkEligibility(),F(this.props,this.options.props),this.options.validate?.({props:this.props}),this.container=this.resolveContainer(e),this.event.emit(g.PRERENDER),this.callPropCallback("onPrerender"),await this.prerender(),this.event.emit(g.PRERENDERED),this.callPropCallback("onPrerendered"),this.event.emit(g.RENDER),this.callPropCallback("onRender");try{await this.open(),await this.waitForHost(),this.context===d.IFRAME&&this.iframe&&await this.renderer.swapPrerenderContentIfNeeded()}catch(s){throw await this.destroy().catch(()=>{}),s}this.rendered=!0,this.event.emit(g.RENDERED),this.callPropCallback("onRendered"),this.event.emit(g.DISPLAY),this.callPropCallback("onDisplay")}async renderTo(e,n,s){if(e!==window)throw new Error("Cross-window renderTo is not supported; pass the current window");return this.render(n,s)}async close(){if(!(this.destroyed||this.closing)){this.closing=!0;try{this.event.emit(g.CLOSE),this.callPropCallback("onClose"),await this.destroy()}finally{this.closing=!1}}}async focus(){this.renderer.focus(this.hostWindow),this.event.emit(g.FOCUS),this.callPropCallback("onFocus")}async resize(e){this.renderer.resize(e,this.hostWindow),this.event.emit(g.RESIZE,e),this.callPropCallback("onResize",e)}async show(){this.renderer.show()}async hide(){this.renderer.hide()}async updateProps(e){return this.applyPropsUpdate(e)}async applyPropsUpdate(e){const n={resolveUrl:s=>this.resolveUrl(s),resolveUrlOrigin:s=>this.resolveUrlOrigin(s),assertStableRenderedOrigin:s=>this.assertStableRenderedOrigin(s),isRendered:()=>this.rendered,syncTrustedDomainForUrl:s=>this.syncTrustedDomainForUrl(s),shouldSendPropsToHost:()=>this.transport.isHostConnected(),sendPropsUpdateToHost:s=>this.sendPropsUpdateToHost(s),emitPropsUpdated:()=>this.emitPropsUpdated()};await this.propsPipeline.updateProps(e,n)}assertStableRenderedOrigin(e){if(this.rendered&&this.openedHostDomain&&e&&e!==this.openedHostDomain)throw new Error(`Cannot change component URL origin after render (from "${this.openedHostDomain}" to "${e}")`)}async sendPropsUpdateToHost(e){await this.transport.sendPropsUpdateToHost(e,this.options.props)}emitPropsUpdated(){this.event.emit(g.PROPS,this.props),this.callPropCallback("onProps",this.props)}clone(){const e=new pe(this.options,this.props);return e.inputProps={...this.inputProps},e}isEligible(){return this.options.eligible?this.options.eligible({props:this.props}).eligible:!0}normalizeOptions(e){return{...e,props:e.props??{},defaultContext:e.defaultContext??d.IFRAME,dimensions:e.dimensions??{width:"100%",height:"100%"},timeout:e.timeout??1e4,children:e.children}}resolveUrl(e=this.props){return typeof this.options.url=="function"?this.options.url(e):this.options.url}resolveDimensions(){return typeof this.options.dimensions=="function"?this.options.dimensions(this.props):this.options.dimensions}resolveUrlOrigin(e){try{return new URL(e,window.location.origin).origin}catch{return null}}isExplicitDomainTrust(e){return this.transport.isExplicitDomainTrust(e)}syncTrustedDomainForUrl(e){const n=this.resolveUrlOrigin(e);n&&this.isExplicitDomainTrust(n),this.transport.syncTrustedDomainForUrl(e)}createPropContext(e=this.props){return{props:e,state:this.state,close:()=>this.close(),focus:()=>this.focus(),onError:n=>this.handleError(n),container:this.container,uid:this.uid,tag:this.options.tag}}resolveContainer(e){return this.renderer.resolveContainer(e)}checkEligibility(){if(!this.options.eligible)return;const e=this.options.eligible({props:this.props});if(!e.eligible)throw new Error(`Component not eligible: ${e.reason??"Unknown reason"}`)}async prerender(){await this.renderer.prerender(e=>this.createIframeElement(e),()=>this.buildWindowName())}createIframeElement(e){return this.renderer.createIframeElement(e)}async open(){const e=this.resolveUrl();this.syncTrustedDomainForUrl(e),this.openedHostDomain=this.resolveUrlOrigin(e),this.hostWindow=this.renderer.open({baseUrl:e,buildUrl:n=>this.buildUrl(n),buildBodyParams:()=>this.buildBodyParams(),buildWindowName:()=>this.buildWindowName(),submitBodyForm:(n,s,r)=>this.submitBodyForm(n,s,r),onPopupClose:()=>{this.close()},registerCleanup:n=>{this.cleanup.register(n)}}),this.hostWindow&&Et(this.uid,this.hostWindow)}buildUrl(e=this.resolveUrl()){const s=Rt(this.props,this.options.props).toString();if(!s)return e;const r=e.includes("?")?"&":"?";return`${e}${r}${s}`}buildBodyParams(){return Dt(this.props,this.options.props)}submitBodyForm(e,n,s){this.renderer.submitBodyForm(e,n,s)}buildWindowName(){return this.transport.buildWindowName({tag:this.options.tag,context:this.context,props:this.props,propDefinitions:this.options.props,hostDomain:this.getHostDomain(),children:this.buildNestedHostRefs(),exports:this.createConsumerExports()})}buildNestedHostRefs(){if(!this.options.children)return;const e=this.options.children({props:this.props}),n={};for(const[s,r]of Object.entries(e)){const i=Mn(r);if(!i)throw new Error(`Nested component "${s}" is missing component metadata`);if(typeof i.url!="string")throw new Error(`Nested component "${s}" must use a static string URL. Function URLs are not supported in children.`);n[s]={tag:i.tag,url:i.url,props:i.props,dimensions:typeof i.dimensions=="function"?void 0:i.dimensions,defaultContext:i.defaultContext}}return Object.keys(n).length>0?n:void 0}createConsumerExports(){return{init:h.INIT,close:h.CLOSE,resize:h.RESIZE,show:h.SHOW,hide:h.HIDE,onError:h.ERROR,updateProps:h.PROPS,export:h.EXPORT}}getHostDomain(){return this.transport.getHostDomain()}async waitForHost(){await this.transport.waitForHost(this.options.timeout,this.options.tag,e=>this.handleError(e))}setupMessageHandlers(){this.transport.setupMessageHandlers({onInit:()=>this.syncSameDomainPropsAfterInit(),onClose:async()=>this.close(),onResize:async e=>this.resize(e),onFocus:async()=>this.focus(),onShow:async()=>this.show(),onHide:async()=>this.hide(),onError:e=>this.handleError(e),onExport:e=>{this.exports=e},onConsumerExport:e=>{this.consumerExports=e},onGetSiblings:e=>this.getSiblingInstances(e)})}async syncSameDomainPropsAfterInit(){if(!(!this.hostWindow||!this.transport.isHostConnected())&&Se(this.hostWindow)&&this.hasSameDomainPropDefinition())try{await this.propsPipeline.syncCurrentPropsToHost({shouldSendPropsToHost:()=>this.transport.isHostConnected(),sendPropsUpdateToHost:e=>this.sendPropsUpdateToHost(e)})}catch(e){this.handleError(e)}}hasSameDomainPropDefinition(){return Object.values(this.options.props).some(e=>!e||S(e)?!1:e.sameDomain===!0)}getSiblingInstances(e){const n=[];if(e.options?.anyConsumer){for(const s of Ln())s.instance.uid!==e.uid&&n.push({uid:s.instance.uid,tag:s.tag,exports:s.instance.exports});return n}for(const s of An(e.tag))s.uid!==e.uid&&n.push({uid:s.uid,tag:e.tag,exports:s.exports});return n}setupCleanup(){this.cleanup.register(()=>{this.messenger.destroy(),this.bridge.destroy(),bt(this.uid)})}handleError(e){this.event.emit(g.ERROR,e),this.callPropCallback("onError",e)}callPropCallback(e,...n){const s=this.props[e];if(typeof s=="function")try{const r=s(...n);r&&typeof r=="object"&&"catch"in r&&typeof r.catch=="function"&&r.catch(i=>{console.error(`Error in async ${e} callback:`,i)})}catch(r){console.error(`Error in ${e} callback:`,r)}}async destroy(){this.destroyed||(this.destroyed=!0,this.initPromise&&(this.initPromise.reject(new Error(`Component "${this.options.tag}" was destroyed before initialization completed`)),this.initPromise=null),this.hostInitialized=!1,this.renderer.destroy(this.hostWindow),this.hostWindow=null,this.openedHostDomain=null,this.dynamicUrlTrustedOrigin=null,this.pendingPropsUpdate=null,await this.cleanup.cleanup(),this.event.emit(g.DESTROY),this.callPropCallback("onDestroy"),this.event.removeAllListeners())}}const $=new Map,A=new Map;function xn(t,e){const n=e;$.get(n.uid)&&Ve(n.uid);let r=A.get(t);r||(r=new Map,A.set(t,r)),r.set(n.uid,n),$.set(n.uid,{tag:t,instance:n})}function Ve(t){const e=$.get(t);if(!e)return;$.delete(t);const n=A.get(e.tag);n&&(n.delete(t),n.size===0&&A.delete(e.tag))}function Tn(t){return Array.from(A.get(t)?.values()??[])}function Un(){return Array.from($.values())}const Ye="Could not resolve consumer window",me="Could not verify consumer origin",Hn=new Set(["uid","tag","close","focus","resize","show","hide","onProps","onError","getConsumer","getConsumerDomain","export","consumer","getPeerInstances","children"]);function L(t){const e={};for(const[n,s]of Object.entries(t))Hn.has(n)||(e[n]=s);return e}class Nn{constructor(e,n={},s,r=!1){this.propDefinitions=n,this.allowedConsumerDomains=s,this.deferInit=r,this.uid=e.uid,this.tag=e.tag,this.event=new Oe;let i=null,o=null;try{this.consumerWindow=this.resolveConsumerWindow(),this.consumerDomain=this.resolveConsumerDomain(e.consumerDomain),o=new We(this.uid,window,B(),this.consumerDomain),this.messenger=o,this.setupMessageHandlers(),i=new ae(this.messenger),this.bridge=i,this.hostProps=this.buildHostProps(e),this.exposeHostProps(),this.deferInit||this.flushInit()}catch(a){throw i?.destroy(),o?.destroy(),this.event.removeAllListeners(),this.propsHandlers.clear(),a}}hostProps;event;uid;tag;consumerWindow;consumerDomain;consumerDomainVerified=!1;messenger;bridge;propsHandlers=new Set;consumerProps;initError=null;destroyed=!1;initSent=!1;deferredInitFlushScheduled=!1;flushInit(){this.destroyed||this.initSent||(this.initSent=!0,this.sendInit())}scheduleDeferredInitFlush(){this.deferredInitFlushScheduled||this.destroyed||this.initSent||(this.deferredInitFlushScheduled=!0,queueMicrotask(()=>{this.deferredInitFlushScheduled=!1,this.flushInit()}))}exposeHostProps(){const e=window;try{Object.defineProperty(e,"hostProps",{configurable:!0,enumerable:!0,get:()=>(this.deferInit&&!this.initSent&&!this.destroyed&&this.scheduleDeferredInitFlush(),this.hostProps),set:n=>{n&&(this.hostProps=n)}})}catch{e.hostProps=this.hostProps}}validateConsumerDomain(){if(this.allowedConsumerDomains){if(!this.consumerDomain)throw new Error(`${me} for component "${this.tag}"`);if(!T(this.allowedConsumerDomains,this.consumerDomain))throw new Error(`Consumer domain "${this.consumerDomain}" is not allowed for component "${this.tag}"`)}}getVerifiedConsumerOrigin(){return this.getReferrerOrigin()??this.getAccessibleConsumerOrigin()}setConsumerDomain(e,n){const s=this.consumerDomain;this.consumerDomain=e,this.consumerDomainVerified=n,!(!this.messenger||!s||s===e)&&(this.messenger.removeTrustedDomain(s),this.messenger.addTrustedDomain(e))}applyHostConfiguration(e,n){n!==void 0&&(this.allowedConsumerDomains=n),e!==void 0&&(this.propDefinitions=e,F(this.consumerProps,this.getBootstrapValidationDefinitions()),Object.assign(this.hostProps,L(this.consumerProps)),this.hostProps.consumer.props=this.consumerProps)}resolveConsumerDomain(e){const n=this.getVerifiedConsumerOrigin();if(n)return this.consumerDomainVerified=!0,this.consumerDomain=n,this.validateConsumerDomain(),n;if(this.consumerDomainVerified=!1,this.allowedConsumerDomains)throw new Error(`${me} for component "${this.tag}"`);return e}assertAllowedConsumerDomain(e){const n=this.getVerifiedConsumerOrigin();if(n&&this.setConsumerDomain(n,!0),!this.consumerDomainVerified)throw new Error(`${me} for component "${this.tag}"`);if(!T(e,this.consumerDomain))throw new Error(`Consumer domain "${this.consumerDomain}" is not allowed for component "${this.tag}"`)}getReferrerOrigin(){if(!document.referrer)return null;try{return new URL(document.referrer,window.location.href).origin}catch{return null}}getAccessibleConsumerOrigin(){try{return this.consumerWindow.location.origin}catch{return null}}getProps(){return this.hostProps}resolveConsumerWindow(){if(wt()){const e=yt();if(e)return e}if(_t()){const e=gt();if(e)return e}throw new Error(Ye)}buildHostProps(e){const n=Ae(e.props,this.propDefinitions,this.messenger,this.bridge,this.consumerWindow,this.consumerDomain);return F(n,this.getBootstrapValidationDefinitions()),this.consumerProps=n,{...L(n),uid:this.uid,tag:this.tag,close:()=>this.close(),focus:()=>this.focus(),resize:r=>this.resize(r),show:()=>this.show(),hide:()=>this.hide(),onProps:r=>this.onProps(r),onError:r=>this.onError(r),getConsumer:()=>this.consumerWindow,getConsumerDomain:()=>this.consumerDomain,export:r=>this.exportData(r),consumer:{props:this.consumerProps,export:r=>this.consumerExport(r)},getPeerInstances:r=>this.getPeerInstances(r),children:this.buildNestedComponents(e.children)}}getBootstrapValidationDefinitions(){if(!this.consumerDomainVerified||this.consumerDomain!==B())return this.propDefinitions;let e=!1;const n={...this.propDefinitions};for(const[s,r]of Object.entries(this.propDefinitions))!r||S(r)||!r.sameDomain||(e=!0,n[s]={...r,required:!1});return e?n:this.propDefinitions}async sendInit(){try{await this.messenger.send(this.consumerWindow,this.consumerDomain,h.INIT,{uid:this.uid,tag:this.tag})}catch(e){const n=e instanceof Error?e:new Error(String(e));this.initError=n,this.event.emit(g.ERROR,{type:"init_failed",message:`Failed to initialize host component: ${n.message}`,error:n}),console.error("Failed to send init message:",e)}}getInitError(){return this.initError}async close(){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.CLOSE,{})}async focus(){window.focus(),await this.messenger.send(this.consumerWindow,this.consumerDomain,h.FOCUS,{})}async resize(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.RESIZE,e)}async show(){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.SHOW,{})}async hide(){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.HIDE,{})}onProps(e){return this.propsHandlers.add(e),{cancel:()=>this.propsHandlers.delete(e)}}async onError(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.ERROR,{message:e.message,stack:e.stack})}async exportData(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.EXPORT,e)}async consumerExport(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.CONSUMER_EXPORT,e)}async getPeerInstances(e){return await this.messenger.send(this.consumerWindow,this.consumerDomain,h.GET_SIBLINGS,{uid:this.uid,tag:this.tag,options:e})??[]}buildNestedComponents(e){if(!e)return;const n={};for(const[s,r]of Object.entries(e))try{n[s]=ye({tag:r.tag,url:r.url,props:r.props,dimensions:r.dimensions,defaultContext:r.defaultContext})}catch(i){console.warn(`Failed to create nested component "${s}":`,i)}return Object.keys(n).length>0?n:void 0}setupMessageHandlers(){this.messenger.on(h.PROPS,(e,n)=>{if(!this.isConsumerSource(n))return{success:!1};try{const s=this.consumerProps,r=Ae(e,this.propDefinitions,this.messenger,this.bridge,this.consumerWindow,this.consumerDomain);F(r,this.propDefinitions),this.removeStaleHostProps(s,r),this.consumerProps=r,Object.assign(this.hostProps,L(r)),this.hostProps.consumer.props=this.consumerProps;for(const i of this.propsHandlers)try{i(r)}catch(o){console.error("Error in props handler:",o)}return this.event.emit(g.PROPS,r),{success:!0}}catch(s){const r=s instanceof Error?s:new Error(String(s));throw console.error("Error deserializing props:",r),this.event.emit(g.ERROR,r),r}})}isConsumerSource(e){return e.window===this.consumerWindow}removeStaleHostProps(e,n){const s=L(e),r=L(n);for(const i of Object.keys(s))i in r||delete this.hostProps[i]}destroy(){this.destroyed||(this.destroyed=!0,this.deferredInitFlushScheduled=!1,this.messenger.destroy(),this.bridge.destroy(),this.event.removeAllListeners(),this.propsHandlers.clear())}}let P=null;function ee(t,e,n={}){if(P){try{P.applyHostConfiguration(t,e),e&&P.assertAllowedConsumerDomain(e)}catch(r){throw Fn(),r}return n.deferInit||P.flushInit(),P}if(!fe())return null;const s=In();if(!s)return console.error("Failed to parse ForgeFrame payload from window.name"),null;try{P=new Nn(s,t,e,n.deferInit??!1)}catch(r){if(r instanceof Error&&r.message===Ye)return null;throw r}return P}function Je(){return fe()}function qe(){return fe()}function Ke(){return window.hostProps}function Fn(){P&&(P.destroy(),P=null),delete window.hostProps}function ge(){return typeof window<"u"&&typeof window.location<"u"}const te=new Map,Xe=Symbol("forgeframe.component.options");function $n(t){if(!t.tag)throw new Error("Component tag is required");if(!/^[a-z][a-z0-9-]*$/.test(t.tag))throw new Error(`Invalid component tag "${t.tag}". Must start with lowercase letter and contain only lowercase letters, numbers, and hyphens.`);if(!t.url)throw new Error("Component url is required");if(typeof t.url=="string")try{const e=ge()?window.location.origin:"https://forgeframe.invalid";new URL(t.url,e)}catch{throw new Error(`Invalid component URL "${t.url}". Must be a valid absolute or relative URL.`)}if(te.has(t.tag))throw new Error(`Component "${t.tag}" is already registered`)}function ye(t){$n(t);const e=[];let n;const s=()=>ge()&&Cn(t.tag),r=()=>{if(n)return n;if(!s())return;const a=ee(t.props,t.allowedConsumerDomains);if(a)return n=a.hostProps,n};r();const i=()=>(r(),n!==void 0||s()),o=function(a={}){const c=new pe(t,a);return e.push(c),xn(t.tag,c),c.event.once("destroy",()=>{const u=e.indexOf(c);u!==-1&&e.splice(u,1),Ve(c.uid)}),c};return o.instances=e,o.isHost=()=>i(),o.isEmbedded=()=>i(),Object.defineProperty(o,"hostProps",{configurable:!0,enumerable:!0,get:()=>r()}),o[Xe]=t,o.canRenderTo=async a=>a===window,te.set(t.tag,o),o}function An(t){return Tn(t)}function Ln(){return Un()}function Mn(t){return t[Xe]}async function Ge(t){await t.close()}async function we(t){const e=te.get(t);if(!e)return;const n=[...e.instances];await Promise.all(n.map(s=>s.close()))}async function Ze(){const t=Array.from(te.keys());await Promise.all(t.map(e=>we(e)))}function zn(t,e){const n=Object.keys(t),s=Object.keys(e);if(n.length!==s.length)return!1;for(const r of n)if(!Object.prototype.hasOwnProperty.call(e,r)||!Object.is(t[r],e[r]))return!1;return!0}function Qe(t,e){const{React:n}=e,{createElement:s,useRef:r,useEffect:i,useState:o,forwardRef:a}=n,c=a(function(y,f){const{onRendered:O,onError:D,onClose:_e,context:tt,className:nt,style:st,...Pe}=y,Ee=r(null),M=r(null),ne=r(null),rt=r(O),se=r(D),it=r(_e),[ot,at]=o(null);return i(()=>{rt.current=O,se.current=D,it.current=_e},[O,D,_e]),i(()=>{const E=Ee.current;if(!E)return;at(null);const w=t(Pe);M.current=w,ne.current=Pe;const re=w.event.once("rendered",()=>{rt.current?.()}),ct=w.event.once("close",()=>{it.current?.()}),be=w.event.on("error",ie=>{se.current?.(ie)});return w.render(E,tt).catch(ie=>{M.current===w&&(at(ie),se.current?.(ie))}),()=>{w.close().catch(()=>{}),re(),ct(),be(),M.current=null,ne.current=null}},[tt]),i(()=>{const E=M.current;if(!E)return;const w=Pe,re=ne.current;re&&zn(re,w)||(ne.current=w,E.updateProps(w).catch(be=>{M.current===E&&se.current?.(be)}))}),i(()=>{const E=Ee.current;if(typeof f=="function")return f(E),()=>{f(null)};if(f&&typeof f=="object")return f.current=E,()=>{f.current=null}},[f]),ot?s("div",{className:nt,style:{color:"red",padding:"16px",...st}},`Error: ${ot.message}`):s("div",{ref:Ee,className:nt,style:{display:"inline-block",...st}})}),u=`ForgeFrame(${t.name||"Component"})`;return c.displayName=u,c}function kn(t){return function(n){return Qe(n,{React:t})}}ge()&&ee(void 0,void 0,{deferInit:!0});const et={create:ye,destroy:Ge,destroyByTag:we,destroyAll:Ze,isHost:Je,isEmbedded:qe,getHostProps:Ke,initHost:ee,PROP_SERIALIZATION:v,CONTEXT:d,EVENT:g,PopupOpenError:le,VERSION:W,isStandardSchema:S,prop:m};l.AnySchema=G,l.ArraySchema=U,l.BooleanSchema=J,l.CONTEXT=d,l.EVENT=g,l.EnumSchema=X,l.ForgeFrame=et,l.FunctionSchema=q,l.LiteralSchema=K,l.NumberSchema=Y,l.ObjectSchema=H,l.PROP_SERIALIZATION=v,l.PopupOpenError=le,l.PropSchema=_,l.StringSchema=V,l.VERSION=W,l.create=ye,l.createReactComponent=Qe,l.default=et,l.destroy=Ge,l.destroyAll=Ze,l.destroyByTag=we,l.getHostProps=Ke,l.initHost=ee,l.isEmbedded=qe,l.isHost=Je,l.isStandardSchema=S,l.prop=m,l.withReactComponent=kn,Object.defineProperties(l,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
5
+ `,(t.head??t.documentElement).appendChild(s)}function Pn(t){const{doc:e,dimensions:n,uid:s,tag:r}=t,i=e.createElement("div");return i.id=`forgeframe-container-${s}`,i.setAttribute("data-forgeframe-tag",r),Object.assign(i.style,{display:"inline-block",position:"relative",width:x(n.width),height:x(n.height),overflow:"hidden"}),i}function En(t){const{doc:e,dimensions:n,cspNonce:s}=t;_n(e,s);const r=e.createElement("div");Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",width:x(n.width),height:x(n.height),backgroundColor:"#f5f5f5",position:"absolute",top:"0",left:"0",zIndex:"100"});const i=e.createElement("div");return Object.assign(i.style,{width:"40px",height:"40px",border:"3px solid #e0e0e0",borderTopColor:"#3498db",borderRadius:"50%",animation:"forgeframe-spin 1s linear infinite"}),r.appendChild(i),r}function bn(t,e=200){return new Promise(n=>{t.style.opacity="0",t.style.transition=`opacity ${e}ms ease-in`,t.offsetHeight,t.style.opacity="1",setTimeout(n,e)})}function Cn(t,e=200){return new Promise(n=>{t.style.transition=`opacity ${e}ms ease-out`,t.style.opacity="0",setTimeout(n,e)})}async function On(t,e,n){e&&(await Cn(e,150),e.remove()),n.style.display="",n.style.visibility="visible",n.style.opacity="0",await bn(n,150)}class Rn{constructor(e,n,s,r,i){this.options=e,this.uid=n,this.getProps=s,this.resolveDimensions=r,this.callbacks=i,this.context=this.options.defaultContext}context;iframe=null;container=null;prerenderElement=null;ownedContainer=null;resolveContainer(e){if(!e)throw new Error("Container is required for rendering");if(typeof e=="string"){const n=document.querySelector(e);if(!n)throw new Error(`Container "${e}" not found`);return n}return e}async prerender(e,n){if(!this.container)return;const s=this.container;this.ownedContainer=null;const r=this.getProps(),i=this.options.prerenderTemplate??En,o=this.options.containerTemplate??Pn,a=this.resolveDimensions(),c=r.cspNonce;if(this.context===f.IFRAME){const p=n();this.iframe=e(p),We(this.iframe)}const u={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:a,props:r,doc:document,container:s,frame:this.iframe,prerenderFrame:null,close:()=>this.callbacks.close(),focus:()=>this.callbacks.focus(),cspNonce:c};this.prerenderElement=i(u);const h={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:a,props:r,doc:document,container:s,frame:this.iframe,prerenderFrame:this.prerenderElement,close:()=>this.callbacks.close(),focus:()=>this.callbacks.focus(),cspNonce:c},y=o(h);if(y){if(y!==s){const p=!y.parentNode;s.appendChild(y),p&&(this.ownedContainer=y)}this.container=y}this.prerenderElement&&!this.prerenderElement.parentNode&&this.container.appendChild(this.prerenderElement),this.iframe&&!this.iframe.parentNode&&this.container.appendChild(this.iframe)}createIframeElement(e){const n=this.resolveDimensions(),s=this.getProps(),r=typeof this.options.attributes=="function"?this.options.attributes(s):this.options.attributes??{},i=typeof this.options.style=="function"?this.options.style(s):this.options.style??{};return rn({name:e,dimensions:n,attributes:r,style:i})}open(e){const n=e.buildUrl(e.baseUrl),s=e.buildBodyParams(),r=s.toString().length>0;if(this.context===f.IFRAME){if(!this.iframe)throw new Error("Iframe not created during prerender");return r?e.submitBodyForm(this.iframe.name,n,s):this.iframe.src=n,this.iframe.contentWindow}const i=e.buildWindowName(),o=pn({url:r?"about:blank":n,name:i,dimensions:this.resolveDimensions()});r&&e.submitBodyForm(i,n,s);const a=yn(o,()=>{e.onPopupClose()});return e.registerCleanup(a),o}async swapPrerenderContentIfNeeded(){this.context===f.IFRAME&&this.iframe&&this.container&&(await On(this.container,this.prerenderElement,this.iframe),this.prerenderElement=null)}submitBodyForm(e,n,s){const r=this.container?.ownerDocument??document,i=r.body??r.documentElement;if(!i)throw new Error("Document root is unavailable for bodyParam form submission");const o=r.createElement("form");o.method="POST",o.action=n,o.target=e,o.style.display="none";for(const[a,c]of s.entries()){const u=r.createElement("input");u.type="hidden",u.name=a,u.value=c,o.appendChild(u)}i.appendChild(o);try{o.submit()}finally{o.remove()}}focus(e){this.context===f.IFRAME&&this.iframe?un(this.iframe):this.context===f.POPUP&&e&&mn(e)}resize(e,n){this.context===f.IFRAME&&this.iframe?an(this.iframe,e):this.context===f.POPUP&&n&&wn(n,e)}show(){this.context===f.IFRAME&&this.iframe&&cn(this.iframe)}hide(){this.context===f.IFRAME&&this.iframe&&We(this.iframe)}destroy(e){this.iframe&&(on(this.iframe),this.iframe=null),this.context===f.POPUP&&e&&fn(e),this.prerenderElement&&(this.prerenderElement.remove(),this.prerenderElement=null),this.ownedContainer&&(this.ownedContainer.remove(),this.ownedContainer=null),this.container=null}}function Sn(t){const e=[];if(t.options?.anyConsumer){for(const n of $n())n.instance.uid!==t.uid&&e.push({uid:n.instance.uid,tag:n.tag,exports:n.instance.exports});return e}for(const n of Mn(t.tag))n.uid!==t.uid&&e.push({uid:n.uid,tag:t.tag,exports:n.exports});return e}function Ve(){let t,e;return{promise:new Promise((s,r)=>{t=s,e=r}),resolve:t,reject:e}}function Dn(t,e,n="Operation timed out"){return new Promise((s,r)=>{const i=setTimeout(()=>{r(new Error(`${n} (${e}ms)`))},e);t.then(o=>{clearTimeout(i),s(o)}).catch(o=>{clearTimeout(i),r(o)})})}const ge="forgeframe:";function ye(t){return ge+JSON.stringify(t)}function In(t){if(typeof t!="string"||!t.startsWith(ge))return null;try{const e=t.slice(ge.length),n=JSON.parse(e);return!n.id||!n.type||!n.name||!n.source?null:n}catch{return null}}function Ye(t,e,n,s){return{id:t,type:k.REQUEST,name:e,data:n,source:s}}function vn(t,e,n,s){return{id:t,type:k.RESPONSE,name:"response",data:e,source:n,error:s?{message:s.message,stack:s.stack}:void 0}}function xn(t,e,n){return e!==t.targetWin?!1:t.expectedOrigin==="*"?!0:n===t.expectedOrigin}function Tn(t,e){if(t==="*")return"*";if(t==="/")return e;try{return new URL(t,e).origin}catch{return t}}class Je{constructor(e,n=window,s=window.location.origin,r){this.uid=e,this.win=n,this.domain=s,this.allowedOrigins.add(s),r&&this.addTrustedDomain(r),this.setupListener()}pending=new Map;handlers=new Map;listener=null;destroyed=!1;allowedOrigins=new Set;allowedOriginPatterns=[];wildcardPatternRegistry=new Map;sourceUidRegistry=new WeakMap;addTrustedDomain(e){if(Array.isArray(e))for(const n of e)this.addTrustedDomain(n);else if(e instanceof RegExp)this.allowedOriginPatterns.push(e);else{const n=Me(e);n?this.wildcardPatternRegistry.has(e)||(this.wildcardPatternRegistry.set(e,n),this.allowedOriginPatterns.push(n)):this.allowedOrigins.add(e)}}removeTrustedDomain(e){if(Array.isArray(e))for(const n of e)this.removeTrustedDomain(n);else if(e instanceof RegExp)this.allowedOriginPatterns=this.allowedOriginPatterns.filter(n=>n!==e);else{const n=this.wildcardPatternRegistry.get(e);n&&(this.allowedOriginPatterns=this.allowedOriginPatterns.filter(s=>s!==n),this.wildcardPatternRegistry.delete(e)),this.allowedOrigins.delete(e)}}isOriginTrusted(e){if(this.allowedOrigins.has(e))return!0;for(const n of this.allowedOriginPatterns)if(pe(n,e))return!0;return!1}resolveVerifiedSource(e,n,s){const r=e,i=this.sourceUidRegistry.get(r);if(i)return{uid:i,domain:n,window:e};const o=s&&typeof s.uid=="string"&&s.uid.length>0?s.uid:B();return this.sourceUidRegistry.set(r,o),{uid:o,domain:n,window:e}}async send(e,n,s,r,i=1e4){if(this.destroyed)throw new Error("Messenger has been destroyed");const o=B(),a=Ye(o,s,r,{uid:this.uid,domain:this.domain}),c=Ve(),u=setTimeout(()=>{this.pending.delete(o),c.reject(new Error(`Message "${s}" timed out after ${i}ms`))},i);this.pending.set(o,{deferred:c,timeout:u,targetWin:e,expectedOrigin:Tn(n,this.domain)});try{e.postMessage(ye(a),n)}catch(h){throw this.pending.delete(o),clearTimeout(u),h}return c.promise}post(e,n,s,r){if(this.destroyed)throw new Error("Messenger has been destroyed");const i=B(),o=Ye(i,s,r,{uid:this.uid,domain:this.domain});e.postMessage(ye(o),n)}on(e,n){return this.handlers.set(e,n),()=>this.handlers.delete(e)}setupListener(){this.listener=e=>{if(e.source===this.win||!this.isOriginTrusted(e.origin))return;const n=In(e.data);if(!n)return;const s=e.source;!s||typeof s.postMessage!="function"||this.handleMessage(n,s,e.origin)},this.win.addEventListener("message",this.listener)}async handleMessage(e,n,s){if(e.type===k.RESPONSE){const r=this.pending.get(e.id);if(r){if(!xn(r,n,s))return;if(this.pending.delete(e.id),clearTimeout(r.timeout),e.error){const i=new Error(e.error.message);i.stack=e.error.stack,r.deferred.reject(i)}else r.deferred.resolve(e.data)}return}if(e.type===k.REQUEST){const r=this.handlers.get(e.name);if(!r)return;let i,o;try{const c=this.resolveVerifiedSource(n,s,e.source);i=await r(e.data,c)}catch(c){o=c instanceof Error?c:new Error(String(c))}const a=vn(e.id,i,{uid:this.uid,domain:this.domain},o);try{n.postMessage(ye(a),s)}catch{}}}destroy(){if(!this.destroyed){this.destroyed=!0,this.listener&&(this.win.removeEventListener("message",this.listener),this.listener=null);for(const e of this.pending.values())clearTimeout(e.timeout),e.deferred.reject(new Error("Messenger destroyed"));this.pending.clear(),this.handlers.clear()}}isDestroyed(){return this.destroyed}}class Hn{constructor(e,n,s,r){this.uid=e,this.options=n,this.resolveUrl=s,this.resolveUrlOrigin=r;const i=this.buildTrustedDomains();this.messenger=new Je(this.uid,window,Q(),i),this.bridge=new le(this.messenger)}messenger;bridge;hostWindow=null;openedHostDomain=null;dynamicUrlTrustedOrigin=null;initPromise=null;hostInitialized=!1;buildTrustedDomains(){const e=[],n=this.resolveUrlOrigin(this.resolveUrl());if(n&&(e.push(n),this.dynamicUrlTrustedOrigin=n),this.options.domain&&(typeof this.options.domain=="string"?e.push(this.options.domain):Array.isArray(this.options.domain)?e.push(...this.options.domain):this.options.domain instanceof RegExp&&e.push(this.options.domain)),e.length!==0)return e.length===1?e[0]:e}isExplicitDomainTrust(e){return this.options.domain?ee(this.options.domain,e):!1}syncTrustedDomainForUrl(e){const n=this.resolveUrlOrigin(e);if(!n)return;const s=this.dynamicUrlTrustedOrigin;s&&s!==n&&!this.isExplicitDomainTrust(s)&&this.messenger.removeTrustedDomain(s),this.messenger.addTrustedDomain(n),this.dynamicUrlTrustedOrigin=n}getHostDomain(){return this.openedHostDomain?this.openedHostDomain:this.resolveUrlOrigin(this.resolveUrl())??"*"}isHostConnected(){return!!(this.hostWindow&&!fe(this.hostWindow))}serializePropsForHost(e,n,s){this.bridge.startBatch();const r=s?.finishBatch??!0;try{const i=Mt(e,n,this.bridge);return r&&this.bridge.finishBatch(),i}catch(i){throw this.bridge.finishBatch(!0),i}}async sendPropsUpdateToHost(e,n){if(!this.hostWindow||fe(this.hostWindow))return;const s=this.getHostDomain(),r=ze(e,n,s,$e(this.hostWindow)),i=this.serializePropsForHost(r,n,{finishBatch:!1});try{await this.messenger.send(this.hostWindow,s,d.PROPS,i),this.bridge.finishBatch()}catch(o){throw this.bridge.finishBatch(!0),o}}buildWindowName(e){const n=e.hostDomain??this.getHostDomain(),s=ze(e.props,e.propDefinitions,n,!1),r=this.serializePropsForHost(s,e.propDefinitions),i=Ot({uid:this.uid,tag:e.tag,context:e.context,consumerDomain:Q(),props:r,exports:e.exports,children:e.children});return mt(i)}async waitForHost(e,n,s){if(this.hostInitialized)return;const r=Ve();this.initPromise=r;try{await Dn(r.promise,e,`Host component "${n}" (uid: ${this.uid}) did not initialize within ${e}ms. Check that the host page loads correctly and calls the initialization code.`)}catch(i){throw s(i),i}finally{this.initPromise===r&&(this.initPromise=null)}}setupMessageHandlers(e){this.messenger.on(d.INIT,(n,s)=>this.isHostControlSource(s)?(this.hostInitialized=!0,this.initPromise&&this.initPromise.resolve(),e.onInit&&queueMicrotask(()=>{Promise.resolve(e.onInit?.()).catch(r=>{e.onError(r)})}),{success:!0}):{success:!1}),this.messenger.on(d.CLOSE,async(n,s)=>this.isHostControlSource(s)?(await e.onClose(),{success:!0}):{success:!1}),this.messenger.on(d.RESIZE,async(n,s)=>this.isHostControlSource(s)?(await e.onResize(n),{success:!0}):{success:!1}),this.messenger.on(d.FOCUS,async(n,s)=>this.isHostControlSource(s)?(await e.onFocus(),{success:!0}):{success:!1}),this.messenger.on(d.SHOW,async(n,s)=>this.isHostControlSource(s)?(await e.onShow(),{success:!0}):{success:!1}),this.messenger.on(d.HIDE,async(n,s)=>this.isHostControlSource(s)?(await e.onHide(),{success:!0}):{success:!1}),this.messenger.on(d.ERROR,async(n,s)=>{if(!this.isHostControlSource(s))return{success:!1};const r=new Error(n.message);return r.stack=n.stack,e.onError(r),{success:!0}}),this.messenger.on(d.EXPORT,async(n,s)=>this.isHostControlSource(s)?(e.onExport(n),{success:!0}):{success:!1}),this.messenger.on(d.CONSUMER_EXPORT,async(n,s)=>this.isHostControlSource(s)?(e.onConsumerExport(n),{success:!0}):{success:!1}),this.messenger.on(d.GET_SIBLINGS,async(n,s)=>this.isHostControlSource(s)?e.onGetSiblings(n):{success:!1})}isHostControlSource(e){return!!(this.hostWindow&&e.window===this.hostWindow)}destroy(){this.messenger.destroy(),this.bridge.destroy()}}class we{event;state={};exports;consumerExports;_uid;get uid(){return this._uid}options;cleanup;transport;renderer;propsPipeline;rendered=!1;destroyed=!1;closing=!1;constructor(e,n={}){this._uid=St(),this.options=this.normalizeOptions(e),this.event=new Ie,this.cleanup=new Zt,this.renderer=new Rn(this.options,this.uid,()=>this.propsPipeline.props,()=>this.resolveDimensions(),{close:()=>this.close(),focus:()=>this.focus()}),this.propsPipeline=new sn(this.options,{...n},s=>this.createPropContext(s)),!this.destroyed&&(this.transport=new Hn(this.uid,this.options,()=>this.resolveUrl(),s=>this.resolveUrlOrigin(s)),this.setupMessageHandlers(),this.setupCleanup())}async render(e,n){if(this.destroyed)throw new Error("Component has been destroyed");if(this.rendered)throw new Error("Component has already been rendered");this.renderer.context=n??this.options.defaultContext,this.checkEligibility(),A(this.propsPipeline.props,this.options.props),this.options.validate?.({props:this.propsPipeline.props}),this.renderer.container=this.resolveContainer(e),this.event.emit(g.PRERENDER),w(this.propsPipeline.props,"onPrerender"),await this.prerender(),this.event.emit(g.PRERENDERED),w(this.propsPipeline.props,"onPrerendered"),this.event.emit(g.RENDER),w(this.propsPipeline.props,"onRender");try{await this.open(),await this.waitForHost(),this.renderer.context===f.IFRAME&&this.renderer.iframe&&await this.renderer.swapPrerenderContentIfNeeded()}catch(s){throw await this.destroy().catch(()=>{}),s}this.rendered=!0,this.event.emit(g.RENDERED),w(this.propsPipeline.props,"onRendered"),this.event.emit(g.DISPLAY),w(this.propsPipeline.props,"onDisplay")}async renderTo(e,n,s){if(e!==window)throw new Error("Cross-window renderTo is not supported; pass the current window");return this.render(n,s)}async close(){if(!(this.destroyed||this.closing)){this.closing=!0;try{const e=this.propsPipeline?this.propsPipeline.props:{};this.event.emit(g.CLOSE),w(e,"onClose"),await this.destroy()}finally{this.closing=!1}}}async focus(){const e=this.transport?this.transport.hostWindow:null,n=this.propsPipeline?this.propsPipeline.props:{};this.renderer.focus(e),this.event.emit(g.FOCUS),w(n,"onFocus")}async resize(e){const n=this.transport?this.transport.hostWindow:null,s=this.propsPipeline?this.propsPipeline.props:{};this.renderer.resize(e,n),this.event.emit(g.RESIZE,e),w(s,"onResize",e)}async show(){this.renderer.show()}async hide(){this.renderer.hide()}async updateProps(e){return this.applyPropsUpdate(e)}async applyPropsUpdate(e){const n={resolveUrl:s=>this.resolveUrl(s),resolveUrlOrigin:s=>this.resolveUrlOrigin(s),assertStableRenderedOrigin:s=>this.assertStableRenderedOrigin(s),isRendered:()=>this.rendered,syncTrustedDomainForUrl:s=>this.syncTrustedDomainForUrl(s),shouldSendPropsToHost:()=>this.transport?this.transport.isHostConnected():!1,sendPropsUpdateToHost:s=>this.sendPropsUpdateToHost(s),emitPropsUpdated:s=>{this.event.emit(g.PROPS,s),w(s,"onProps",s)}};await this.propsPipeline.updateProps(e,n)}assertStableRenderedOrigin(e){const n=this.transport?.openedHostDomain;if(this.rendered&&n&&e&&e!==n)throw new Error(`Cannot change component URL origin after render (from "${n}" to "${e}")`)}async sendPropsUpdateToHost(e){this.transport&&await this.transport.sendPropsUpdateToHost(e,this.options.props)}clone(){const e=new we(this.options,this.propsPipeline.props);return e.propsPipeline.inputProps={...this.propsPipeline.inputProps},e}isEligible(){return this.options.eligible?this.options.eligible({props:this.propsPipeline.props}).eligible:!0}normalizeOptions(e){return{...e,props:e.props??{},defaultContext:e.defaultContext??f.IFRAME,dimensions:e.dimensions??{width:"100%",height:"100%"},timeout:e.timeout??1e4,children:e.children}}resolveUrl(e=this.propsPipeline.props){return typeof this.options.url=="function"?this.options.url(e):this.options.url}resolveDimensions(){return typeof this.options.dimensions=="function"?this.options.dimensions(this.propsPipeline.props):this.options.dimensions}resolveUrlOrigin(e){try{return new URL(e,window.location.origin).origin}catch{return null}}isExplicitDomainTrust(e){return this.transport?this.transport.isExplicitDomainTrust(e):!1}syncTrustedDomainForUrl(e){const n=this.resolveUrlOrigin(e);n&&this.isExplicitDomainTrust(n),this.transport&&this.transport.syncTrustedDomainForUrl(e)}createPropContext(e){const n=e??this.propsPipeline?.props??{};return{props:n,state:this.state,close:()=>this.close(),focus:()=>this.focus(),onError:s=>te(this.event,this.propsPipeline?.props??n,s),container:this.renderer.container,uid:this.uid,tag:this.options.tag}}resolveContainer(e){return this.renderer.resolveContainer(e)}checkEligibility(){if(!this.options.eligible)return;const e=this.options.eligible({props:this.propsPipeline.props});if(!e.eligible)throw new Error(`Component not eligible: ${e.reason??"Unknown reason"}`)}async prerender(){await this.renderer.prerender(e=>this.createIframeElement(e),()=>this.buildWindowName())}createIframeElement(e){return this.renderer.createIframeElement(e)}async open(){const e=this.resolveUrl();this.syncTrustedDomainForUrl(e),this.transport.openedHostDomain=this.resolveUrlOrigin(e),this.transport.hostWindow=this.renderer.open({baseUrl:e,buildUrl:n=>this.buildUrl(n),buildBodyParams:()=>this.buildBodyParams(),buildWindowName:()=>this.buildWindowName(),submitBodyForm:(n,s,r)=>this.submitBodyForm(n,s,r),onPopupClose:()=>{this.close()},registerCleanup:n=>{this.cleanup.register(n)}}),this.transport.hostWindow&&en(this.uid,this.transport.hostWindow)}buildUrl(e=this.resolveUrl()){const s=Xt(this.propsPipeline.props,this.options.props).toString();if(!s)return e;const r=e.includes("?")?"&":"?";return`${e}${r}${s}`}buildBodyParams(){return Gt(this.propsPipeline.props,this.options.props)}submitBodyForm(e,n,s){this.renderer.submitBodyForm(e,n,s)}buildWindowName(){return this.transport.buildWindowName({tag:this.options.tag,context:this.renderer.context,props:this.propsPipeline.props,propDefinitions:this.options.props,hostDomain:this.getHostDomain(),children:nn(this.options,this.propsPipeline.props),exports:this.createConsumerExports()})}createConsumerExports(){return{init:d.INIT,close:d.CLOSE,resize:d.RESIZE,show:d.SHOW,hide:d.HIDE,onError:d.ERROR,updateProps:d.PROPS,export:d.EXPORT}}getHostDomain(){return this.transport.getHostDomain()}async waitForHost(){await this.transport.waitForHost(this.options.timeout,this.options.tag,e=>te(this.event,this.propsPipeline.props,e))}setupMessageHandlers(){this.transport.setupMessageHandlers({onInit:()=>this.syncSameDomainPropsAfterInit(),onClose:async()=>this.close(),onResize:async e=>this.resize(e),onFocus:async()=>this.focus(),onShow:async()=>this.show(),onHide:async()=>this.hide(),onError:e=>te(this.event,this.propsPipeline.props,e),onExport:e=>{this.exports=e},onConsumerExport:e=>{this.consumerExports=e},onGetSiblings:e=>Sn(e)})}async syncSameDomainPropsAfterInit(){if(!(!this.transport.hostWindow||!this.transport.isHostConnected())&&$e(this.transport.hostWindow)&&this.hasSameDomainPropDefinition())try{await this.propsPipeline.syncCurrentPropsToHost({shouldSendPropsToHost:()=>this.transport.isHostConnected(),sendPropsUpdateToHost:e=>this.sendPropsUpdateToHost(e)})}catch(e){te(this.event,this.propsPipeline.props,e)}}hasSameDomainPropDefinition(){return Object.values(this.options.props).some(e=>!e||I(e)?!1:e.sameDomain===!0)}setupCleanup(){this.cleanup.register(()=>{this.transport.destroy(),tn(this.uid)})}async destroy(){if(this.destroyed)return;this.destroyed=!0;const e=this.propsPipeline?this.propsPipeline.props:{},n=this.transport?this.transport.hostWindow:null;this.transport&&this.transport.initPromise&&(this.transport.initPromise.reject(new Error(`Component "${this.options.tag}" was destroyed before initialization completed`)),this.transport.initPromise=null),this.transport&&(this.transport.hostInitialized=!1),this.renderer.destroy(n),this.transport&&(this.transport.hostWindow=null,this.transport.openedHostDomain=null,this.transport.dynamicUrlTrustedOrigin=null),this.propsPipeline&&(this.propsPipeline.pendingPropsUpdate=null),await this.cleanup.cleanup(),this.event.emit(g.DESTROY),w(e,"onDestroy"),this.event.removeAllListeners()}}const M=new Map,$=new Map;function Un(t,e){const n=e;M.get(n.uid)&&qe(n.uid);let r=$.get(t);r||(r=new Map,$.set(t,r)),r.set(n.uid,n),M.set(n.uid,{tag:t,instance:n})}function qe(t){const e=M.get(t);if(!e)return;M.delete(t);const n=$.get(e.tag);n&&(n.delete(t),n.size===0&&$.delete(e.tag))}function Fn(t){return Array.from($.get(t)?.values()??[])}function Nn(){return Array.from(M.values())}function Ke(){return ue()}function Xe(){return ue()}function Ge(){return window.hostProps}const se=new Map,Ze=Symbol("forgeframe.component.options");function An(t){if(!t.tag)throw new Error("Component tag is required");if(!/^[a-z][a-z0-9-]*$/.test(t.tag))throw new Error(`Invalid component tag "${t.tag}". Must start with lowercase letter and contain only lowercase letters, numbers, and hyphens.`);if(!t.url)throw new Error("Component url is required");if(typeof t.url=="string")try{const e=R()?window.location.origin:"https://forgeframe.invalid";new URL(t.url,e)}catch{throw new Error(`Invalid component URL "${t.url}". Must be a valid absolute or relative URL.`)}if(se.has(t.tag))throw new Error(`Component "${t.tag}" is already registered`)}function _e(t){An(t);const e=[];let n;const s=()=>R()&&Et(t.tag),r=()=>{if(n)return n;if(!s())return;const a=re(t.props,t.allowedConsumerDomains);if(a)return n=a.hostProps,n};r();const i=()=>(r(),n!==void 0||s()),o=function(a={}){const c=new we(t,a);return c.destroyed||(e.push(c),Un(t.tag,c),c.event.once("destroy",()=>{const h=e.indexOf(c);h!==-1&&e.splice(h,1),qe(c.uid)})),c};return o.instances=e,o.isHost=()=>i(),o.isEmbedded=()=>i(),Object.defineProperty(o,"hostProps",{configurable:!0,enumerable:!0,get:()=>r()}),o[Ze]=t,o.canRenderTo=async a=>a===window,se.set(t.tag,o),o}function Mn(t){return Fn(t)}function $n(){return Nn()}function Ln(t){return t[Ze]}async function Qe(t){await t.close()}async function Pe(t){const e=se.get(t);if(!e)return;const n=[...e.instances];await Promise.all(n.map(s=>s.close()))}async function et(){const t=Array.from(se.keys());await Promise.all(t.map(e=>Pe(e)))}const zn=new Set(["uid","tag","close","focus","resize","show","hide","onProps","onError","getConsumer","getConsumerDomain","export","consumer","getPeerInstances","children"]);function L(t){const e={};for(const[n,s]of Object.entries(t))zn.has(n)||(e[n]=s);return e}class kn{constructor(e={},n){this.propDefinitions=e,this.options=n}hostProps;consumerProps;propsHandlers=new Set;initializeHostProps(e){const n=this.deserialize(e.props);A(n,this.getBootstrapValidationDefinitions()),this.consumerProps=n;const s=L(n);return this.hostProps={...s,uid:this.options.uid,tag:this.options.tag,close:()=>this.options.controls.close(),focus:()=>this.options.controls.focus(),resize:r=>this.options.controls.resize(r),show:()=>this.options.controls.show(),hide:()=>this.options.controls.hide(),onProps:r=>this.onProps(r),onError:r=>this.options.controls.onError(r),getConsumer:()=>this.options.getConsumerWindow(),getConsumerDomain:()=>this.options.getConsumerDomain(),export:r=>this.options.controls.exportData(r),consumer:{props:this.consumerProps,export:r=>this.options.controls.consumerExport(r)},getPeerInstances:r=>this.options.controls.getPeerInstances(r),children:this.buildNestedComponents(e.children)},this.hostProps}exposeHostProps(){const e=window;try{Object.defineProperty(e,"hostProps",{configurable:!0,enumerable:!0,get:()=>(this.options.onFirstHostPropsAccess(),this.hostProps),set:n=>{n&&(this.hostProps=n)}})}catch{e.hostProps=this.hostProps}}applyHostConfiguration(e){this.propDefinitions=e,A(this.consumerProps,this.getBootstrapValidationDefinitions()),Object.assign(this.hostProps,L(this.consumerProps)),this.hostProps.consumer.props=this.consumerProps}applySerializedProps(e){try{const n=this.consumerProps,s=this.deserialize(e);A(s,this.propDefinitions),this.removeStaleHostProps(n,s),this.consumerProps=s,Object.assign(this.hostProps,L(s)),this.hostProps.consumer.props=this.consumerProps;for(const r of this.propsHandlers)try{r(s)}catch(i){console.error("Error in props handler:",i)}return this.options.event.emit(g.PROPS,s),{success:!0}}catch(n){const s=n instanceof Error?n:new Error(String(n));throw console.error("Error deserializing props:",s),this.options.event.emit(g.ERROR,s),s}}destroy(){this.propsHandlers.clear()}onProps(e){return this.propsHandlers.add(e),{cancel:()=>this.propsHandlers.delete(e)}}deserialize(e){return Lt(e,this.propDefinitions,this.options.getMessenger(),this.options.getBridge(),this.options.getConsumerWindow(),this.options.getConsumerDomain())}getBootstrapValidationDefinitions(){if(!this.options.isConsumerDomainVerified()||this.options.getConsumerDomain()!==Q())return this.propDefinitions;let e=!1;const n={...this.propDefinitions};for(const[s,r]of Object.entries(this.propDefinitions))!r||I(r)||!r.sameDomain||(e=!0,n[s]={...r,required:!1});return e?n:this.propDefinitions}buildNestedComponents(e){if(!e)return;const n={};for(const[s,r]of Object.entries(e))try{n[s]=_e({tag:r.tag,url:r.url,props:r.props,dimensions:r.dimensions,defaultContext:r.defaultContext})}catch(i){console.warn(`Failed to create nested component "${s}":`,i)}return Object.keys(n).length>0?n:void 0}removeStaleHostProps(e,n){const s=L(e),r=L(n);for(const i of Object.keys(s))i in r||delete this.hostProps[i]}}const tt="Could not resolve consumer window",Ee="Could not verify consumer origin";function nt(t,e,n){if(!e)throw new Error(`${Ee} for component "${n}"`);if(!ee(t,e))throw new Error(`Consumer domain "${e}" is not allowed for component "${n}"`)}function Wn(t=window){if(Yt(t)){const e=Vt(t);if(e)return e}if(Jt(t)){const e=Bt(t);if(e)return e}throw new Error(tt)}function jn(t=document,e=window){if(!t.referrer)return null;try{return new URL(t.referrer,e.location.href).origin}catch{return null}}function Bn(t){try{return t.location.origin}catch{return null}}function st(t,e=document,n=window){return jn(e,n)??Bn(t)}function Vn(t){const e=st(t.consumerWindow);if(e)return t.allowedConsumerDomains&&nt(t.allowedConsumerDomains,e,t.tag),{consumerDomain:e,consumerDomainVerified:!0};if(t.allowedConsumerDomains)throw new Error(`${Ee} for component "${t.tag}"`);return{consumerDomain:t.claimedConsumerDomain,consumerDomainVerified:!1}}function Yn(t){const e=st(t.consumerWindow);let n=t.consumerDomain,s=t.consumerDomainVerified;if(e&&(e!==n&&t.onConsumerDomainChange?.(n,e),n=e,s=!0),!s)throw new Error(`${Ee} for component "${t.tag}"`);return nt(t.allowedConsumerDomains,n,t.tag),{consumerDomain:n,consumerDomainVerified:s}}class Jn{constructor(e){this.options=e,this.messenger=new Je(this.options.uid,window,Q(),this.options.consumerDomain),this.bridge=new le(this.messenger)}messenger;bridge;destroyed=!1;initSent=!1;initError=null;deferredInitFlushScheduled=!1;registerPropsHandler(e){this.messenger.on(d.PROPS,(n,s)=>e.isConsumerSource(s)?e.applySerializedProps(n):{success:!1})}handleHostPropsAccess(){this.options.deferInit&&!this.initSent&&!this.destroyed&&this.scheduleDeferredInitFlush()}flushInit(){this.destroyed||this.initSent||(this.initSent=!0,this.sendInit())}getInitError(){return this.initError}updateTrustedConsumerDomain(e,n){!e||e===n||(this.messenger.removeTrustedDomain(e),this.messenger.addTrustedDomain(n))}async close(){await this.sendMessage(d.CLOSE,{})}async focus(){window.focus(),await this.sendMessage(d.FOCUS,{})}async resize(e){await this.sendMessage(d.RESIZE,e)}async show(){await this.sendMessage(d.SHOW,{})}async hide(){await this.sendMessage(d.HIDE,{})}async onError(e){await this.sendMessage(d.ERROR,{message:e.message,stack:e.stack})}async exportData(e){await this.sendMessage(d.EXPORT,e)}async consumerExport(e){await this.sendMessage(d.CONSUMER_EXPORT,e)}async getPeerInstances(e){return await this.messenger.send(this.options.consumerWindow,this.options.getConsumerDomain(),d.GET_SIBLINGS,{uid:this.options.uid,tag:this.options.tag,options:e})??[]}destroy(){this.destroyed||(this.destroyed=!0,this.deferredInitFlushScheduled=!1,this.messenger.destroy(),this.bridge.destroy())}scheduleDeferredInitFlush(){this.deferredInitFlushScheduled||this.destroyed||this.initSent||(this.deferredInitFlushScheduled=!0,queueMicrotask(()=>{this.deferredInitFlushScheduled=!1,this.flushInit()}))}async sendInit(){try{await this.sendMessage(d.INIT,{uid:this.options.uid,tag:this.options.tag})}catch(e){const n=e instanceof Error?e:new Error(String(e));this.initError=n,this.options.event.emit(g.ERROR,{type:"init_failed",message:`Failed to initialize host component: ${n.message}`,error:n}),console.error("Failed to send init message:",e)}}async sendMessage(e,n){await this.messenger.send(this.options.consumerWindow,this.options.getConsumerDomain(),e,n)}}class qn{event;uid;tag;consumerWindow;consumerDomain;consumerDomainVerified=!1;allowedConsumerDomains;transport;propsRuntime;destroyed=!1;constructor(e,n={},s,r=!1){this.uid=e.uid,this.tag=e.tag,this.event=new Ie,this.allowedConsumerDomains=s;let i=null,o=null;try{this.consumerWindow=Wn();const a=Vn({consumerWindow:this.consumerWindow,claimedConsumerDomain:e.consumerDomain,allowedConsumerDomains:this.allowedConsumerDomains,tag:this.tag});this.consumerDomain=a.consumerDomain,this.consumerDomainVerified=a.consumerDomainVerified,i=new Jn({uid:this.uid,tag:this.tag,event:this.event,consumerWindow:this.consumerWindow,consumerDomain:this.consumerDomain,getConsumerDomain:()=>this.consumerDomain,deferInit:r}),this.transport=i,o=new kn(n,{uid:this.uid,tag:this.tag,event:this.event,controls:{close:()=>this.transport.close(),focus:()=>this.transport.focus(),resize:c=>this.transport.resize(c),show:()=>this.transport.show(),hide:()=>this.transport.hide(),onError:c=>this.transport.onError(c),exportData:c=>this.transport.exportData(c),consumerExport:c=>this.transport.consumerExport(c),getPeerInstances:c=>this.transport.getPeerInstances(c)},getConsumerWindow:()=>this.consumerWindow,getConsumerDomain:()=>this.consumerDomain,isConsumerDomainVerified:()=>this.consumerDomainVerified,getMessenger:()=>this.transport.messenger,getBridge:()=>this.transport.bridge,onFirstHostPropsAccess:()=>this.transport.handleHostPropsAccess()}),this.propsRuntime=o,Object.defineProperties(this,{messenger:{configurable:!0,get:()=>this.transport.messenger},bridge:{configurable:!0,get:()=>this.transport.bridge},consumerProps:{configurable:!0,get:()=>this.propsRuntime.consumerProps},propsHandlers:{configurable:!0,get:()=>this.propsRuntime.propsHandlers}}),this.transport.registerPropsHandler({isConsumerSource:c=>c.window===this.consumerWindow,applySerializedProps:c=>this.propsRuntime.applySerializedProps(c)}),this.hostProps=this.propsRuntime.initializeHostProps(e),this.propsRuntime.exposeHostProps(),r||this.flushInit()}catch(a){throw o?.destroy(),i?.destroy(),this.event.removeAllListeners(),a}}get hostProps(){return this.propsRuntime.hostProps}set hostProps(e){this.propsRuntime.hostProps=e}flushInit(){this.transport.flushInit()}getProps(){return this.hostProps}getInitError(){return this.transport.getInitError()}applyHostConfiguration(e,n){n!==void 0&&(this.allowedConsumerDomains=n),e!==void 0&&this.propsRuntime.applyHostConfiguration(e)}assertAllowedConsumerDomain(e){const n=Yn({consumerWindow:this.consumerWindow,consumerDomain:this.consumerDomain,consumerDomainVerified:this.consumerDomainVerified,allowedConsumerDomains:e,tag:this.tag,onConsumerDomainChange:(s,r)=>{this.transport.updateTrustedConsumerDomain(s,r)}});this.consumerDomain=n.consumerDomain,this.consumerDomainVerified=n.consumerDomainVerified}destroy(){this.destroyed||(this.destroyed=!0,this.transport.destroy(),this.event.removeAllListeners(),this.propsRuntime.destroy())}}let E=null;function re(t,e,n={}){if(E){try{E.applyHostConfiguration(t,e),e&&E.assertAllowedConsumerDomain(e)}catch(r){throw Kn(),r}return n.deferInit||E.flushInit(),E}if(!ue())return null;const s=Rt();if(!s)return console.error("Failed to parse ForgeFrame payload from window.name"),null;try{E=new qn(s,t,e,n.deferInit??!1)}catch(r){if(r instanceof Error&&r.message===tt)return null;throw r}return E}function Kn(){E&&(E.destroy(),E=null),delete window.hostProps}function Xn(){R()&&re(void 0,void 0,{deferInit:!0})}const rt={create:_e,destroy:Qe,destroyByTag:Pe,destroyAll:et,isHost:Ke,isEmbedded:Xe,getHostProps:Ge,initHost:re,PROP_SERIALIZATION:T,CONTEXT:f,EVENT:g,PopupOpenError:me,VERSION:j,isStandardSchema:I,prop:m};function Gn(t,e){const n=Object.keys(t),s=Object.keys(e);if(n.length!==s.length)return!1;for(const r of n)if(!Object.prototype.hasOwnProperty.call(e,r)||!Object.is(t[r],e[r]))return!1;return!0}function it(t,e){const{React:n}=e,{createElement:s,useRef:r,useEffect:i,useState:o,forwardRef:a}=n,c=a(function(y,p){const{onRendered:O,onError:v,onClose:be,context:ot,className:at,style:ct,...Ce}=y,Oe=r(null),z=r(null),ie=r(null),ut=r(O),oe=r(v),lt=r(be),[dt,ht]=o(null);return i(()=>{ut.current=O,oe.current=v,lt.current=be},[O,v,be]),i(()=>{const b=Oe.current;if(!b)return;ht(null);const _=t(Ce);z.current=_,ie.current=Ce;const ae=_.event.once("rendered",()=>{ut.current?.()}),pt=_.event.once("close",()=>{lt.current?.()}),Re=_.event.on("error",ce=>{oe.current?.(ce)});return _.render(b,ot).catch(ce=>{z.current===_&&(ht(ce),oe.current?.(ce))}),()=>{_.close().catch(()=>{}),ae(),pt(),Re(),z.current=null,ie.current=null}},[ot]),i(()=>{const b=z.current;if(!b)return;const _=Ce,ae=ie.current;ae&&Gn(ae,_)||(ie.current=_,b.updateProps(_).catch(Re=>{z.current===b&&oe.current?.(Re)}))}),i(()=>{const b=Oe.current;if(typeof p=="function")return p(b),()=>{p(null)};if(p&&typeof p=="object")return p.current=b,()=>{p.current=null}},[p]),dt?s("div",{className:at,style:{color:"red",padding:"16px",...ct}},`Error: ${dt.message}`):s("div",{ref:Oe,className:at,style:{display:"inline-block",...ct}})}),u=`ForgeFrame(${t.name||"Component"})`;return c.displayName=u,c}function Zn(t){return function(n){return it(n,{React:t})}}Xn(),l.AnySchema=G,l.ArraySchema=H,l.BooleanSchema=J,l.CONTEXT=f,l.EVENT=g,l.EnumSchema=X,l.ForgeFrame=rt,l.FunctionSchema=q,l.LiteralSchema=K,l.NumberSchema=Y,l.ObjectSchema=U,l.PROP_SERIALIZATION=T,l.PopupOpenError=me,l.PropSchema=P,l.StringSchema=V,l.VERSION=j,l.create=_e,l.createReactComponent=it,l.default=rt,l.destroy=Qe,l.destroyAll=et,l.destroyByTag=Pe,l.getHostProps=Ge,l.initHost=re,l.isEmbedded=Xe,l.isHost=Ke,l.isStandardSchema=I,l.prop=m,l.withReactComponent=Zn,Object.defineProperties(l,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
package/dist/index.d.ts CHANGED
@@ -29,208 +29,8 @@
29
29
  * }).render('#container');
30
30
  * ```
31
31
  */
32
- import { create, destroy, destroyByTag, destroyAll, isHost, isEmbedded, getHostProps, initHost } from './core';
33
- import { PopupOpenError } from './render/popup';
34
- import { isStandardSchema } from './props/schema';
35
- /**
36
- * Main ForgeFrame API object.
37
- *
38
- * @remarks
39
- * Provides a zoid-compatible interface for creating and managing
40
- * cross-domain components. All methods and constants are accessible
41
- * through this object.
42
- *
43
- * @example
44
- * ```typescript
45
- * import ForgeFrame from 'forgeframe';
46
- *
47
- * const Component = ForgeFrame.create({
48
- * tag: 'my-component',
49
- * url: '/component.html',
50
- * });
51
- * ```
52
- *
53
- * @public
54
- */
55
- export declare const ForgeFrame: {
56
- /**
57
- * Create a new component definition.
58
- *
59
- * @remarks
60
- * This is the main entry point for defining components. Returns a
61
- * component factory function that can be called to create instances.
62
- *
63
- * @example
64
- * ```typescript
65
- * import ForgeFrame, { prop } from 'forgeframe';
66
- *
67
- * const MyComponent = ForgeFrame.create({
68
- * tag: 'my-component',
69
- * url: 'https://example.com/component',
70
- * props: {
71
- * email: prop.string().email(),
72
- * onLogin: prop.function<(user: { id: string }) => void>(),
73
- * },
74
- * });
75
- *
76
- * const instance = MyComponent({ email: 'user@example.com', onLogin: (user) => {} });
77
- * await instance.render('#container');
78
- * ```
79
- */
80
- readonly create: typeof create;
81
- /**
82
- * Destroy a single component instance.
83
- *
84
- * @param instance - The component instance to destroy
85
- */
86
- readonly destroy: typeof destroy;
87
- /**
88
- * Destroy all instances of a specific component by tag.
89
- *
90
- * @param tag - The component tag name
91
- */
92
- readonly destroyByTag: typeof destroyByTag;
93
- /**
94
- * Destroy all ForgeFrame component instances.
95
- */
96
- readonly destroyAll: typeof destroyAll;
97
- /**
98
- * Check if the current window is a host component context.
99
- *
100
- * @remarks
101
- * A "host" is the embedded iframe or popup window that receives props
102
- * from the consumer (the embedding app).
103
- *
104
- * @returns True if running inside a ForgeFrame iframe/popup
105
- */
106
- readonly isHost: typeof isHost;
107
- /**
108
- * Check if the current window is embedded by ForgeFrame.
109
- *
110
- * @remarks
111
- * This is an alias for {@link isHost} that uses more intuitive terminology.
112
- *
113
- * @returns True if running inside a ForgeFrame iframe/popup
114
- */
115
- readonly isEmbedded: typeof isEmbedded;
116
- /**
117
- * Get hostProps from the current host window.
118
- *
119
- * @remarks
120
- * Returns the props passed from the consumer plus built-in control methods.
121
- *
122
- * @returns The hostProps object if in host context, undefined otherwise
123
- */
124
- readonly getHostProps: typeof getHostProps;
125
- /**
126
- * Flush host initialization in embedded contexts.
127
- *
128
- * @remarks
129
- * Only required in host pages that access `window.hostProps` directly
130
- * without defining a component via `ForgeFrame.create(...)`.
131
- * When `create()` is used on the host side, init is flushed automatically.
132
- *
133
- * @returns The host component instance if running embedded, otherwise null
134
- */
135
- readonly initHost: typeof initHost;
136
- /**
137
- * Serialization strategy constants.
138
- * @see {@link PROP_SERIALIZATION}
139
- */
140
- readonly PROP_SERIALIZATION: {
141
- readonly JSON: "json";
142
- readonly BASE64: "base64";
143
- readonly DOTIFY: "dotify";
144
- };
145
- /**
146
- * Rendering context constants (IFRAME, POPUP).
147
- * @see {@link CONTEXT}
148
- */
149
- readonly CONTEXT: {
150
- readonly IFRAME: "iframe";
151
- readonly POPUP: "popup";
152
- };
153
- /**
154
- * Lifecycle event name constants.
155
- * @see {@link EVENT}
156
- */
157
- readonly EVENT: {
158
- readonly RENDER: "render";
159
- readonly RENDERED: "rendered";
160
- readonly PRERENDER: "prerender";
161
- readonly PRERENDERED: "prerendered";
162
- readonly DISPLAY: "display";
163
- readonly ERROR: "error";
164
- readonly CLOSE: "close";
165
- readonly DESTROY: "destroy";
166
- readonly PROPS: "props";
167
- readonly RESIZE: "resize";
168
- readonly FOCUS: "focus";
169
- };
170
- /**
171
- * Error thrown when popup window fails to open.
172
- */
173
- readonly PopupOpenError: typeof PopupOpenError;
174
- /**
175
- * Current library version.
176
- */
177
- readonly VERSION: string;
178
- /**
179
- * Check if a value is a Standard Schema (Zod, Valibot, ArkType, etc.)
180
- *
181
- * @param value - The value to check
182
- * @returns True if the value implements StandardSchemaV1
183
- *
184
- * @example
185
- * ```typescript
186
- * import { z } from 'zod';
187
- *
188
- * const schema = z.string();
189
- * if (ForgeFrame.isStandardSchema(schema)) {
190
- * // schema is StandardSchemaV1
191
- * }
192
- * ```
193
- */
194
- readonly isStandardSchema: typeof isStandardSchema;
195
- /**
196
- * Prop schema builders for defining component props.
197
- *
198
- * @remarks
199
- * Provides a fluent, Zod-like API for defining prop schemas with built-in
200
- * validation. All schemas implement StandardSchemaV1.
201
- *
202
- * @example
203
- * ```typescript
204
- * import ForgeFrame from 'forgeframe';
205
- *
206
- * const Component = ForgeFrame.create({
207
- * tag: 'my-component',
208
- * url: '/component',
209
- * props: {
210
- * name: ForgeFrame.prop.string(),
211
- * count: ForgeFrame.prop.number().default(0),
212
- * onSubmit: ForgeFrame.prop.function().optional(),
213
- * },
214
- * });
215
- * ```
216
- */
217
- readonly prop: {
218
- readonly string: () => import("./props").StringSchema;
219
- readonly number: () => import("./props").NumberSchema;
220
- readonly boolean: () => import("./props").BooleanSchema;
221
- readonly function: <T extends (...args: any[]) => any = (...args: any[]) => any>() => import("./props").FunctionSchema<T>;
222
- readonly array: <T = unknown>() => import("./props").ArraySchema<T>;
223
- readonly object: <T extends object = Record<string, unknown>>() => import("./props").ObjectSchema<T>;
224
- readonly literal: <T extends string | number | boolean>(value: T) => import("./props").LiteralSchema<T>;
225
- readonly enum: <T extends string | number>(values: readonly T[]) => import("./props").EnumSchema<T>;
226
- readonly any: () => import("./props").AnySchema;
227
- };
228
- };
229
- /**
230
- * Default export of the ForgeFrame API object.
231
- * @public
232
- */
233
- export default ForgeFrame;
32
+ export { ForgeFrame } from './forgeframe';
33
+ export { default } from './forgeframe';
234
34
  export { create, destroy, destroyByTag, destroyAll, isHost, isEmbedded, getHostProps, initHost, } from './core';
235
35
  export { PROP_SERIALIZATION, CONTEXT, EVENT, VERSION, } from './constants';
236
36
  export { PopupOpenError } from './render/popup';
@@ -1,37 +1,13 @@
1
1
  /**
2
2
  * @packageDocumentation
3
3
  *
4
- * Rendering utilities for ForgeFrame.
5
- *
6
- * This module provides functions for creating and managing iframes, popups,
7
- * and their associated templates. It handles the visual rendering layer
8
- * of ForgeFrame components.
4
+ * Internal source barrel for ForgeFrame rendering primitives.
9
5
  *
10
6
  * @remarks
11
- * The render module is divided into three main areas:
12
- * - **Iframe management** - Creating, destroying, and manipulating iframes
13
- * - **Popup management** - Opening, closing, and monitoring popup windows
14
- * - **Templates** - Default templates and styling utilities for containers
15
- *
16
- * @example
17
- * ```typescript
18
- * import { createIframe, openPopup, defaultContainerTemplate } from '@forgeframe/render';
19
- *
20
- * // Create an iframe
21
- * const iframe = createIframe({
22
- * url: 'https://example.com',
23
- * name: 'my-iframe',
24
- * container: document.body,
25
- * dimensions: { width: 400, height: 300 }
26
- * });
27
- *
28
- * // Open a popup
29
- * const popup = openPopup({
30
- * url: 'https://example.com',
31
- * name: 'my-popup',
32
- * dimensions: { width: 600, height: 400 }
33
- * });
34
- * ```
7
+ * This file groups iframe, popup, and template helpers for internal source
8
+ * organization. The published package does not expose a `forgeframe/render`
9
+ * subpath, so consumers should treat this barrel as internal implementation
10
+ * structure.
35
11
  */
36
12
  export { createIframe, createPrerenderIframe, destroyIframe, resizeIframe, showIframe, hideIframe, focusIframe, getIframeContentDimensions, type IframeOptions, } from './iframe';
37
13
  export { openPopup, closePopup, focusPopup, isPopupBlocked, watchPopupClose, resizePopup, PopupOpenError, type PopupOptions, } from './popup';
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Internal domain-pattern helpers shared by ForgeFrame trust and origin checks.
4
+ *
5
+ * @remarks
6
+ * Centralizes wildcard compilation and stateless `RegExp` evaluation so
7
+ * window helpers and the messenger preserve identical domain-matching behavior.
8
+ */
9
+ /**
10
+ * Compiles a wildcard domain pattern into an anchored `RegExp`.
11
+ *
12
+ * @param pattern - Domain pattern that may contain `*` wildcards.
13
+ * @returns Compiled `RegExp`, or `null` when the pattern has no wildcards.
14
+ *
15
+ * @remarks
16
+ * Compiled patterns are cached with a bounded, oldest-entry eviction policy to
17
+ * preserve the prior helper-level wildcard cache behavior.
18
+ *
19
+ * @internal
20
+ */
21
+ export declare function compileWildcardDomainPattern(pattern: string): RegExp | null;
22
+ /**
23
+ * Tests a domain `RegExp` without mutating `lastIndex` on global or sticky patterns.
24
+ *
25
+ * @param pattern - Pattern to test.
26
+ * @param value - Domain string to match.
27
+ * @returns `true` when the pattern matches the provided value.
28
+ *
29
+ * @remarks
30
+ * Global and sticky flags are stripped from a cloned `RegExp` before testing so
31
+ * repeated trust checks behave consistently regardless of prior matches.
32
+ *
33
+ * @internal
34
+ */
35
+ export declare function testDomainRegExpStateless(pattern: RegExp, value: string): boolean;
@@ -56,7 +56,7 @@ export declare function isSameDomain(win: Window, reference?: Window): boolean;
56
56
  * - `"*"` matches any domain
57
57
  * - String patterns without wildcards require exact match
58
58
  * - String patterns with `*` use wildcard matching (for example, `'https://*.example.com'`)
59
- * - RegExp patterns use `.test()` method
59
+ * - RegExp patterns are evaluated statelessly so global/sticky flags do not leak `lastIndex` across calls
60
60
  * - Array patterns return `true` if any element matches (OR logic)
61
61
  *
62
62
  * @example