forgeframe 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -4
- package/dist/communication/messenger.d.ts +6 -0
- package/dist/core/component.d.ts +5 -0
- package/dist/core/consumer.d.ts +29 -0
- package/dist/core/host.d.ts +43 -3
- package/dist/forgeframe.js +787 -628
- package/dist/forgeframe.umd.cjs +2 -2
- package/dist/index.d.ts +13 -2
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
package/dist/forgeframe.umd.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
(function(u,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(u=typeof globalThis<"u"?globalThis:u||self,p(u.ForgeFrame={}))})(this,(function(u){"use strict";const p={IFRAME:"iframe",POPUP:"popup"},m={RENDER:"render",RENDERED:"rendered",PRERENDER:"prerender",PRERENDERED:"prerendered",DISPLAY:"display",ERROR:"error",CLOSE:"close",DESTROY:"destroy",PROPS:"props",RESIZE:"resize",FOCUS:"focus"},O={JSON:"json",BASE64:"base64",DOTIFY:"dotify"},D={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"},N="__forgeframe__",j="0.0.1";class re{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=i=>(this.off(e,s),n(i));return this.on(e,s)}emit(e,n){const s=this.listeners.get(e);if(s)for(const i of s)try{const r=i(n);r&&typeof r=="object"&&"catch"in r&&typeof r.catch=="function"&&r.catch(o=>{console.error(`Error in async event handler for "${e}":`,o)})}catch(r){console.error(`Error in event handler for "${e}":`,r)}}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 $e(){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)}class Le{tasks=[];cleaned=!1;register(e){if(this.cleaned){try{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 oe(){let t,e;return{promise:new Promise((s,i)=>{t=s,e=i}),resolve:t,reject:e}}function Ae(t,e,n="Operation timed out"){return new Promise((s,i)=>{const r=setTimeout(()=>{i(new Error(`${n} (${e}ms)`))},e);t.then(o=>{clearTimeout(r),s(o)}).catch(o=>{clearTimeout(r),i(o)})})}const V="forgeframe:";function J(t){return V+JSON.stringify(t)}function He(t){if(typeof t!="string"||!t.startsWith(V))return null;try{const e=t.slice(V.length),n=JSON.parse(e);return!n.id||!n.type||!n.name||!n.source?null:n}catch{return null}}function ae(t,e,n,s){return{id:t,type:D.REQUEST,name:e,data:n,source:s}}function Me(t,e,n,s){return{id:t,type:D.RESPONSE,name:"response",data:e,source:n,error:s?{message:s.message,stack:s.stack}:void 0}}class ce{constructor(e,n=window,s=window.location.origin,i){this.uid=e,this.win=n,this.domain=s,this.allowedOrigins.add(s),i&&this.addTrustedDomain(i),this.setupListener()}pending=new Map;handlers=new Map;listener=null;destroyed=!1;allowedOrigins=new Set;allowedOriginPatterns=[];addTrustedDomain(e){if(Array.isArray(e))for(const n of e)this.allowedOrigins.add(n);else e instanceof RegExp?this.allowedOriginPatterns.push(e):this.allowedOrigins.add(e)}isOriginTrusted(e){if(this.allowedOrigins.has(e))return!0;for(const n of this.allowedOriginPatterns)if(n.test(e))return!0;return!1}async send(e,n,s,i,r=1e4){if(this.destroyed)throw new Error("Messenger has been destroyed");const o=B(),a=ae(o,s,i,{uid:this.uid,domain:this.domain}),c=oe(),l=setTimeout(()=>{this.pending.delete(o),c.reject(new Error(`Message "${s}" timed out after ${r}ms`))},r);this.pending.set(o,{deferred:c,timeout:l});try{e.postMessage(J(a),n)}catch(d){throw this.pending.delete(o),clearTimeout(l),d}return c.promise}post(e,n,s,i){if(this.destroyed)throw new Error("Messenger has been destroyed");const r=B(),o=ae(r,s,i,{uid:this.uid,domain:this.domain});e.postMessage(J(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=He(e.data);n&&this.handleMessage(n,e.source,e.origin)},this.win.addEventListener("message",this.listener)}async handleMessage(e,n,s){if(e.type===D.RESPONSE){const i=this.pending.get(e.id);if(i)if(this.pending.delete(e.id),clearTimeout(i.timeout),e.error){const r=new Error(e.error.message);r.stack=e.error.stack,i.deferred.reject(r)}else i.deferred.resolve(e.data);return}if(e.type===D.REQUEST){const i=this.handlers.get(e.name);if(!i)return;let r,o;try{r=await i(e.data,e.source)}catch(c){o=c instanceof Error?c:new Error(String(c))}const a=Me(e.id,r,{uid:this.uid,domain:this.domain},o);try{n.postMessage(J(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 le=500;class q{constructor(e){this.messenger=e,this.setupCallHandler()}localFunctions=new Map;remoteFunctions=new Map;currentBatchIds=new Set;serialize(e,n){if(this.localFunctions.size>=le){const i=this.localFunctions.keys().next().value;i&&this.localFunctions.delete(i)}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 i=`${e.__id__}`,r=this.remoteFunctions.get(i);if(r)return r;if(this.remoteFunctions.size>=le){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(i,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 X(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");return n.add(t),t.map(s=>X(s,e,n))}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);const s={};for(const[i,r]of Object.entries(t))s[i]=X(r,e,n);return s}return t}function Z(t,e,n,s,i=new WeakSet){if(q.isFunctionRef(t))return e.deserialize(t,n,s);if(Array.isArray(t)){if(i.has(t))throw new Error("Circular reference detected in serialized props");return i.add(t),t.map(r=>Z(r,e,n,s,i))}if(typeof t=="object"&&t!==null){if(i.has(t))throw new Error("Circular reference detected in serialized props");i.add(t);const r={};for(const[o,a]of Object.entries(t))r[o]=Z(a,e,n,s,i);return r}return t}function Y(t=window){try{return t.location.origin}catch{return""}}function ue(t,e=window){try{return t.location.origin===e.location.origin}catch{return!1}}function he(t,e){return typeof t=="string"?t==="*"?!0:t===e:t instanceof RegExp?t.test(e):Array.isArray(t)?t.some(n=>he(n,e)):!1}function de(t){if(!t)return!0;try{return t.closed}catch{return!0}}function We(t=window){try{return t.opener}catch{return null}}function ze(t=window){try{const e=t.parent;return e&&e!==t?e:null}catch{return null}}function Ue(t=window){try{return t.parent!==t}catch{return!0}}function je(t=window){try{return t.opener!==null&&t.opener!==void 0}catch{return!1}}const fe=32*1024;function Be(t){const e=Ve(t);return`${N}${e}`}function pe(t){if(!t||!t.startsWith(N))return null;const e=t.slice(N.length);return Je(e)}function G(t=window){try{return t.name.startsWith(N)}catch{return!1}}function K(t,e=window){return pe(e.name)?.tag===t}function Ve(t){try{const e=JSON.stringify(t),n=btoa(encodeURIComponent(e)),s=new Blob([n]).size;if(s>fe)throw new Error(`Payload size (${Math.round(s/1024)}KB) exceeds maximum allowed size (${fe/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 Je(t){try{const e=decodeURIComponent(atob(t));return JSON.parse(e)}catch{return null}}function qe(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 Xe(t=window){return pe(t.name)}const me=100,y=new Map;function Ze(){const t=[];for(const[e,n]of y.entries())de(n)&&t.push(e);for(const e of t)y.delete(e)}function Ye(t,e){if(y.size>=me&&Ze(),y.size>=me){const n=y.keys().next().value;n&&y.delete(n)}y.set(t,e)}function Ge(t){y.delete(t)}class g{_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 T extends g{_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&&!this._pattern.test(n)?{issues:[{message:this._patternMessage||`String must match pattern ${this._pattern}`}]}:{value:n}}_clone(){const e=new T;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 F extends g{_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 F;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 k extends g{_validate(e){return typeof e!="boolean"?{issues:[{message:`Expected boolean, got ${typeof e}`}]}:{value:e}}_clone(){const e=new k;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class $ extends g{_validate(e){return typeof e!="function"?{issues:[{message:`Expected function, got ${typeof e}`}]}:{value:e}}_clone(){const e=new $;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class C extends g{_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 i=this._itemSchema["~standard"].validate(e[s]);if(i instanceof Promise)throw new Error("Async schema validation is not supported. Use synchronous schemas.");if(i.issues)return{issues:i.issues.map(r=>({...r,path:[s,...r.path||[]]}))};n.push(i.value)}return{value:n}}return{value:e}}_clone(){const e=new C;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 C;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 v extends g{_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 i=new Set(Object.keys(this._shape));for(const r of Object.keys(n))if(!i.has(r))return{issues:[{message:`Unknown key: ${r}`,path:[r]}]}}for(const[i,r]of Object.entries(this._shape)){const o=r["~standard"].validate(n[i]);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:[i,...a.path||[]]}))};s[i]=o.value}if(!this._strict)for(const i of Object.keys(n))i in this._shape||(s[i]=n[i]);return{value:s}}return{value:e}}_clone(){const e=new v;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 v;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 L extends g{_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 L(this._value);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class A extends g{_values;constructor(e){super(),this._values=e}_validate(e){return this._values.includes(e)?{value:e}:{issues:[{message:`Expected one of [${this._values.map(n=>JSON.stringify(n)).join(", ")}], got ${JSON.stringify(e)}`}]}}_clone(){const e=new A(this._values);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class H extends g{constructor(){super(),this._nullable=!0}_validate(e){return{value:e}}_clone(){const e=new H;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}const f={string:()=>new T,number:()=>new F,boolean:()=>new k,function:()=>new $,array:()=>new C,object:()=>new v,literal:t=>new L(t),enum:t=>new A(t),any:()=>new H},P={uid:{schema:f.string().optional(),sendToHost:!0},tag:{schema:f.string().optional(),sendToHost:!0},dimensions:{schema:f.object().default(()=>({width:"100%",height:"100%"})),sendToHost:!1},timeout:{schema:f.number().default(1e4),sendToHost:!1},cspNonce:{schema:f.string().optional(),sendToHost:!0},onDisplay:{schema:f.function().optional(),sendToHost:!1},onRendered:{schema:f.function().optional(),sendToHost:!1},onRender:{schema:f.function().optional(),sendToHost:!1},onPrerendered:{schema:f.function().optional(),sendToHost:!1},onPrerender:{schema:f.function().optional(),sendToHost:!1},onClose:{schema:f.function().optional(),sendToHost:!1},onDestroy:{schema:f.function().optional(),sendToHost:!1},onResize:{schema:f.function().optional(),sendToHost:!1},onFocus:{schema:f.function().optional(),sendToHost:!1},onError:{schema:f.function().optional(),sendToHost:!1},onProps:{schema:f.function().optional(),sendToHost:!1}};function _(t){return typeof t=="object"&&t!==null&&"~standard"in t&&typeof t["~standard"]=="object"&&t["~standard"]!==null&&t["~standard"].version===1&&typeof t["~standard"].validate=="function"}function Ke(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 i=s.issues.map(r=>`${Qe(r.path,n)}: ${r.message}`);throw new Error(`Validation failed: ${i.join("; ")}`)}return s.value}function Qe(t,e){if(!t||t.length===0)return e;const n=t.map(s=>typeof s=="object"&&s!==null&&"key"in s?String(s.key):String(s));return`${e}.${n.join(".")}`}function ge(t,e,n){const s={...P,...e},i={};for(const[r,o]of Object.entries(s)){const c=_(o)?{schema:o}:o;let l;const d=c.alias,w=r in t,E=d&&d in t;if(w)l=t[r];else if(E)l=t[d];else if(c.value)l=c.value(n);else if(c.default!==void 0)l=typeof c.default=="function"?c.default(n):c.default;else if(c.schema&&_(c.schema)){const S=c.schema["~standard"].validate(void 0);!(S instanceof Promise)&&!S.issues&&(l=S.value)}l!==void 0&&c.decorate&&(l=c.decorate({value:l,props:i})),i[r]=l}return i}function et(t,e){const n={...P,...e};for(const[s,i]of Object.entries(n)){const r=_(i),o=r?{schema:i}:i;let a=t[s];if(o.required&&a===void 0)throw new Error(`Prop "${s}" is required but was not provided`);if(o.schema&&_(o.schema))(a!==void 0||r)&&(a=Ke(o.schema,a,s),t[s]=a);else if(a===void 0)continue;o.validate&&o.validate({value:a,props:t})}}function ye(t,e,n,s){const i={...P,...e},r={};for(const[o,a]of Object.entries(i)){const l=_(a)?{schema:a}:a,d=t[o];if(l.sendToHost===!1||l.sameDomain&&!s)continue;if(l.trustedDomains){const E=l.trustedDomains;if(!he(E,n))continue}let w=d;l.hostDecorate&&d!==void 0&&(w=l.hostDecorate({value:d,props:t})),r[o]=w}return r}function tt(t,e){const n=new URLSearchParams,s={...P,...e};for(const[i,r]of Object.entries(s)){const a=_(r)?{schema:r}:r,c=t[i];if(c===void 0||typeof c=="function"||!a.queryParam)continue;const l=typeof a.queryParam=="string"?a.queryParam:i;let d;typeof a.queryParam=="function"?d=a.queryParam({value:c}):typeof c=="object"?d=JSON.stringify(c):d=String(c),n.set(l,d)}return n}function _e(t,e=""){const n=[];for(const[s,i]of Object.entries(t)){const r=e?`${e}.${s}`:s;if(i!==null&&typeof i=="object"&&!Array.isArray(i))n.push(_e(i,r));else{const o=encodeURIComponent(JSON.stringify(i));n.push(`${r}=${o}`)}}return n.filter(Boolean).join("&")}function nt(t){const e={};if(!t)return e;const n=t.split("&");for(const s of n){const[i,r]=s.split("=");if(!i||r===void 0)continue;let o;try{o=JSON.parse(decodeURIComponent(r))}catch{o=decodeURIComponent(r)}const a=i.split(".");let c=e;for(let l=0;l<a.length-1;l++){const d=a[l];(!(d in c)||typeof c[d]!="object")&&(c[d]={}),c=c[d]}c[a[a.length-1]]=o}return e}function st(t){return typeof t=="object"&&t!==null&&t.__type__==="dotify"&&typeof t.__value__=="string"}function we(t,e,n){const s={...P,...e},i={};for(const[r,o]of Object.entries(t)){if(o===void 0)continue;const a=s[r];i[r]=it(o,a,n)}return i}function it(t,e,n){if(typeof t=="function")return n.serialize(t);const s=e?.serialization??O.JSON;if(s===O.BASE64&&typeof t=="object"){const i=JSON.stringify(t);return{__type__:"base64",__value__:btoa(encodeURIComponent(i))}}return s===O.DOTIFY&&typeof t=="object"&&t!==null&&!Array.isArray(t)?{__type__:"dotify",__value__:_e(t)}:X(t,n)}function Ee(t,e,n,s,i,r){const o={...P,...e},a={};for(const[c,l]of Object.entries(t)){const d=o[c];a[c]=rt(l,d,n,s,i,r)}return a}function rt(t,e,n,s,i,r){if(ot(t))try{const o=decodeURIComponent(atob(t.__value__));return JSON.parse(o)}catch{return t}if(st(t))try{return nt(t.__value__)}catch{return t}return Z(t,s,i,r)}function ot(t){return typeof t=="object"&&t!==null&&t.__type__==="base64"&&typeof t.__value__=="string"}function R(t,e="100%"){return t===void 0?e:typeof t=="number"?`${t}px`:t}function M(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 at(t){try{t.src="about:blank",t.parentNode?.removeChild(t)}catch{}}function ct(t,e){ht(t,e)}function lt(t){t.style.display="",t.style.visibility="visible"}function be(t){t.style.display="none",t.style.visibility="hidden"}function ut(t){try{t.focus(),t.contentWindow?.focus()}catch{}}function ht(t,e){e.width!==void 0&&(t.style.width=R(e.width)),e.height!==void 0&&(t.style.height=R(e.height))}class Q extends Error{constructor(e="Popup blocked by browser"){super(e),this.name="PopupOpenError"}}function dt(t){const{url:e,name:n,dimensions:s}=t,i=M(s.width,500),r=M(s.height,500),o=Math.floor(window.screenX+(window.outerWidth-i)/2),a=Math.floor(window.screenY+(window.outerHeight-r)/2),c=[`width=${i}`,`height=${r}`,`left=${o}`,`top=${a}`,"menubar=no","toolbar=no","location=yes","status=no","resizable=yes","scrollbars=yes"].join(","),l=window.open(e,n,c);if(!l||mt(l))throw new Q;return l}function ft(t){try{t.closed||t.close()}catch{}}function pt(t){try{t.closed||t.focus()}catch{}}function mt(t){if(!t)return!0;try{return!!(t.closed||t.innerHeight===0||t.innerWidth===0)}catch{return!0}}function gt(t,e,n={}){const{initialInterval:s=100,maxInterval:i=2e3,multiplier:r=1.5}=n;let o=s,a,c=!1;const l=()=>{try{e()}catch(w){console.error("Error in popup close callback:",w)}},d=()=>{if(!c){try{if(t.closed){l();return}}catch{l();return}o=Math.min(o*r,i),a=setTimeout(d,o)}};return a=setTimeout(d,o),()=>{c=!0,clearTimeout(a)}}function yt(t,e){try{const n=M(e.width,t.outerWidth),s=M(e.height,t.outerHeight);t.resizeTo(n,s)}catch{}}function _t(t){const{doc:e,dimensions:n,uid:s,tag:i}=t,r=e.createElement("div");return r.id=`forgeframe-container-${s}`,r.setAttribute("data-forgeframe-tag",i),Object.assign(r.style,{display:"inline-block",position:"relative",width:R(n.width),height:R(n.height),overflow:"hidden"}),r}function wt(t){const{doc:e,dimensions:n,cspNonce:s}=t,i=e.createElement("div");Object.assign(i.style,{display:"flex",alignItems:"center",justifyContent:"center",width:R(n.width),height:R(n.height),backgroundColor:"#f5f5f5",position:"absolute",top:"0",left:"0",zIndex:"100"});const r=e.createElement("div");Object.assign(r.style,{width:"40px",height:"40px",border:"3px solid #e0e0e0",borderTopColor:"#3498db",borderRadius:"50%",animation:"forgeframe-spin 1s linear infinite"});const o=e.createElement("style");return s&&o.setAttribute("nonce",s),o.textContent=`
|
|
1
|
+
(function(h,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(h=typeof globalThis<"u"?globalThis:h||self,p(h.ForgeFrame={}))})(this,(function(h){"use strict";const p={IFRAME:"iframe",POPUP:"popup"},m={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"},F={REQUEST:"request",RESPONSE:"response"},u={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"},$="__forgeframe__",q="0.0.1";class le{listeners=new Map;on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>this.off(e,t)}once(e,t){const n=i=>(this.off(e,n),t(i));return this.on(e,n)}emit(e,t){const n=this.listeners.get(e);if(n)for(const i of n)try{const r=i(t);r&&typeof r=="object"&&"catch"in r&&typeof r.catch=="function"&&r.catch(o=>{console.error(`Error in async event handler for "${e}":`,o)})}catch(r){console.error(`Error in event handler for "${e}":`,r)}}off(e,t){if(!t){this.listeners.delete(e);return}const n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&this.listeners.delete(e))}removeAllListeners(){this.listeners.clear()}listenerCount(e){return this.listeners.get(e)?.size??0}}function He(){const s=Date.now().toString(36),e=Math.random().toString(36).slice(2,11);return`${s}_${e}`}function J(){return Math.random().toString(36).slice(2,11)}class Ae{tasks=[];cleaned=!1;register(e){if(this.cleaned){try{e()}catch(t){console.error("Error in cleanup task:",t)}return}this.tasks.push(e)}async cleanup(){if(this.cleaned)return;this.cleaned=!0;const e=this.tasks.reverse();this.tasks=[];for(const t of e)try{await t()}catch(n){console.error("Error in cleanup task:",n)}}isCleaned(){return this.cleaned}reset(){this.tasks=[],this.cleaned=!1}}function he(){let s,e;return{promise:new Promise((n,i)=>{s=n,e=i}),resolve:s,reject:e}}function Ue(s,e,t="Operation timed out"){return new Promise((n,i)=>{const r=setTimeout(()=>{i(new Error(`${t} (${e}ms)`))},e);s.then(o=>{clearTimeout(r),n(o)}).catch(o=>{clearTimeout(r),i(o)})})}const X="forgeframe:";function K(s){return X+JSON.stringify(s)}function Me(s){if(typeof s!="string"||!s.startsWith(X))return null;try{const e=s.slice(X.length),t=JSON.parse(e);return!t.id||!t.type||!t.name||!t.source?null:t}catch{return null}}function ue(s,e,t,n){return{id:s,type:F.REQUEST,name:e,data:t,source:n}}function We(s,e,t,n){return{id:s,type:F.RESPONSE,name:"response",data:e,source:t,error:n?{message:n.message,stack:n.stack}:void 0}}class de{constructor(e,t=window,n=window.location.origin,i){this.uid=e,this.win=t,this.domain=n,this.allowedOrigins.add(n),i&&this.addTrustedDomain(i),this.setupListener()}pending=new Map;handlers=new Map;listener=null;destroyed=!1;allowedOrigins=new Set;allowedOriginPatterns=[];addTrustedDomain(e){if(Array.isArray(e))for(const t of e)this.allowedOrigins.add(t);else e instanceof RegExp?this.allowedOriginPatterns.push(e):this.allowedOrigins.add(e)}removeTrustedDomain(e){if(Array.isArray(e))for(const t of e)this.allowedOrigins.delete(t);else e instanceof RegExp?this.allowedOriginPatterns=this.allowedOriginPatterns.filter(t=>t!==e):this.allowedOrigins.delete(e)}isOriginTrusted(e){if(this.allowedOrigins.has(e))return!0;for(const t of this.allowedOriginPatterns)if(t.test(e))return!0;return!1}async send(e,t,n,i,r=1e4){if(this.destroyed)throw new Error("Messenger has been destroyed");const o=J(),a=ue(o,n,i,{uid:this.uid,domain:this.domain}),c=he(),l=setTimeout(()=>{this.pending.delete(o),c.reject(new Error(`Message "${n}" timed out after ${r}ms`))},r);this.pending.set(o,{deferred:c,timeout:l});try{e.postMessage(K(a),t)}catch(d){throw this.pending.delete(o),clearTimeout(l),d}return c.promise}post(e,t,n,i){if(this.destroyed)throw new Error("Messenger has been destroyed");const r=J(),o=ue(r,n,i,{uid:this.uid,domain:this.domain});e.postMessage(K(o),t)}on(e,t){return this.handlers.set(e,t),()=>this.handlers.delete(e)}setupListener(){this.listener=e=>{if(e.source===this.win||!this.isOriginTrusted(e.origin))return;const t=Me(e.data);t&&this.handleMessage(t,e.source,e.origin)},this.win.addEventListener("message",this.listener)}async handleMessage(e,t,n){if(e.type===F.RESPONSE){const i=this.pending.get(e.id);if(i)if(this.pending.delete(e.id),clearTimeout(i.timeout),e.error){const r=new Error(e.error.message);r.stack=e.error.stack,i.deferred.reject(r)}else i.deferred.resolve(e.data);return}if(e.type===F.REQUEST){const i=this.handlers.get(e.name);if(!i)return;let r,o;try{r=await i(e.data,e.source)}catch(c){o=c instanceof Error?c:new Error(String(c))}const a=We(e.id,r,{uid:this.uid,domain:this.domain},o);try{t.postMessage(K(a),n)}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 fe=500;class Z{constructor(e){this.messenger=e,this.setupCallHandler()}localFunctions=new Map;remoteFunctions=new Map;currentBatchIds=new Set;serialize(e,t){if(this.localFunctions.size>=fe){const i=this.localFunctions.keys().next().value;i&&this.localFunctions.delete(i)}const n=J();return this.localFunctions.set(n,e),this.currentBatchIds.add(n),{__type__:"function",__id__:n,__name__:t||e.name||"anonymous"}}deserialize(e,t,n){const i=`${e.__id__}`,r=this.remoteFunctions.get(i);if(r)return r;if(this.remoteFunctions.size>=fe){const a=this.remoteFunctions.keys().next().value;a&&this.remoteFunctions.delete(a)}const o=async(...a)=>this.messenger.send(t,n,u.CALL,{id:e.__id__,args:a});return Object.defineProperty(o,"name",{value:e.__name__,configurable:!0}),this.remoteFunctions.set(i,o),o}static isFunctionRef(e){return typeof e=="object"&&e!==null&&e.__type__==="function"&&typeof e.__id__=="string"}setupCallHandler(){this.messenger.on(u.CALL,async({id:e,args:t})=>{const n=this.localFunctions.get(e);if(!n)throw new Error(`Function with id "${e}" not found`);return n(...t)})}removeLocal(e){this.localFunctions.delete(e)}startBatch(){this.currentBatchIds.clear()}finishBatch(e=!1){if(e){this.currentBatchIds.clear();return}for(const t of this.localFunctions.keys())this.currentBatchIds.has(t)||this.localFunctions.delete(t);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 Y(s,e,t=new WeakSet){if(typeof s=="function")return e.serialize(s);if(Array.isArray(s)){if(t.has(s))throw new Error("Circular reference detected in props - arrays cannot contain circular references");return t.add(s),s.map(n=>Y(n,e,t))}if(typeof s=="object"&&s!==null){if(t.has(s))throw new Error("Circular reference detected in props - objects cannot contain circular references");t.add(s);const n={};for(const[i,r]of Object.entries(s))n[i]=Y(r,e,t);return n}return s}function G(s,e,t,n,i=new WeakSet){if(Z.isFunctionRef(s))return e.deserialize(s,t,n);if(Array.isArray(s)){if(i.has(s))throw new Error("Circular reference detected in serialized props");return i.add(s),s.map(r=>G(r,e,t,n,i))}if(typeof s=="object"&&s!==null){if(i.has(s))throw new Error("Circular reference detected in serialized props");i.add(s);const r={};for(const[o,a]of Object.entries(s))r[o]=G(a,e,t,n,i);return r}return s}function Q(s=window){try{return s.location.origin}catch{return""}}function pe(s,e=window){try{return s.location.origin===e.location.origin}catch{return!1}}function k(s,e){return typeof s=="string"?s==="*"?!0:s===e:s instanceof RegExp?s.test(e):Array.isArray(s)?s.some(t=>k(t,e)):!1}function me(s){if(!s)return!0;try{return s.closed}catch{return!0}}function ze(s=window){try{return s.opener}catch{return null}}function je(s=window){try{const e=s.parent;return e&&e!==s?e:null}catch{return null}}function Be(s=window){try{return s.parent!==s}catch{return!0}}function Ve(s=window){try{return s.opener!==null&&s.opener!==void 0}catch{return!1}}const ge=32*1024;function qe(s){const e=Je(s);return`${$}${e}`}function ye(s){if(!s||!s.startsWith($))return null;const e=s.slice($.length);return Xe(e)}function ee(s=window){try{return s.name.startsWith($)}catch{return!1}}function te(s,e=window){return ye(e.name)?.tag===s}function Je(s){try{const e=JSON.stringify(s),t=btoa(encodeURIComponent(e)),n=new Blob([t]).size;if(n>ge)throw new Error(`Payload size (${Math.round(n/1024)}KB) exceeds maximum allowed size (${ge/1024}KB). Consider reducing the amount of data passed via props.`);return t}catch(e){throw e instanceof Error&&e.message.includes("Payload size")?e:new Error(`Failed to encode payload: ${e}`)}}function Xe(s){try{const e=decodeURIComponent(atob(s));return JSON.parse(e)}catch{return null}}function Ke(s){return{uid:s.uid,tag:s.tag,version:q,context:s.context,consumerDomain:s.consumerDomain,props:s.props,exports:s.exports,children:s.children}}function Ze(s=window){return ye(s.name)}const we=100,_=new Map;function Ye(){const s=[];for(const[e,t]of _.entries())me(t)&&s.push(e);for(const e of s)_.delete(e)}function Ge(s,e){if(_.size>=we&&Ye(),_.size>=we){const t=_.keys().next().value;t&&_.delete(t)}_.set(s,e)}function Qe(s){_.delete(s)}class g{_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 t=this._clone();return t._default=e,t}}class L extends g{_minLength;_maxLength;_pattern;_patternMessage;_trim=!1;_validate(e){if(typeof e!="string")return{issues:[{message:`Expected string, got ${typeof e}`}]};const t=this._trim?e.trim():e;return this._minLength!==void 0&&t.length<this._minLength?{issues:[{message:`String must be at least ${this._minLength} characters`}]}:this._maxLength!==void 0&&t.length>this._maxLength?{issues:[{message:`String must be at most ${this._maxLength} characters`}]}:this._pattern&&!this._pattern.test(t)?{issues:[{message:this._patternMessage||`String must match pattern ${this._pattern}`}]}:{value:t}}_clone(){const e=new L;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 t=this._clone();return t._minLength=e,t}max(e){const t=this._clone();return t._maxLength=e,t}length(e){const t=this._clone();return t._minLength=e,t._maxLength=e,t}pattern(e,t){const n=this._clone();return n._pattern=e,n._patternMessage=t,n}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 H extends g{_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 H;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 t=this._clone();return t._min=e,t}max(e){const t=this._clone();return t._max=e,t}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 A extends g{_validate(e){return typeof e!="boolean"?{issues:[{message:`Expected boolean, got ${typeof e}`}]}:{value:e}}_clone(){const e=new A;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class U extends g{_validate(e){return typeof e!="function"?{issues:[{message:`Expected function, got ${typeof e}`}]}:{value:e}}_clone(){const e=new U;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class C extends g{_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 t=[];for(let n=0;n<e.length;n++){const i=this._itemSchema["~standard"].validate(e[n]);if(i instanceof Promise)throw new Error("Async schema validation is not supported. Use synchronous schemas.");if(i.issues)return{issues:i.issues.map(r=>({...r,path:[n,...r.path||[]]}))};t.push(i.value)}return{value:t}}return{value:e}}_clone(){const e=new C;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 t=new C;return t._optional=this._optional,t._nullable=this._nullable,t._itemSchema=e,t._minLength=this._minLength,t._maxLength=this._maxLength,t}min(e){const t=this._clone();return t._minLength=e,t}max(e){const t=this._clone();return t._maxLength=e,t}nonempty(){return this.min(1)}}class I extends g{_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 t=e,n={};if(this._shape){if(this._strict){const i=new Set(Object.keys(this._shape));for(const r of Object.keys(t))if(!i.has(r))return{issues:[{message:`Unknown key: ${r}`,path:[r]}]}}for(const[i,r]of Object.entries(this._shape)){const o=r["~standard"].validate(t[i]);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:[i,...a.path||[]]}))};n[i]=o.value}if(!this._strict)for(const i of Object.keys(t))i in this._shape||(n[i]=t[i]);return{value:n}}return{value:e}}_clone(){const e=new I;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 t=new I;return t._optional=this._optional,t._nullable=this._nullable,t._shape=e,t._strict=this._strict,t}strict(){const e=this._clone();return e._strict=!0,e}}class M extends g{_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 M(this._value);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class W extends g{_values;constructor(e){super(),this._values=e}_validate(e){return this._values.includes(e)?{value:e}:{issues:[{message:`Expected one of [${this._values.map(t=>JSON.stringify(t)).join(", ")}], got ${JSON.stringify(e)}`}]}}_clone(){const e=new W(this._values);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class z extends g{constructor(){super(),this._nullable=!0}_validate(e){return{value:e}}_clone(){const e=new z;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}const f={string:()=>new L,number:()=>new H,boolean:()=>new A,function:()=>new U,array:()=>new C,object:()=>new I,literal:s=>new M(s),enum:s=>new W(s),any:()=>new z},O={uid:{schema:f.string().optional(),sendToHost:!0},tag:{schema:f.string().optional(),sendToHost:!0},dimensions:{schema:f.object().default(()=>({width:"100%",height:"100%"})),sendToHost:!1},timeout:{schema:f.number().default(1e4),sendToHost:!1},cspNonce:{schema:f.string().optional(),sendToHost:!0},onDisplay:{schema:f.function().optional(),sendToHost:!1},onRendered:{schema:f.function().optional(),sendToHost:!1},onRender:{schema:f.function().optional(),sendToHost:!1},onPrerendered:{schema:f.function().optional(),sendToHost:!1},onPrerender:{schema:f.function().optional(),sendToHost:!1},onClose:{schema:f.function().optional(),sendToHost:!1},onDestroy:{schema:f.function().optional(),sendToHost:!1},onResize:{schema:f.function().optional(),sendToHost:!1},onFocus:{schema:f.function().optional(),sendToHost:!1},onError:{schema:f.function().optional(),sendToHost:!1},onProps:{schema:f.function().optional(),sendToHost:!1}};function E(s){return typeof s=="object"&&s!==null&&"~standard"in s&&typeof s["~standard"]=="object"&&s["~standard"]!==null&&s["~standard"].version===1&&typeof s["~standard"].validate=="function"}function et(s,e,t){const n=s["~standard"].validate(e);if(n instanceof Promise)throw new Error(`Prop "${t}" 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(n.issues){const i=n.issues.map(r=>`${tt(r.path,t)}: ${r.message}`);throw new Error(`Validation failed: ${i.join("; ")}`)}return n.value}function tt(s,e){if(!s||s.length===0)return e;const t=s.map(n=>typeof n=="object"&&n!==null&&"key"in n?String(n.key):String(n));return`${e}.${t.join(".")}`}function _e(s,e,t){const n={...O,...e},i={};for(const[r,o]of Object.entries(n)){const c=E(o)?{schema:o}:o;let l;const d=c.alias,b=r in s,P=d&&d in s;if(b)l=s[r];else if(P)l=s[d];else if(c.value)l=c.value(t);else if(c.default!==void 0)l=typeof c.default=="function"?c.default(t):c.default;else if(c.schema&&E(c.schema)){const S=c.schema["~standard"].validate(void 0);!(S instanceof Promise)&&!S.issues&&(l=S.value)}l!==void 0&&c.decorate&&(l=c.decorate({value:l,props:i})),i[r]=l}return i}function st(s,e){const t={...O,...e};for(const[n,i]of Object.entries(t)){const r=E(i),o=r?{schema:i}:i;let a=s[n];if(o.required&&a===void 0)throw new Error(`Prop "${n}" is required but was not provided`);if(o.schema&&E(o.schema))(a!==void 0||r)&&(a=et(o.schema,a,n),s[n]=a);else if(a===void 0)continue;o.validate&&o.validate({value:a,props:s})}}function Ee(s,e,t,n){const i={...O,...e},r={};for(const[o,a]of Object.entries(i)){const l=E(a)?{schema:a}:a,d=s[o];if(l.sendToHost===!1||l.sameDomain&&!n)continue;if(l.trustedDomains){const P=l.trustedDomains;if(!k(P,t))continue}let b=d;l.hostDecorate&&d!==void 0&&(b=l.hostDecorate({value:d,props:s})),r[o]=b}return r}function nt(s,e){const t=new URLSearchParams,n={...O,...e};for(const[i,r]of Object.entries(n)){const a=E(r)?{schema:r}:r,c=s[i];if(c===void 0||typeof c=="function"||!a.queryParam)continue;const l=typeof a.queryParam=="string"?a.queryParam:i;let d;typeof a.queryParam=="function"?d=a.queryParam({value:c}):typeof c=="object"?d=JSON.stringify(c):d=String(c),t.set(l,d)}return t}function be(s,e=""){const t=[];for(const[n,i]of Object.entries(s)){const r=e?`${e}.${n}`:n;if(i!==null&&typeof i=="object"&&!Array.isArray(i))t.push(be(i,r));else{const o=encodeURIComponent(JSON.stringify(i));t.push(`${r}=${o}`)}}return t.filter(Boolean).join("&")}function it(s){const e={};if(!s)return e;const t=s.split("&");for(const n of t){const[i,r]=n.split("=");if(!i||r===void 0)continue;let o;try{o=JSON.parse(decodeURIComponent(r))}catch{o=decodeURIComponent(r)}const a=i.split(".");let c=e;for(let l=0;l<a.length-1;l++){const d=a[l];(!(d in c)||typeof c[d]!="object")&&(c[d]={}),c=c[d]}c[a[a.length-1]]=o}return e}function rt(s){return typeof s=="object"&&s!==null&&s.__type__==="dotify"&&typeof s.__value__=="string"}function Pe(s,e,t){const n={...O,...e},i={};for(const[r,o]of Object.entries(s)){if(o===void 0)continue;const a=n[r];i[r]=ot(o,a,t)}return i}function ot(s,e,t){if(typeof s=="function")return t.serialize(s);const n=e?.serialization??v.JSON;if(n===v.BASE64&&typeof s=="object"){const i=JSON.stringify(s);return{__type__:"base64",__value__:btoa(encodeURIComponent(i))}}return n===v.DOTIFY&&typeof s=="object"&&s!==null&&!Array.isArray(s)?{__type__:"dotify",__value__:be(s)}:Y(s,t)}function Oe(s,e,t,n,i,r){const o={...O,...e},a={};for(const[c,l]of Object.entries(s)){const d=o[c];a[c]=at(l,d,t,n,i,r)}return a}function at(s,e,t,n,i,r){if(ct(s))try{const o=decodeURIComponent(atob(s.__value__));return JSON.parse(o)}catch{return s}if(rt(s))try{return it(s.__value__)}catch{return s}return G(s,n,i,r)}function ct(s){return typeof s=="object"&&s!==null&&s.__type__==="base64"&&typeof s.__value__=="string"}function R(s,e="100%"){return s===void 0?e:typeof s=="number"?`${s}px`:s}function j(s,e){if(s===void 0)return e;if(typeof s=="number")return s;const t=parseInt(s,10);return isNaN(t)?e:t}function lt(s){try{s.src="about:blank",s.parentNode?.removeChild(s)}catch{}}function ht(s,e){ft(s,e)}function ut(s){s.style.display="",s.style.visibility="visible"}function Re(s){s.style.display="none",s.style.visibility="hidden"}function dt(s){try{s.focus(),s.contentWindow?.focus()}catch{}}function ft(s,e){e.width!==void 0&&(s.style.width=R(e.width)),e.height!==void 0&&(s.style.height=R(e.height))}class se extends Error{constructor(e="Popup blocked by browser"){super(e),this.name="PopupOpenError"}}function pt(s){const{url:e,name:t,dimensions:n}=s,i=j(n.width,500),r=j(n.height,500),o=Math.floor(window.screenX+(window.outerWidth-i)/2),a=Math.floor(window.screenY+(window.outerHeight-r)/2),c=[`width=${i}`,`height=${r}`,`left=${o}`,`top=${a}`,"menubar=no","toolbar=no","location=yes","status=no","resizable=yes","scrollbars=yes"].join(","),l=window.open(e,t,c);if(!l||yt(l))throw new se;return l}function mt(s){try{s.closed||s.close()}catch{}}function gt(s){try{s.closed||s.focus()}catch{}}function yt(s){if(!s)return!0;try{return!!(s.closed||s.innerHeight===0||s.innerWidth===0)}catch{return!0}}function wt(s,e,t={}){const{initialInterval:n=100,maxInterval:i=2e3,multiplier:r=1.5}=t;let o=n,a,c=!1;const l=()=>{try{e()}catch(b){console.error("Error in popup close callback:",b)}},d=()=>{if(!c){try{if(s.closed){l();return}}catch{l();return}o=Math.min(o*r,i),a=setTimeout(d,o)}};return a=setTimeout(d,o),()=>{c=!0,clearTimeout(a)}}function _t(s,e){try{const t=j(e.width,s.outerWidth),n=j(e.height,s.outerHeight);s.resizeTo(t,n)}catch{}}function Et(s){const{doc:e,dimensions:t,uid:n,tag:i}=s,r=e.createElement("div");return r.id=`forgeframe-container-${n}`,r.setAttribute("data-forgeframe-tag",i),Object.assign(r.style,{display:"inline-block",position:"relative",width:R(t.width),height:R(t.height),overflow:"hidden"}),r}function bt(s){const{doc:e,dimensions:t,cspNonce:n}=s,i=e.createElement("div");Object.assign(i.style,{display:"flex",alignItems:"center",justifyContent:"center",width:R(t.width),height:R(t.height),backgroundColor:"#f5f5f5",position:"absolute",top:"0",left:"0",zIndex:"100"});const r=e.createElement("div");Object.assign(r.style,{width:"40px",height:"40px",border:"3px solid #e0e0e0",borderTopColor:"#3498db",borderRadius:"50%",animation:"forgeframe-spin 1s linear infinite"});const o=e.createElement("style");return n&&o.setAttribute("nonce",n),o.textContent=`
|
|
2
2
|
@keyframes forgeframe-spin {
|
|
3
3
|
to { transform: rotate(360deg); }
|
|
4
4
|
}
|
|
5
|
-
`,i.appendChild(o),i.appendChild(r),i}function Et(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 bt(t,e=200){return new Promise(n=>{t.style.transition=`opacity ${e}ms ease-out`,t.style.opacity="0",setTimeout(n,e)})}async function Pt(t,e,n){e&&(await bt(e,150),e.remove()),n.style.display="",n.style.visibility="visible",n.style.opacity="0",await Et(n,150)}class ee{event;state={};exports;consumerExports;_uid;get uid(){return this._uid}options;props;context;messenger;bridge;cleanup;hostWindow=null;iframe=null;container=null;prerenderElement=null;initPromise=null;rendered=!1;destroyed=!1;constructor(e,n={}){this._uid=$e(),this.options=this.normalizeOptions(e),this.context=this.options.defaultContext,this.event=new re,this.cleanup=new Le;const s=this.buildTrustedDomains();this.messenger=new ce(this.uid,window,Y(),s),this.bridge=new q(this.messenger);const i=this.createPropContext();this.props=ge(n,this.options.props,i),this.setupMessageHandlers(),this.setupCleanup()}buildTrustedDomains(){const e=[],n=typeof this.options.url=="function"?this.options.url(this.props):this.options.url;try{const s=new URL(n);e.push(s.origin)}catch{}if(this.options.domain){if(typeof this.options.domain=="string")e.push(this.options.domain);else if(Array.isArray(this.options.domain))e.push(...this.options.domain);else if(this.options.domain instanceof RegExp)return this.options.domain}return e.length>0?e:void 0}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(),et(this.props,this.options.props),this.container=this.resolveContainer(e),this.event.emit(m.PRERENDER),this.callPropCallback("onPrerender"),await this.prerender(),this.event.emit(m.PRERENDERED),this.callPropCallback("onPrerendered"),this.event.emit(m.RENDER),this.callPropCallback("onRender"),await this.open(),await this.waitForHost(),this.context===p.IFRAME&&this.iframe&&this.prerenderElement&&(await Pt(this.container,this.prerenderElement,this.iframe),this.prerenderElement=null),this.rendered=!0,this.event.emit(m.RENDERED),this.callPropCallback("onRendered"),this.event.emit(m.DISPLAY),this.callPropCallback("onDisplay")}async renderTo(e,n,s){return this.render(n,s)}async close(){this.destroyed||(this.event.emit(m.CLOSE),await this.destroy())}async focus(){this.context===p.IFRAME&&this.iframe?ut(this.iframe):this.context===p.POPUP&&this.hostWindow&&pt(this.hostWindow),this.event.emit(m.FOCUS),this.callPropCallback("onFocus")}async resize(e){this.context===p.IFRAME&&this.iframe?ct(this.iframe,e):this.context===p.POPUP&&this.hostWindow&&yt(this.hostWindow,e),this.event.emit(m.RESIZE,e),this.callPropCallback("onResize",e)}async show(){this.context===p.IFRAME&&this.iframe&<(this.iframe)}async hide(){this.context===p.IFRAME&&this.iframe&&be(this.iframe)}async updateProps(e){const n=this.createPropContext();if(this.props=ge({...this.props,...e},this.options.props,n),this.hostWindow&&!de(this.hostWindow)){const s=this.getHostDomain(),i=ye(this.props,this.options.props,s,ue(this.hostWindow)),r=we(i,this.options.props,this.bridge);await this.messenger.send(this.hostWindow,s,h.PROPS,r)}this.event.emit(m.PROPS,this.props),this.callPropCallback("onProps",this.props)}clone(){return new ee(this.options,this.props)}isEligible(){return this.options.eligible?this.options.eligible({props:this.props}).eligible:!0}normalizeOptions(e){return{...e,props:e.props??{},defaultContext:e.defaultContext??p.IFRAME,dimensions:typeof e.dimensions=="function"?e.dimensions(this.props):e.dimensions??{width:"100%",height:"100%"},timeout:e.timeout??1e4,children:e.children}}createPropContext(){return{props:this.props,state:this.state,close:()=>this.close(),focus:()=>this.focus(),onError:e=>this.handleError(e),container:this.container,uid:this.uid,tag:this.options.tag}}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}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(){if(!this.container)return;const e=this.options.prerenderTemplate??wt,n=this.options.containerTemplate??_t,s=this.options.dimensions,i=this.props.cspNonce;if(this.context===p.IFRAME){const c=this.buildWindowName();this.iframe=this.createIframeElement(c),be(this.iframe)}const r={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:s,props:this.props,doc:document,container:this.container,frame:this.iframe,prerenderFrame:null,close:()=>this.close(),focus:()=>this.focus(),cspNonce:i};this.prerenderElement=e(r);const o={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:s,props:this.props,doc:document,container:this.container,frame:this.iframe,prerenderFrame:this.prerenderElement,close:()=>this.close(),focus:()=>this.focus(),cspNonce:i},a=n(o);a&&(this.container.appendChild(a),this.container=a),this.prerenderElement&&!this.prerenderElement.parentNode&&this.container.appendChild(this.prerenderElement),this.iframe&&!this.iframe.parentNode&&this.container.appendChild(this.iframe)}createIframeElement(e){const n=document.createElement("iframe"),s=this.options.dimensions,i=typeof this.options.attributes=="function"?this.options.attributes(this.props):this.options.attributes??{},r=typeof this.options.style=="function"?this.options.style(this.props):this.options.style??{};n.name=e,n.setAttribute("frameborder","0"),n.setAttribute("allowtransparency","true"),n.setAttribute("scrolling","auto"),s.width!==void 0&&(n.style.width=typeof s.width=="number"?`${s.width}px`:s.width),s.height!==void 0&&(n.style.height=typeof s.height=="number"?`${s.height}px`:s.height);for(const[o,a]of Object.entries(i))a!==void 0&&(typeof a=="boolean"?a&&n.setAttribute(o,""):n.setAttribute(o,a));for(const[o,a]of Object.entries(r)){if(a===void 0)continue;const c=typeof a=="number"?`${a}px`:a;n.style.setProperty(o.replace(/([A-Z])/g,"-$1").toLowerCase(),String(c))}return i.sandbox||n.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox"),n}async open(){const e=this.buildUrl();if(this.context===p.IFRAME){if(!this.iframe)throw new Error("Iframe not created during prerender");this.iframe.src=e,this.hostWindow=this.iframe.contentWindow}else{const n=this.buildWindowName();this.hostWindow=dt({url:e,name:n,dimensions:this.options.dimensions});const s=gt(this.hostWindow,()=>{this.destroy()});this.cleanup.register(s)}this.hostWindow&&Ye(this.uid,this.hostWindow)}buildUrl(){const e=typeof this.options.url=="function"?this.options.url(this.props):this.options.url,s=tt(this.props,this.options.props).toString();if(!s)return e;const i=e.includes("?")?"&":"?";return`${e}${i}${s}`}buildWindowName(){const e=this.getHostDomain(),n=ye(this.props,this.options.props,e,!1),s=we(n,this.options.props,this.bridge),i=this.buildNestedHostRefs(),r=qe({uid:this.uid,tag:this.options.tag,context:this.context,consumerDomain:Y(),props:s,exports:this.createConsumerExports(),children:i});return Be(r)}buildNestedHostRefs(){if(!this.options.children)return;const e=this.options.children({props:this.props}),n={};for(const[s,i]of Object.entries(e)){const r=i;n[s]={tag:r.tag??s,url:typeof r.url=="function"?r.url.toString():r.url??""}}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(){const e=typeof this.options.url=="function"?this.options.url(this.props):this.options.url;try{return new URL(e,window.location.origin).origin}catch{return"*"}}async waitForHost(){this.initPromise=oe();try{await Ae(this.initPromise.promise,this.options.timeout,`Host component "${this.options.tag}" (uid: ${this._uid}) did not initialize within ${this.options.timeout}ms. Check that the host page loads correctly and calls the initialization code.`)}catch(e){throw this.handleError(e),e}}setupMessageHandlers(){this.messenger.on(h.INIT,()=>(this.initPromise&&this.initPromise.resolve(),{success:!0})),this.messenger.on(h.CLOSE,async()=>(await this.close(),{success:!0})),this.messenger.on(h.RESIZE,async e=>(await this.resize(e),{success:!0})),this.messenger.on(h.FOCUS,async()=>(await this.focus(),{success:!0})),this.messenger.on(h.SHOW,async()=>(await this.show(),{success:!0})),this.messenger.on(h.HIDE,async()=>(await this.hide(),{success:!0})),this.messenger.on(h.ERROR,async e=>{const n=new Error(e.message);return n.stack=e.stack,this.handleError(n),{success:!0}}),this.messenger.on(h.EXPORT,async e=>(this.exports=e,{success:!0})),this.messenger.on(h.CONSUMER_EXPORT,async e=>(this.consumerExports=e,{success:!0})),this.messenger.on(h.GET_SIBLINGS,async e=>{const n=[],s=Ot(e.tag);if(s)for(const i of s.instances)i.uid!==e.uid&&n.push({uid:i.uid,tag:e.tag,exports:i.exports});return n})}setupCleanup(){this.cleanup.register(()=>{this.messenger.destroy(),this.bridge.destroy(),this.event.removeAllListeners(),Ge(this.uid)})}handleError(e){this.event.emit(m.ERROR,e),this.callPropCallback("onError",e)}callPropCallback(e,...n){const s=this.props[e];if(typeof s=="function")try{const i=s(...n);i&&typeof i=="object"&&"catch"in i&&typeof i.catch=="function"&&i.catch(r=>{console.error(`Error in async ${e} callback:`,r)})}catch(i){console.error(`Error in ${e} callback:`,i)}}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.iframe&&(at(this.iframe),this.iframe=null),this.context===p.POPUP&&this.hostWindow&&ft(this.hostWindow),this.hostWindow=null,this.prerenderElement&&(this.prerenderElement.remove(),this.prerenderElement=null),await this.cleanup.cleanup(),this.event.emit(m.DESTROY),this.callPropCallback("onDestroy"))}}class Rt{constructor(e,n={}){this.propDefinitions=n,this.uid=e.uid,this.tag=e.tag,this.consumerDomain=e.consumerDomain,this.event=new re,this.messenger=new ce(this.uid,window,Y(),this.consumerDomain),this.setupMessageHandlers(),this.consumerWindow=this.resolveConsumerWindow(),this.bridge=new q(this.messenger),this.hostProps=this.buildHostProps(e),window.hostProps=this.hostProps,this.sendInit()}hostProps;event;uid;tag;consumerWindow;consumerDomain;messenger;bridge;propsHandlers=new Set;consumerProps;initError=null;getProps(){return this.hostProps}resolveConsumerWindow(){if(Ue()){const e=ze();if(e)return e}if(je()){const e=We();if(e)return e}throw new Error("Could not resolve consumer window")}buildHostProps(e){const n=Ee(e.props,this.propDefinitions,this.messenger,this.bridge,this.consumerWindow,this.consumerDomain);return this.consumerProps=n,{...n,uid:this.uid,tag:this.tag,close:()=>this.close(),focus:()=>this.focus(),resize:s=>this.resize(s),show:()=>this.show(),hide:()=>this.hide(),onProps:s=>this.onProps(s),onError:s=>this.onError(s),getConsumer:()=>this.consumerWindow,getConsumerDomain:()=>this.consumerDomain,export:s=>this.exportData(s),consumer:{props:this.consumerProps,export:s=>this.consumerExport(s)},getPeerInstances:s=>this.getPeerInstances(s),children:this.buildNestedComponents(e.children)}}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(m.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,i]of Object.entries(e))try{n[s]=te({tag:i.tag,url:i.url,props:i.props,dimensions:i.dimensions,defaultContext:i.defaultContext})}catch(r){console.warn(`Failed to create nested component "${s}":`,r)}return Object.keys(n).length>0?n:void 0}setupMessageHandlers(){this.messenger.on(h.PROPS,e=>{try{const n=Ee(e,this.propDefinitions,this.messenger,this.bridge,this.consumerWindow,this.consumerDomain);Object.assign(this.hostProps,n);for(const s of this.propsHandlers)try{s(n)}catch(i){console.error("Error in props handler:",i)}return this.event.emit(m.PROPS,n),{success:!0}}catch(n){const s=n instanceof Error?n:new Error(String(n));throw console.error("Error deserializing props:",s),this.event.emit(m.ERROR,s),s}})}destroy(){this.messenger.destroy(),this.bridge.destroy(),this.event.removeAllListeners(),this.propsHandlers.clear()}}let W=null;function Pe(t){if(W)return W;if(!G())return null;const e=Xe();return e?(W=new Rt(e,t),W):(console.error("Failed to parse ForgeFrame payload from window.name"),null)}function Re(){return G()}function Se(){return G()}function Oe(){return window.hostProps}const I=new Map;function St(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{new URL(t.url,window.location.origin)}catch{throw new Error(`Invalid component URL "${t.url}". Must be a valid absolute or relative URL.`)}if(I.has(t.tag))throw new Error(`Component "${t.tag}" is already registered`)}function te(t){St(t);const e=[];let n;if(K(t.tag)){const i=Pe(t.props);i&&(n=i.hostProps)}const s=function(i={}){const r=new ee(t,i);return e.push(r),r.event.once("destroy",()=>{const o=e.indexOf(r);o!==-1&&e.splice(o,1)}),r};return s.instances=e,s.isHost=()=>K(t.tag),s.isEmbedded=()=>K(t.tag),s.hostProps=n,s.canRenderTo=async i=>{try{return!!(ue(i)||t.domain)}catch{return!1}},I.set(t.tag,s),s}function Ot(t){return I.get(t)}async function Ce(t){await t.close()}async function ne(t){const e=I.get(t);if(!e)return;const n=[...e.instances];await Promise.all(n.map(s=>s.close()))}async function ve(){const t=Array.from(I.keys());await Promise.all(t.map(e=>ne(e)))}function Ie(t,e){const{React:n}=e,{createElement:s,useRef:i,useEffect:r,useState:o,forwardRef:a}=n,c=a(function(w,E){const{onRendered:S,onError:z,onClose:De,context:vt,className:Ne,style:Te,...se}=w,U=i(null),ie=i(null),[Fe,It]=o(null);return r(()=>{const x=U.current;if(!x)return;const b=t(se);return ie.current=b,S&&b.event.once("rendered",S),De&&b.event.once("close",De),z&&b.event.on("error",z),b.render(x,vt).catch(ke=>{It(ke),z?.(ke)}),()=>{b.close().catch(()=>{}),ie.current=null}},[]),r(()=>{const x=ie.current;x&&x.updateProps(se).catch(b=>{z?.(b)})},[JSON.stringify(se)]),r(()=>{E&&typeof E=="object"&&U.current&&(E.current=U.current)},[E]),Fe?s("div",{className:Ne,style:{color:"red",padding:"16px",...Te}},`Error: ${Fe.message}`):s("div",{ref:U,className:Ne,style:{display:"inline-block",...Te}})}),l=`ForgeFrame(${t.name||"Component"})`;return c.displayName=l,c}function Ct(t){return function(n){return Ie(n,{React:t})}}Pe();const xe={create:te,destroy:Ce,destroyByTag:ne,destroyAll:ve,isHost:Re,isEmbedded:Se,getHostProps:Oe,PROP_SERIALIZATION:O,CONTEXT:p,EVENT:m,PopupOpenError:Q,VERSION:j,isStandardSchema:_,prop:f};u.AnySchema=H,u.ArraySchema=C,u.BooleanSchema=k,u.CONTEXT=p,u.EVENT=m,u.EnumSchema=A,u.ForgeFrame=xe,u.FunctionSchema=$,u.LiteralSchema=L,u.NumberSchema=F,u.ObjectSchema=v,u.PROP_SERIALIZATION=O,u.PopupOpenError=Q,u.PropSchema=g,u.StringSchema=T,u.VERSION=j,u.create=te,u.createReactComponent=Ie,u.default=xe,u.destroy=Ce,u.destroyAll=ve,u.destroyByTag=ne,u.getHostProps=Oe,u.isEmbedded=Se,u.isHost=Re,u.isStandardSchema=_,u.prop=f,u.withReactComponent=Ct,Object.defineProperties(u,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
|
5
|
+
`,i.appendChild(o),i.appendChild(r),i}function Pt(s,e=200){return new Promise(t=>{s.style.opacity="0",s.style.transition=`opacity ${e}ms ease-in`,s.offsetHeight,s.style.opacity="1",setTimeout(t,e)})}function Ot(s,e=200){return new Promise(t=>{s.style.transition=`opacity ${e}ms ease-out`,s.style.opacity="0",setTimeout(t,e)})}async function Rt(s,e,t){e&&(await Ot(e,150),e.remove()),t.style.display="",t.style.visibility="visible",t.style.opacity="0",await Pt(t,150)}class ne{event;state={};exports;consumerExports;_uid;get uid(){return this._uid}options;props;context;messenger;bridge;cleanup;hostWindow=null;openedHostDomain=null;dynamicUrlTrustedOrigin=null;iframe=null;container=null;prerenderElement=null;initPromise=null;rendered=!1;destroyed=!1;constructor(e,t={}){this._uid=He(),this.options=this.normalizeOptions(e),this.context=this.options.defaultContext,this.event=new le,this.cleanup=new Ae;const n=this.createPropContext();this.props=_e(t,this.options.props,n);const i=this.buildTrustedDomains();this.messenger=new de(this.uid,window,Q(),i),this.bridge=new Z(this.messenger),this.setupMessageHandlers(),this.setupCleanup()}buildTrustedDomains(){const e=[],t=this.resolveUrlOrigin(this.resolveUrl());if(t&&(e.push(t),this.dynamicUrlTrustedOrigin=t),this.options.domain){if(typeof this.options.domain=="string")e.push(this.options.domain);else if(Array.isArray(this.options.domain))e.push(...this.options.domain);else if(this.options.domain instanceof RegExp)return this.options.domain}return e.length>0?e:void 0}async render(e,t){if(this.destroyed)throw new Error("Component has been destroyed");if(this.rendered)throw new Error("Component has already been rendered");this.context=t??this.options.defaultContext,this.checkEligibility(),st(this.props,this.options.props),this.options.validate?.({props:this.props}),this.container=this.resolveContainer(e),this.event.emit(m.PRERENDER),this.callPropCallback("onPrerender"),await this.prerender(),this.event.emit(m.PRERENDERED),this.callPropCallback("onPrerendered"),this.event.emit(m.RENDER),this.callPropCallback("onRender"),await this.open(),await this.waitForHost(),this.context===p.IFRAME&&this.iframe&&this.prerenderElement&&(await Rt(this.container,this.prerenderElement,this.iframe),this.prerenderElement=null),this.rendered=!0,this.event.emit(m.RENDERED),this.callPropCallback("onRendered"),this.event.emit(m.DISPLAY),this.callPropCallback("onDisplay")}async renderTo(e,t,n){return this.render(t,n)}async close(){this.destroyed||(this.event.emit(m.CLOSE),await this.destroy())}async focus(){this.context===p.IFRAME&&this.iframe?dt(this.iframe):this.context===p.POPUP&&this.hostWindow&>(this.hostWindow),this.event.emit(m.FOCUS),this.callPropCallback("onFocus")}async resize(e){this.context===p.IFRAME&&this.iframe?ht(this.iframe,e):this.context===p.POPUP&&this.hostWindow&&_t(this.hostWindow,e),this.event.emit(m.RESIZE,e),this.callPropCallback("onResize",e)}async show(){this.context===p.IFRAME&&this.iframe&&ut(this.iframe)}async hide(){this.context===p.IFRAME&&this.iframe&&Re(this.iframe)}async updateProps(e){const t=this.createPropContext(),n=_e({...this.props,...e},this.options.props,t);this.options.validate?.({props:n});const i=this.resolveUrl(n),r=this.resolveUrlOrigin(i);if(this.rendered&&this.openedHostDomain&&r&&r!==this.openedHostDomain)throw new Error(`Cannot change component URL origin after render (from "${this.openedHostDomain}" to "${r}")`);if(this.props=n,this.rendered||this.syncTrustedDomainForUrl(i),this.hostWindow&&!me(this.hostWindow)){const o=this.openedHostDomain??this.getHostDomain(),a=Ee(n,this.options.props,o,pe(this.hostWindow)),c=Pe(a,this.options.props,this.bridge);await this.messenger.send(this.hostWindow,o,u.PROPS,c)}this.event.emit(m.PROPS,this.props),this.callPropCallback("onProps",this.props)}clone(){return new ne(this.options,this.props)}isEligible(){return this.options.eligible?this.options.eligible({props:this.props}).eligible:!0}normalizeOptions(e){return{...e,props:e.props??{},defaultContext:e.defaultContext??p.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.options.domain||this.options.domain instanceof RegExp?!1:typeof this.options.domain=="string"?this.options.domain===e:this.options.domain.includes(e)}syncTrustedDomainForUrl(e){const t=this.resolveUrlOrigin(e);if(!t)return;const n=this.dynamicUrlTrustedOrigin;n&&n!==t&&!this.isExplicitDomainTrust(n)&&this.messenger.removeTrustedDomain(n),this.messenger.addTrustedDomain(t),this.dynamicUrlTrustedOrigin=t}createPropContext(){return{props:this.props,state:this.state,close:()=>this.close(),focus:()=>this.focus(),onError:e=>this.handleError(e),container:this.container,uid:this.uid,tag:this.options.tag}}resolveContainer(e){if(!e)throw new Error("Container is required for rendering");if(typeof e=="string"){const t=document.querySelector(e);if(!t)throw new Error(`Container "${e}" not found`);return t}return 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(){if(!this.container)return;const e=this.options.prerenderTemplate??bt,t=this.options.containerTemplate??Et,n=this.resolveDimensions(),i=this.props.cspNonce;if(this.context===p.IFRAME){const c=this.buildWindowName();this.iframe=this.createIframeElement(c),Re(this.iframe)}const r={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:n,props:this.props,doc:document,container:this.container,frame:this.iframe,prerenderFrame:null,close:()=>this.close(),focus:()=>this.focus(),cspNonce:i};this.prerenderElement=e(r);const o={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:n,props:this.props,doc:document,container:this.container,frame:this.iframe,prerenderFrame:this.prerenderElement,close:()=>this.close(),focus:()=>this.focus(),cspNonce:i},a=t(o);a&&(this.container.appendChild(a),this.container=a),this.prerenderElement&&!this.prerenderElement.parentNode&&this.container.appendChild(this.prerenderElement),this.iframe&&!this.iframe.parentNode&&this.container.appendChild(this.iframe)}createIframeElement(e){const t=document.createElement("iframe"),n=this.resolveDimensions(),i=typeof this.options.attributes=="function"?this.options.attributes(this.props):this.options.attributes??{},r=typeof this.options.style=="function"?this.options.style(this.props):this.options.style??{};t.name=e,t.setAttribute("frameborder","0"),t.setAttribute("allowtransparency","true"),t.setAttribute("scrolling","auto"),n.width!==void 0&&(t.style.width=typeof n.width=="number"?`${n.width}px`:n.width),n.height!==void 0&&(t.style.height=typeof n.height=="number"?`${n.height}px`:n.height);for(const[o,a]of Object.entries(i))a!==void 0&&(typeof a=="boolean"?a&&t.setAttribute(o,""):t.setAttribute(o,a));for(const[o,a]of Object.entries(r)){if(a===void 0)continue;const c=typeof a=="number"?`${a}px`:a;t.style.setProperty(o.replace(/([A-Z])/g,"-$1").toLowerCase(),String(c))}return i.sandbox||t.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox"),t}async open(){const e=this.resolveUrl();this.syncTrustedDomainForUrl(e),this.openedHostDomain=this.resolveUrlOrigin(e);const t=this.buildUrl(e);if(this.context===p.IFRAME){if(!this.iframe)throw new Error("Iframe not created during prerender");this.iframe.src=t,this.hostWindow=this.iframe.contentWindow}else{const n=this.buildWindowName();this.hostWindow=pt({url:t,name:n,dimensions:this.resolveDimensions()});const i=wt(this.hostWindow,()=>{this.destroy()});this.cleanup.register(i)}this.hostWindow&&Ge(this.uid,this.hostWindow)}buildUrl(e=this.resolveUrl()){const n=nt(this.props,this.options.props).toString();if(!n)return e;const i=e.includes("?")?"&":"?";return`${e}${i}${n}`}buildWindowName(){const e=this.getHostDomain(),t=Ee(this.props,this.options.props,e,!1),n=Pe(t,this.options.props,this.bridge),i=this.buildNestedHostRefs(),r=Ke({uid:this.uid,tag:this.options.tag,context:this.context,consumerDomain:Q(),props:n,exports:this.createConsumerExports(),children:i});return qe(r)}buildNestedHostRefs(){if(!this.options.children)return;const e=this.options.children({props:this.props}),t={};for(const[n,i]of Object.entries(e)){const r=Dt(i);if(!r)throw new Error(`Nested component "${n}" is missing component metadata`);if(typeof r.url!="string")throw new Error(`Nested component "${n}" must use a static string URL. Function URLs are not supported in children.`);t[n]={tag:r.tag,url:r.url,props:r.props,dimensions:typeof r.dimensions=="function"?void 0:r.dimensions,defaultContext:r.defaultContext}}return Object.keys(t).length>0?t:void 0}createConsumerExports(){return{init:u.INIT,close:u.CLOSE,resize:u.RESIZE,show:u.SHOW,hide:u.HIDE,onError:u.ERROR,updateProps:u.PROPS,export:u.EXPORT}}getHostDomain(){return this.openedHostDomain?this.openedHostDomain:this.resolveUrlOrigin(this.resolveUrl())??"*"}async waitForHost(){this.initPromise=he();try{await Ue(this.initPromise.promise,this.options.timeout,`Host component "${this.options.tag}" (uid: ${this._uid}) did not initialize within ${this.options.timeout}ms. Check that the host page loads correctly and calls the initialization code.`)}catch(e){throw this.handleError(e),e}}setupMessageHandlers(){this.messenger.on(u.INIT,()=>(this.initPromise&&this.initPromise.resolve(),{success:!0})),this.messenger.on(u.CLOSE,async()=>(await this.close(),{success:!0})),this.messenger.on(u.RESIZE,async e=>(await this.resize(e),{success:!0})),this.messenger.on(u.FOCUS,async()=>(await this.focus(),{success:!0})),this.messenger.on(u.SHOW,async()=>(await this.show(),{success:!0})),this.messenger.on(u.HIDE,async()=>(await this.hide(),{success:!0})),this.messenger.on(u.ERROR,async e=>{const t=new Error(e.message);return t.stack=e.stack,this.handleError(t),{success:!0}}),this.messenger.on(u.EXPORT,async e=>(this.exports=e,{success:!0})),this.messenger.on(u.CONSUMER_EXPORT,async e=>(this.consumerExports=e,{success:!0})),this.messenger.on(u.GET_SIBLINGS,async e=>{const t=[],n=It(e.tag);if(n)for(const i of n.instances)i.uid!==e.uid&&t.push({uid:i.uid,tag:e.tag,exports:i.exports});return t})}setupCleanup(){this.cleanup.register(()=>{this.messenger.destroy(),this.bridge.destroy(),Qe(this.uid)})}handleError(e){this.event.emit(m.ERROR,e),this.callPropCallback("onError",e)}callPropCallback(e,...t){const n=this.props[e];if(typeof n=="function")try{const i=n(...t);i&&typeof i=="object"&&"catch"in i&&typeof i.catch=="function"&&i.catch(r=>{console.error(`Error in async ${e} callback:`,r)})}catch(i){console.error(`Error in ${e} callback:`,i)}}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.iframe&&(lt(this.iframe),this.iframe=null),this.context===p.POPUP&&this.hostWindow&&mt(this.hostWindow),this.hostWindow=null,this.openedHostDomain=null,this.dynamicUrlTrustedOrigin=null,this.prerenderElement&&(this.prerenderElement.remove(),this.prerenderElement=null),await this.cleanup.cleanup(),this.event.emit(m.DESTROY),this.callPropCallback("onDestroy"),this.event.removeAllListeners())}}class St{constructor(e,t={},n,i=!1){this.propDefinitions=t,this.allowedConsumerDomains=n,this.deferInit=i,this.uid=e.uid,this.tag=e.tag,this.consumerDomain=e.consumerDomain,this.validateConsumerDomain(),this.event=new le,this.messenger=new de(this.uid,window,Q(),this.consumerDomain),this.setupMessageHandlers(),this.consumerWindow=this.resolveConsumerWindow(),this.bridge=new Z(this.messenger),this.hostProps=this.buildHostProps(e),this.exposeHostProps(),this.deferInit||this.flushInit()}hostProps;event;uid;tag;consumerWindow;consumerDomain;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:t=>{t&&(this.hostProps=t)}})}catch{e.hostProps=this.hostProps}}validateConsumerDomain(){if(this.allowedConsumerDomains&&!k(this.allowedConsumerDomains,this.consumerDomain))throw new Error(`Consumer domain "${this.consumerDomain}" is not allowed for component "${this.tag}"`)}getProps(){return this.hostProps}resolveConsumerWindow(){if(Be()){const e=je();if(e)return e}if(Ve()){const e=ze();if(e)return e}throw new Error("Could not resolve consumer window")}buildHostProps(e){const t=Oe(e.props,this.propDefinitions,this.messenger,this.bridge,this.consumerWindow,this.consumerDomain);return this.consumerProps=t,{...t,uid:this.uid,tag:this.tag,close:()=>this.close(),focus:()=>this.focus(),resize:n=>this.resize(n),show:()=>this.show(),hide:()=>this.hide(),onProps:n=>this.onProps(n),onError:n=>this.onError(n),getConsumer:()=>this.consumerWindow,getConsumerDomain:()=>this.consumerDomain,export:n=>this.exportData(n),consumer:{props:this.consumerProps,export:n=>this.consumerExport(n)},getPeerInstances:n=>this.getPeerInstances(n),children:this.buildNestedComponents(e.children)}}async sendInit(){try{await this.messenger.send(this.consumerWindow,this.consumerDomain,u.INIT,{uid:this.uid,tag:this.tag})}catch(e){const t=e instanceof Error?e:new Error(String(e));this.initError=t,this.event.emit(m.ERROR,{type:"init_failed",message:`Failed to initialize host component: ${t.message}`,error:t}),console.error("Failed to send init message:",e)}}getInitError(){return this.initError}async close(){await this.messenger.send(this.consumerWindow,this.consumerDomain,u.CLOSE,{})}async focus(){window.focus(),await this.messenger.send(this.consumerWindow,this.consumerDomain,u.FOCUS,{})}async resize(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,u.RESIZE,e)}async show(){await this.messenger.send(this.consumerWindow,this.consumerDomain,u.SHOW,{})}async hide(){await this.messenger.send(this.consumerWindow,this.consumerDomain,u.HIDE,{})}onProps(e){return this.propsHandlers.add(e),{cancel:()=>this.propsHandlers.delete(e)}}async onError(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,u.ERROR,{message:e.message,stack:e.stack})}async exportData(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,u.EXPORT,e)}async consumerExport(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,u.CONSUMER_EXPORT,e)}async getPeerInstances(e){return await this.messenger.send(this.consumerWindow,this.consumerDomain,u.GET_SIBLINGS,{uid:this.uid,tag:this.tag,options:e})??[]}buildNestedComponents(e){if(!e)return;const t={};for(const[n,i]of Object.entries(e))try{t[n]=ie({tag:i.tag,url:i.url,props:i.props,dimensions:i.dimensions,defaultContext:i.defaultContext})}catch(r){console.warn(`Failed to create nested component "${n}":`,r)}return Object.keys(t).length>0?t:void 0}setupMessageHandlers(){this.messenger.on(u.PROPS,e=>{try{const t=Oe(e,this.propDefinitions,this.messenger,this.bridge,this.consumerWindow,this.consumerDomain);Object.assign(this.hostProps,t);for(const n of this.propsHandlers)try{n(t)}catch(i){console.error("Error in props handler:",i)}return this.event.emit(m.PROPS,t),{success:!0}}catch(t){const n=t instanceof Error?t:new Error(String(t));throw console.error("Error deserializing props:",n),this.event.emit(m.ERROR,n),n}})}destroy(){this.destroyed||(this.destroyed=!0,this.deferredInitFlushScheduled=!1,this.messenger.destroy(),this.bridge.destroy(),this.event.removeAllListeners(),this.propsHandlers.clear())}}let w=null;function B(s,e,t={}){if(w){if(e){const i=w.getProps().getConsumerDomain();if(!k(e,i))throw vt(),new Error(`Consumer domain "${i}" is not allowed for this host component`)}return t.deferInit||w.flushInit(),w}if(!ee())return null;const n=Ze();return n?(w=new St(n,s,e,t.deferInit??!1),w):(console.error("Failed to parse ForgeFrame payload from window.name"),null)}function Se(){return ee()}function ve(){return ee()}function Ce(){return window.hostProps}function vt(){w&&(w.destroy(),w=null),delete window.hostProps}const D=new Map,Ie=Symbol("forgeframe.component.options");function Ct(s){if(!s.tag)throw new Error("Component tag is required");if(!/^[a-z][a-z0-9-]*$/.test(s.tag))throw new Error(`Invalid component tag "${s.tag}". Must start with lowercase letter and contain only lowercase letters, numbers, and hyphens.`);if(!s.url)throw new Error("Component url is required");if(typeof s.url=="string")try{new URL(s.url,window.location.origin)}catch{throw new Error(`Invalid component URL "${s.url}". Must be a valid absolute or relative URL.`)}if(D.has(s.tag))throw new Error(`Component "${s.tag}" is already registered`)}function ie(s){Ct(s);const e=[];let t;if(te(s.tag)){const i=B(s.props,s.allowedConsumerDomains);i&&(t=i.hostProps)}const n=function(i={}){const r=new ne(s,i);return e.push(r),r.event.once("destroy",()=>{const o=e.indexOf(r);o!==-1&&e.splice(o,1)}),r};return n.instances=e,n.isHost=()=>te(s.tag),n.isEmbedded=()=>te(s.tag),n.hostProps=t,n[Ie]=s,n.canRenderTo=async i=>{try{return!!(pe(i)||s.domain)}catch{return!1}},D.set(s.tag,n),n}function It(s){return D.get(s)}function Dt(s){return s[Ie]}async function De(s){await s.close()}async function re(s){const e=D.get(s);if(!e)return;const t=[...e.instances];await Promise.all(t.map(n=>n.close()))}async function xe(){const s=Array.from(D.keys());await Promise.all(s.map(e=>re(e)))}function xt(s,e){const t=Object.keys(s),n=Object.keys(e);if(t.length!==n.length)return!1;for(const i of t)if(!Object.prototype.hasOwnProperty.call(e,i)||!Object.is(s[i],e[i]))return!1;return!0}function Te(s,e){const{React:t}=e,{createElement:n,useRef:i,useEffect:r,useState:o,forwardRef:a}=t,c=a(function(b,P){const{onRendered:S,onError:x,onClose:Fe,context:Nt,className:$e,style:ke,...oe}=b,V=i(null),ae=i(null),ce=i(null),[Le,Ft]=o(null);return r(()=>{const T=V.current;if(!T)return;const y=s(oe);return ae.current=y,S&&y.event.once("rendered",S),Fe&&y.event.once("close",Fe),x&&y.event.on("error",x),y.render(T,Nt).catch(N=>{Ft(N),x?.(N)}),()=>{y.close().catch(()=>{}),ae.current=null,ce.current=null}},[]),r(()=>{const T=ae.current;if(!T)return;const y=oe,N=ce.current;N&&xt(N,y)||(ce.current=y,T.updateProps(y).catch($t=>{x?.($t)}))},[oe,x]),r(()=>{P&&typeof P=="object"&&V.current&&(P.current=V.current)},[P]),Le?n("div",{className:$e,style:{color:"red",padding:"16px",...ke}},`Error: ${Le.message}`):n("div",{ref:V,className:$e,style:{display:"inline-block",...ke}})}),l=`ForgeFrame(${s.name||"Component"})`;return c.displayName=l,c}function Tt(s){return function(t){return Te(t,{React:s})}}B(void 0,void 0,{deferInit:!0});const Ne={create:ie,destroy:De,destroyByTag:re,destroyAll:xe,isHost:Se,isEmbedded:ve,getHostProps:Ce,initHost:B,PROP_SERIALIZATION:v,CONTEXT:p,EVENT:m,PopupOpenError:se,VERSION:q,isStandardSchema:E,prop:f};h.AnySchema=z,h.ArraySchema=C,h.BooleanSchema=A,h.CONTEXT=p,h.EVENT=m,h.EnumSchema=W,h.ForgeFrame=Ne,h.FunctionSchema=U,h.LiteralSchema=M,h.NumberSchema=H,h.ObjectSchema=I,h.PROP_SERIALIZATION=v,h.PopupOpenError=se,h.PropSchema=g,h.StringSchema=L,h.VERSION=q,h.create=ie,h.createReactComponent=Te,h.default=Ne,h.destroy=De,h.destroyAll=xe,h.destroyByTag=re,h.getHostProps=Ce,h.initHost=B,h.isEmbedded=ve,h.isHost=Se,h.isStandardSchema=E,h.prop=f,h.withReactComponent=Tt,Object.defineProperties(h,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* }).render('#container');
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
|
-
import { create, destroy, destroyByTag, destroyAll, isHost, isEmbedded, getHostProps } from './core';
|
|
32
|
+
import { create, destroy, destroyByTag, destroyAll, isHost, isEmbedded, getHostProps, initHost } from './core';
|
|
33
33
|
import { PopupOpenError } from './render/popup';
|
|
34
34
|
import { isStandardSchema } from './props/schema';
|
|
35
35
|
/**
|
|
@@ -122,6 +122,17 @@ export declare const ForgeFrame: {
|
|
|
122
122
|
* @returns The hostProps object if in host context, undefined otherwise
|
|
123
123
|
*/
|
|
124
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;
|
|
125
136
|
/**
|
|
126
137
|
* Serialization strategy constants.
|
|
127
138
|
* @see {@link PROP_SERIALIZATION}
|
|
@@ -220,7 +231,7 @@ export declare const ForgeFrame: {
|
|
|
220
231
|
* @public
|
|
221
232
|
*/
|
|
222
233
|
export default ForgeFrame;
|
|
223
|
-
export { create, destroy, destroyByTag, destroyAll, isHost, isEmbedded, getHostProps, } from './core';
|
|
234
|
+
export { create, destroy, destroyByTag, destroyAll, isHost, isEmbedded, getHostProps, initHost, } from './core';
|
|
224
235
|
export { PROP_SERIALIZATION, CONTEXT, EVENT, VERSION, } from './constants';
|
|
225
236
|
export { PopupOpenError } from './render/popup';
|
|
226
237
|
export { isStandardSchema } from './props/schema';
|
package/dist/types.d.ts
CHANGED
|
@@ -363,8 +363,8 @@ export type ChildrenDefinition<P = Record<string, unknown>> = (props: {
|
|
|
363
363
|
export interface HostComponentRef {
|
|
364
364
|
/** Component tag name */
|
|
365
365
|
tag: string;
|
|
366
|
-
/** Component URL
|
|
367
|
-
url: string
|
|
366
|
+
/** Component URL */
|
|
367
|
+
url: string;
|
|
368
368
|
/** Prop definitions */
|
|
369
369
|
props?: PropsDefinition<Record<string, unknown>>;
|
|
370
370
|
/** Default dimensions */
|