forgeframe 0.0.10 → 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,3 +1,6 @@
1
+ function ce() {
2
+ return typeof window < "u" && typeof window.location < "u";
3
+ }
1
4
  const f = {
2
5
  /** Render component in an iframe */
3
6
  IFRAME: "iframe",
@@ -26,19 +29,19 @@ const f = {
26
29
  RESIZE: "resize",
27
30
  /** Emitted when component receives focus */
28
31
  FOCUS: "focus"
29
- }, z = {
32
+ }, k = {
30
33
  /** Default JSON serialization */
31
34
  JSON: "json",
32
35
  /** Base64 encoding for binary or large data */
33
36
  BASE64: "base64",
34
37
  /** Explicit framed-path encoding for nested objects */
35
38
  DOTIFY: "dotify"
36
- }, W = {
39
+ }, j = {
37
40
  /** Request message expecting a response */
38
41
  REQUEST: "request",
39
42
  /** Response to a previous request */
40
43
  RESPONSE: "response"
41
- }, u = {
44
+ }, l = {
42
45
  /** Host initialization complete */
43
46
  INIT: "forgeframe_init",
44
47
  /** Props update from consumer to host */
@@ -63,14 +66,107 @@ const f = {
63
66
  CONSUMER_EXPORT: "forgeframe_consumer_export",
64
67
  /** Get sibling components request */
65
68
  GET_SIBLINGS: "forgeframe_get_siblings"
66
- }, j = "__forgeframe__", ae = (() => {
67
- if ("0.0.10".trim().length === 0)
69
+ }, B = "__forgeframe__", ue = (() => {
70
+ if ("0.0.13".trim().length === 0)
68
71
  throw new Error(
69
72
  "ForgeFrame VERSION injection is missing. Configure __FORGEFRAME_VERSION__ in build/test tooling."
70
73
  );
71
- return "0.0.10";
72
- })();
73
- class Ae {
74
+ return "0.0.13";
75
+ })(), ot = [
76
+ "init",
77
+ "close",
78
+ "resize",
79
+ "show",
80
+ "hide",
81
+ "onError",
82
+ "updateProps",
83
+ "export"
84
+ ], ve = 32 * 1024;
85
+ function at(t) {
86
+ const e = ft(t);
87
+ return `${B}${e}`;
88
+ }
89
+ function ze(t) {
90
+ if (!t || !t.startsWith(B))
91
+ return null;
92
+ const e = t.slice(B.length);
93
+ return mt(e);
94
+ }
95
+ function R(t) {
96
+ return typeof t == "object" && t !== null;
97
+ }
98
+ function ct(t) {
99
+ return R(t);
100
+ }
101
+ function ut(t) {
102
+ return R(t) && ot.every(
103
+ (e) => typeof t[e] == "string" && t[e].length > 0
104
+ );
105
+ }
106
+ function lt(t) {
107
+ 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 !== f.IFRAME && t.defaultContext !== f.POPUP)
108
+ return !1;
109
+ if (t.dimensions !== void 0) {
110
+ if (!R(t.dimensions))
111
+ return !1;
112
+ const { width: e, height: n } = t.dimensions;
113
+ if (e !== void 0 && typeof e != "string" && typeof e != "number" || n !== void 0 && typeof n != "string" && typeof n != "number")
114
+ return !1;
115
+ }
116
+ return !0;
117
+ }
118
+ function dt(t) {
119
+ return R(t) ? Object.values(t).every((e) => lt(e)) : !1;
120
+ }
121
+ function ht(t) {
122
+ 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 !== ue || t.context !== f.IFRAME && t.context !== f.POPUP || typeof t.consumerDomain != "string" || t.consumerDomain.length === 0 || !ct(t.props) || !ut(t.exports) || t.children !== void 0 && !dt(t.children));
123
+ }
124
+ function le(t = window) {
125
+ try {
126
+ return t.name.startsWith(B);
127
+ } catch {
128
+ return !1;
129
+ }
130
+ }
131
+ function pt(t, e = window) {
132
+ return ze(e.name)?.tag === t;
133
+ }
134
+ function ft(t) {
135
+ try {
136
+ const e = JSON.stringify(t), n = btoa(encodeURIComponent(e)), s = n.length;
137
+ if (s > ve)
138
+ throw new Error(
139
+ `Payload size (${Math.round(s / 1024)}KB) exceeds maximum allowed size (${ve / 1024}KB). Consider reducing the amount of data passed via props.`
140
+ );
141
+ return n;
142
+ } catch (e) {
143
+ throw e instanceof Error && e.message.includes("Payload size") ? e : new Error(`Failed to encode payload: ${e}`);
144
+ }
145
+ }
146
+ function mt(t) {
147
+ try {
148
+ const e = decodeURIComponent(atob(t)), n = JSON.parse(e);
149
+ return ht(n) ? n : null;
150
+ } catch {
151
+ return null;
152
+ }
153
+ }
154
+ function gt(t) {
155
+ return {
156
+ uid: t.uid,
157
+ tag: t.tag,
158
+ version: ue,
159
+ context: t.context,
160
+ consumerDomain: t.consumerDomain,
161
+ props: t.props,
162
+ exports: t.exports,
163
+ children: t.children
164
+ };
165
+ }
166
+ function yt(t = window) {
167
+ return ze(t.name);
168
+ }
169
+ class Le {
74
170
  /**
75
171
  * Internal storage for event listeners mapped by event name.
76
172
  * @internal
@@ -221,249 +317,243 @@ class Ae {
221
317
  return this.listeners.get(e)?.size ?? 0;
222
318
  }
223
319
  }
224
- function tt() {
320
+ function wt() {
225
321
  const t = Date.now().toString(36), e = Math.random().toString(36).slice(2, 11);
226
322
  return `${t}_${e}`;
227
323
  }
228
- function k() {
324
+ function W() {
229
325
  return Math.random().toString(36).slice(2, 11);
230
326
  }
231
- class nt {
327
+ const Te = 500, _t = /* @__PURE__ */ new Set(["__proto__"]);
328
+ function ke(t) {
329
+ return !_t.has(t);
330
+ }
331
+ class de {
232
332
  /**
233
- * Array of registered cleanup tasks awaiting execution.
234
- * @internal
333
+ * Creates a new FunctionBridge instance.
334
+ *
335
+ * @param messenger - The messenger to use for cross-domain calls
235
336
  */
236
- tasks = [];
337
+ constructor(e) {
338
+ this.messenger = e, this.setupCallHandler();
339
+ }
340
+ /** @internal */
341
+ localFunctions = /* @__PURE__ */ new Map();
342
+ /** @internal */
343
+ remoteFunctions = /* @__PURE__ */ new Map();
237
344
  /**
238
- * Flag indicating whether cleanup has already been performed.
345
+ * Tracks function IDs from the current serialization batch.
346
+ * Used for cleanup of stale references when props are updated.
239
347
  * @internal
240
348
  */
241
- cleaned = !1;
349
+ currentBatchIds = /* @__PURE__ */ new Set();
242
350
  /**
243
- * Registers a cleanup task to be executed when {@link cleanup} is called.
244
- *
245
- * @param task - The cleanup function to register
246
- *
247
- * @remarks
248
- * If cleanup has already been performed, the task is scheduled on a microtask
249
- * and executed asynchronously rather than being registered. This ensures
250
- * late-registered tasks are still handled appropriately while safely capturing
251
- * both sync and async task failures.
252
- *
253
- * @example
254
- * ```typescript
255
- * cleanup.register(() => {
256
- * eventEmitter.removeAllListeners();
257
- * });
258
- *
259
- * cleanup.register(async () => {
260
- * await database.close();
261
- * });
262
- * ```
351
+ * Serializes a local function to a transferable reference.
263
352
  *
264
- * @public
353
+ * @param fn - The function to serialize
354
+ * @param name - Optional name for debugging
355
+ * @returns A function reference that can be sent across domains
265
356
  */
266
- register(e) {
267
- if (this.cleaned) {
268
- Promise.resolve().then(() => e()).catch((n) => {
269
- console.error("Error in cleanup task:", n);
270
- });
271
- return;
357
+ serialize(e, n) {
358
+ if (this.localFunctions.size >= Te) {
359
+ const r = this.localFunctions.keys().next().value;
360
+ r && this.localFunctions.delete(r);
272
361
  }
273
- this.tasks.push(e);
362
+ const s = W();
363
+ return this.localFunctions.set(s, e), this.currentBatchIds.add(s), {
364
+ __type__: "function",
365
+ __id__: s,
366
+ __name__: n || e.name || "anonymous"
367
+ };
274
368
  }
275
369
  /**
276
- * Executes all registered cleanup tasks in LIFO order.
277
- *
278
- * @returns A Promise that resolves when all cleanup tasks have completed
370
+ * Deserializes a function reference to a callable wrapper.
279
371
  *
280
372
  * @remarks
281
- * Tasks are executed in reverse order of registration (LIFO pattern).
282
- * Each task is awaited individually, and errors are caught and logged
283
- * to prevent one failing task from blocking subsequent cleanup operations.
284
- * Calling this method multiple times has no effect after the first call.
373
+ * The returned function, when called, will invoke the original function
374
+ * in the remote window via postMessage and return the result.
285
375
  *
286
- * @example
287
- * ```typescript
288
- * // In a component's destroy lifecycle
289
- * async destroy() {
290
- * await this.cleanupManager.cleanup();
291
- * }
292
- * ```
376
+ * @param ref - The function reference to deserialize
377
+ * @param targetWin - The window containing the original function
378
+ * @param targetDomain - The origin of the target window
379
+ * @returns A callable wrapper function
380
+ */
381
+ deserialize(e, n, s) {
382
+ const r = `${e.__id__}`, i = this.remoteFunctions.get(r);
383
+ if (i) return i;
384
+ if (this.remoteFunctions.size >= Te) {
385
+ const a = this.remoteFunctions.keys().next().value;
386
+ a && this.remoteFunctions.delete(a);
387
+ }
388
+ const o = async (...a) => this.messenger.send(n, s, l.CALL, {
389
+ id: e.__id__,
390
+ args: a
391
+ });
392
+ return Object.defineProperty(o, "name", {
393
+ value: e.__name__,
394
+ configurable: !0
395
+ }), this.remoteFunctions.set(r, o), o;
396
+ }
397
+ /**
398
+ * Type guard to check if a value is a function reference.
293
399
  *
294
- * @public
400
+ * @param value - The value to check
401
+ * @returns True if the value is a FunctionRef
295
402
  */
296
- async cleanup() {
297
- if (this.cleaned) return;
298
- this.cleaned = !0;
299
- const e = this.tasks.reverse();
300
- this.tasks = [];
301
- for (const n of e)
302
- try {
303
- await n();
304
- } catch (s) {
305
- console.error("Error in cleanup task:", s);
403
+ static isFunctionRef(e) {
404
+ return typeof e == "object" && e !== null && e.__type__ === "function" && typeof e.__id__ == "string";
405
+ }
406
+ /**
407
+ * Sets up the handler for incoming function call messages.
408
+ * @internal
409
+ */
410
+ setupCallHandler() {
411
+ this.messenger.on(
412
+ l.CALL,
413
+ async ({ id: e, args: n }) => {
414
+ const s = this.localFunctions.get(e);
415
+ if (!s)
416
+ throw new Error(`Function with id "${e}" not found`);
417
+ return s(...n);
306
418
  }
419
+ );
307
420
  }
308
421
  /**
309
- * Checks whether cleanup has already been performed.
422
+ * Removes a local function reference.
310
423
  *
311
- * @returns `true` if {@link cleanup} has been called, `false` otherwise
424
+ * @param id - The function reference ID to remove
425
+ */
426
+ removeLocal(e) {
427
+ this.localFunctions.delete(e);
428
+ }
429
+ /**
430
+ * Starts a new serialization batch.
431
+ *
432
+ * @remarks
433
+ * Call this before serializing a new set of props. After serialization,
434
+ * call {@link finishBatch} to clean up functions from previous batches.
312
435
  *
313
436
  * @example
314
437
  * ```typescript
315
- * if (!cleanupManager.isCleaned()) {
316
- * // Safe to register more tasks
317
- * cleanupManager.register(myTask);
318
- * }
438
+ * bridge.startBatch();
439
+ * const serialized = serializeFunctions(props, bridge);
440
+ * bridge.finishBatch();
319
441
  * ```
320
- *
321
- * @public
322
442
  */
323
- isCleaned() {
324
- return this.cleaned;
443
+ startBatch() {
444
+ this.currentBatchIds.clear();
325
445
  }
326
446
  /**
327
- * Resets the manager to its initial state, allowing it to be reused.
447
+ * Finishes the current batch and removes functions not in this batch.
328
448
  *
329
449
  * @remarks
330
- * This method clears all registered tasks and resets the cleaned flag.
331
- * It is primarily intended for testing scenarios or cases where the
332
- * manager needs to be reused after cleanup.
450
+ * This cleans up function references from previous prop updates that
451
+ * are no longer needed, preventing memory leaks.
333
452
  *
334
- * @example
335
- * ```typescript
336
- * // In a test teardown
337
- * afterEach(() => {
338
- * cleanupManager.reset();
339
- * });
340
- * ```
453
+ * @param keepPrevious - If true, keeps previous batch functions (default: false)
454
+ */
455
+ finishBatch(e = !1) {
456
+ if (e) {
457
+ this.currentBatchIds.clear();
458
+ return;
459
+ }
460
+ for (const n of this.localFunctions.keys())
461
+ this.currentBatchIds.has(n) || this.localFunctions.delete(n);
462
+ this.currentBatchIds.clear();
463
+ }
464
+ /**
465
+ * Clears all remote function references.
341
466
  *
342
- * @public
467
+ * @remarks
468
+ * Call this when the remote window is no longer accessible
469
+ * (e.g., closed or navigated away).
343
470
  */
344
- reset() {
345
- this.tasks = [], this.cleaned = !1;
471
+ clearRemote() {
472
+ this.remoteFunctions.clear();
346
473
  }
347
- }
348
- function Le() {
349
- let t, e;
350
- return { promise: new Promise((s, r) => {
351
- t = s, e = r;
352
- }), resolve: t, reject: e };
353
- }
354
- function st(t, e, n = "Operation timed out") {
355
- return new Promise((s, r) => {
356
- const i = setTimeout(() => {
357
- r(new Error(`${n} (${e}ms)`));
358
- }, e);
359
- t.then((o) => {
360
- clearTimeout(i), s(o);
361
- }).catch((o) => {
362
- clearTimeout(i), r(o);
363
- });
364
- });
365
- }
366
- const S = /* @__PURE__ */ new Map(), rt = 200;
367
- function it(t) {
368
- return t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
369
- }
370
- function ot(t) {
371
- if (!t.includes("*"))
372
- return null;
373
- const e = S.get(t);
374
- if (e)
375
- return e;
376
- const n = t.split("*").map((r) => it(r)).join(".*"), s = new RegExp(`^${n}$`);
377
- if (S.size >= rt) {
378
- const r = S.keys().next().value;
379
- r && S.delete(r);
380
- }
381
- return S.set(t, s), s;
382
- }
383
- function at(t, e) {
384
- return t.global || t.sticky ? new RegExp(t.source, t.flags.replace(/[gy]/g, "")).test(e) : t.test(e);
385
- }
386
- function B(t = window) {
387
- try {
388
- return t.location.origin;
389
- } catch {
390
- return "";
391
- }
392
- }
393
- function Me(t, e = window) {
394
- try {
395
- return t.location.origin === e.location.origin;
396
- } catch {
397
- return !1;
398
- }
399
- }
400
- function U(t, e) {
401
- if (typeof t == "string") {
402
- if (t === "*") return !0;
403
- const n = ot(t);
404
- return n ? n.test(e) : t === e;
474
+ /**
475
+ * Returns the current number of registered local functions.
476
+ * Useful for debugging and monitoring.
477
+ */
478
+ get localFunctionCount() {
479
+ return this.localFunctions.size;
405
480
  }
406
- return t instanceof RegExp ? at(t, e) : Array.isArray(t) ? t.some((n) => U(n, e)) : !1;
407
- }
408
- function se(t) {
409
- if (!t) return !0;
410
- try {
411
- return t.closed;
412
- } catch {
413
- return !0;
481
+ /**
482
+ * Returns the current number of cached remote functions.
483
+ * Useful for debugging and monitoring.
484
+ */
485
+ get remoteFunctionCount() {
486
+ return this.remoteFunctions.size;
414
487
  }
415
- }
416
- function ct(t = window) {
417
- try {
418
- return t.opener;
419
- } catch {
420
- return null;
488
+ /**
489
+ * Cleans up all function references.
490
+ */
491
+ destroy() {
492
+ this.localFunctions.clear(), this.remoteFunctions.clear(), this.currentBatchIds.clear();
421
493
  }
422
494
  }
423
- function lt(t = window) {
424
- try {
425
- const e = t.parent;
426
- return e && e !== t ? e : null;
427
- } catch {
428
- return null;
495
+ function se(t, e, n = /* @__PURE__ */ new WeakSet()) {
496
+ if (typeof t == "function")
497
+ return e.serialize(t);
498
+ if (Array.isArray(t)) {
499
+ if (n.has(t))
500
+ throw new Error("Circular reference detected in props - arrays cannot contain circular references");
501
+ n.add(t);
502
+ try {
503
+ return t.map((s) => se(s, e, n));
504
+ } finally {
505
+ n.delete(t);
506
+ }
429
507
  }
430
- }
431
- function ut(t = window) {
432
- try {
433
- return t.parent !== t;
434
- } catch {
435
- return !0;
508
+ if (typeof t == "object" && t !== null) {
509
+ if (n.has(t))
510
+ throw new Error("Circular reference detected in props - objects cannot contain circular references");
511
+ n.add(t);
512
+ try {
513
+ const s = {};
514
+ for (const [r, i] of Object.entries(t))
515
+ ke(r) && (s[r] = se(i, e, n));
516
+ return s;
517
+ } finally {
518
+ n.delete(t);
519
+ }
436
520
  }
521
+ return t;
437
522
  }
438
- function ht(t = window) {
439
- try {
440
- return t.opener !== null && t.opener !== void 0;
441
- } catch {
442
- return !1;
523
+ function re(t, e, n, s, r = /* @__PURE__ */ new WeakSet()) {
524
+ if (de.isFunctionRef(t))
525
+ return e.deserialize(t, n, s);
526
+ if (Array.isArray(t)) {
527
+ if (r.has(t))
528
+ throw new Error("Circular reference detected in serialized props");
529
+ r.add(t);
530
+ try {
531
+ return t.map(
532
+ (i) => re(i, e, n, s, r)
533
+ );
534
+ } finally {
535
+ r.delete(t);
536
+ }
443
537
  }
444
- }
445
- const De = 100, b = /* @__PURE__ */ new Map();
446
- function dt() {
447
- const t = [];
448
- for (const [e, n] of b.entries())
449
- se(n) && t.push(e);
450
- for (const e of t)
451
- b.delete(e);
452
- }
453
- function pt(t, e) {
454
- if (b.size >= De && dt(), b.size >= De) {
455
- const n = b.keys().next().value;
456
- n && b.delete(n);
538
+ if (typeof t == "object" && t !== null) {
539
+ if (r.has(t))
540
+ throw new Error("Circular reference detected in serialized props");
541
+ r.add(t);
542
+ try {
543
+ const i = {};
544
+ for (const [o, a] of Object.entries(t))
545
+ ke(o) && (i[o] = re(a, e, n, s, r));
546
+ return i;
547
+ } finally {
548
+ r.delete(t);
549
+ }
457
550
  }
458
- b.set(t, e);
459
- }
460
- function ft(t) {
461
- b.delete(t);
551
+ return t;
462
552
  }
463
- function mt(t, e) {
553
+ function Pt(t, e) {
464
554
  return t.global || t.sticky ? new RegExp(t.source, t.flags.replace(/[gy]/g, "")).test(e) : t.test(e);
465
555
  }
466
- class P {
556
+ class E {
467
557
  /** @internal */
468
558
  _optional = !1;
469
559
  /** @internal */
@@ -530,7 +620,7 @@ class P {
530
620
  return n._default = e, n;
531
621
  }
532
622
  }
533
- class ce extends P {
623
+ class he extends E {
534
624
  /** @internal */
535
625
  _minLength;
536
626
  /** @internal */
@@ -556,7 +646,7 @@ class ce extends P {
556
646
  issues: [
557
647
  { message: `String must be at most ${this._maxLength} characters` }
558
648
  ]
559
- } : this._pattern && !mt(this._pattern, n) ? {
649
+ } : this._pattern && !Pt(this._pattern, n) ? {
560
650
  issues: [
561
651
  {
562
652
  message: this._patternMessage || `String must match pattern ${this._pattern}`
@@ -566,7 +656,7 @@ class ce extends P {
566
656
  }
567
657
  /** @internal */
568
658
  _clone() {
569
- const e = new ce();
659
+ const e = new he();
570
660
  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;
571
661
  }
572
662
  /**
@@ -691,7 +781,7 @@ class ce extends P {
691
781
  return e._minLength = 1, e;
692
782
  }
693
783
  }
694
- class le extends P {
784
+ class pe extends E {
695
785
  /** @internal */
696
786
  _min;
697
787
  /** @internal */
@@ -706,7 +796,7 @@ class le extends P {
706
796
  }
707
797
  /** @internal */
708
798
  _clone() {
709
- const e = new le();
799
+ const e = new pe();
710
800
  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;
711
801
  }
712
802
  /**
@@ -786,7 +876,7 @@ class le extends P {
786
876
  return e._max = -Number.MIN_VALUE, e;
787
877
  }
788
878
  }
789
- class ue extends P {
879
+ class fe extends E {
790
880
  /** @internal */
791
881
  _validate(e) {
792
882
  return typeof e != "boolean" ? {
@@ -795,11 +885,11 @@ class ue extends P {
795
885
  }
796
886
  /** @internal */
797
887
  _clone() {
798
- const e = new ue();
888
+ const e = new fe();
799
889
  return e._optional = this._optional, e._nullable = this._nullable, e._default = this._default, e;
800
890
  }
801
891
  }
802
- class he extends P {
892
+ class me extends E {
803
893
  /** @internal */
804
894
  _validate(e) {
805
895
  return typeof e != "function" ? {
@@ -808,11 +898,11 @@ class he extends P {
808
898
  }
809
899
  /** @internal */
810
900
  _clone() {
811
- const e = new he();
901
+ const e = new me();
812
902
  return e._optional = this._optional, e._nullable = this._nullable, e._default = this._default, e;
813
903
  }
814
904
  }
815
- class V extends P {
905
+ class V extends E {
816
906
  /** @internal */
817
907
  _itemSchema;
818
908
  /** @internal */
@@ -919,7 +1009,7 @@ class V extends P {
919
1009
  return this.min(1);
920
1010
  }
921
1011
  }
922
- class Y extends P {
1012
+ class Y extends E {
923
1013
  /** @internal */
924
1014
  _shape;
925
1015
  /** @internal */
@@ -1002,7 +1092,7 @@ class Y extends P {
1002
1092
  return e._strict = !0, e;
1003
1093
  }
1004
1094
  }
1005
- class de extends P {
1095
+ class ge extends E {
1006
1096
  /** @internal */
1007
1097
  _value;
1008
1098
  constructor(e) {
@@ -1016,11 +1106,11 @@ class de extends P {
1016
1106
  }
1017
1107
  /** @internal */
1018
1108
  _clone() {
1019
- const e = new de(this._value);
1109
+ const e = new ge(this._value);
1020
1110
  return e._optional = this._optional, e._nullable = this._nullable, e._default = this._default, e;
1021
1111
  }
1022
1112
  }
1023
- class pe extends P {
1113
+ class ye extends E {
1024
1114
  /** @internal */
1025
1115
  _values;
1026
1116
  /** @internal */
@@ -1040,11 +1130,11 @@ class pe extends P {
1040
1130
  }
1041
1131
  /** @internal */
1042
1132
  _clone() {
1043
- const e = new pe(this._values);
1133
+ const e = new ye(this._values);
1044
1134
  return e._optional = this._optional, e._nullable = this._nullable, e._default = this._default, e;
1045
1135
  }
1046
1136
  }
1047
- class fe extends P {
1137
+ class we extends E {
1048
1138
  constructor() {
1049
1139
  super(), this._nullable = !0;
1050
1140
  }
@@ -1054,7 +1144,7 @@ class fe extends P {
1054
1144
  }
1055
1145
  /** @internal */
1056
1146
  _clone() {
1057
- const e = new fe();
1147
+ const e = new we();
1058
1148
  return e._optional = this._optional, e._nullable = this._nullable, e._default = this._default, e;
1059
1149
  }
1060
1150
  }
@@ -1071,7 +1161,7 @@ const p = {
1071
1161
  * prop.string().pattern(/^[a-z]+$/)
1072
1162
  * ```
1073
1163
  */
1074
- string: () => new ce(),
1164
+ string: () => new he(),
1075
1165
  /**
1076
1166
  * Creates a number schema.
1077
1167
  *
@@ -1083,7 +1173,7 @@ const p = {
1083
1173
  * prop.number().positive()
1084
1174
  * ```
1085
1175
  */
1086
- number: () => new le(),
1176
+ number: () => new pe(),
1087
1177
  /**
1088
1178
  * Creates a boolean schema.
1089
1179
  *
@@ -1093,7 +1183,7 @@ const p = {
1093
1183
  * prop.boolean().default(false)
1094
1184
  * ```
1095
1185
  */
1096
- boolean: () => new ue(),
1186
+ boolean: () => new fe(),
1097
1187
  /**
1098
1188
  * Creates a function schema.
1099
1189
  *
@@ -1106,7 +1196,7 @@ const p = {
1106
1196
  * prop.function<(data: { id: string }) => Promise<void>>()
1107
1197
  * ```
1108
1198
  */
1109
- function: () => new he(),
1199
+ function: () => new me(),
1110
1200
  /**
1111
1201
  * Creates an array schema.
1112
1202
  *
@@ -1148,7 +1238,7 @@ const p = {
1148
1238
  * prop.literal(true)
1149
1239
  * ```
1150
1240
  */
1151
- literal: (t) => new de(t),
1241
+ literal: (t) => new ge(t),
1152
1242
  /**
1153
1243
  * Creates an enum schema for a set of allowed values.
1154
1244
  *
@@ -1160,7 +1250,7 @@ const p = {
1160
1250
  * prop.enum([1, 2, 3])
1161
1251
  * ```
1162
1252
  */
1163
- enum: (t) => new pe(t),
1253
+ enum: (t) => new ye(t),
1164
1254
  /**
1165
1255
  * Creates a schema that accepts any value.
1166
1256
  *
@@ -1172,8 +1262,8 @@ const p = {
1172
1262
  * prop.any()
1173
1263
  * ```
1174
1264
  */
1175
- any: () => new fe()
1176
- }, R = {
1265
+ any: () => new we()
1266
+ }, D = {
1177
1267
  uid: {
1178
1268
  schema: p.string().optional(),
1179
1269
  sendToHost: !0
@@ -1239,511 +1329,535 @@ const p = {
1239
1329
  schema: p.function().optional(),
1240
1330
  sendToHost: !1
1241
1331
  }
1242
- };
1243
- function D(t) {
1244
- 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";
1332
+ }, Et = /* @__PURE__ */ new Set(["__proto__"]), We = "__forgeframe.dotify_path__:", J = "__forgeframe.dotify_empty_object_path__:", je = "__forgeframe.dotify_empty_object__";
1333
+ function Be(t) {
1334
+ return !Et.has(t);
1245
1335
  }
1246
- function gt(t, e, n) {
1247
- const s = t["~standard"].validate(e);
1248
- if (s instanceof Promise)
1249
- throw new Error(
1250
- `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.`
1251
- );
1252
- if (s.issues) {
1253
- const r = s.issues.map((i) => `${yt(i.path, n)}: ${i.message}`);
1254
- throw new Error(`Validation failed: ${r.join("; ")}`);
1336
+ function He(t) {
1337
+ if (t === null || typeof t != "object" || Array.isArray(t))
1338
+ return !1;
1339
+ const e = Object.getPrototypeOf(t);
1340
+ return e === Object.prototype || e === null;
1341
+ }
1342
+ function Ve(t, e = We) {
1343
+ return `${e}${encodeURIComponent(JSON.stringify(t))}`;
1344
+ }
1345
+ function bt(t) {
1346
+ return encodeURIComponent(JSON.stringify(t));
1347
+ }
1348
+ function Ct(t, e) {
1349
+ return `${Ve(t)}=${bt(e)}`;
1350
+ }
1351
+ function Ot(t) {
1352
+ return `${Ve(t, J)}=1`;
1353
+ }
1354
+ function Rt(t, e, n) {
1355
+ Object.defineProperty(t, e, {
1356
+ configurable: !0,
1357
+ enumerable: !0,
1358
+ writable: !0,
1359
+ value: n
1360
+ });
1361
+ }
1362
+ function Ye(t, e = []) {
1363
+ const n = Object.entries(t);
1364
+ if (n.length === 0 && He(t))
1365
+ return e.length === 0 ? je : Ot(e);
1366
+ const s = [];
1367
+ for (const [r, i] of n) {
1368
+ if (i === void 0) continue;
1369
+ const o = [...e, r];
1370
+ He(i) ? s.push(Ye(i, o)) : s.push(Ct(o, i));
1255
1371
  }
1256
- return s.value;
1372
+ return s.filter(Boolean).join("&");
1257
1373
  }
1258
- function yt(t, e) {
1259
- if (!t || t.length === 0)
1260
- return e;
1261
- const n = t.map((s) => {
1262
- if (typeof s == "object" && s !== null) {
1263
- if ("key" in s && s.key !== void 0)
1264
- return String(s.key);
1265
- if ("index" in s && typeof s.index == "number")
1266
- return String(s.index);
1374
+ function Dt(t) {
1375
+ const e = {};
1376
+ if (!t || t === je) return e;
1377
+ const n = t.split("&");
1378
+ for (const s of n) {
1379
+ const r = s.indexOf("=");
1380
+ if (r === -1) continue;
1381
+ const i = s.slice(0, r), o = s.slice(r + 1);
1382
+ if (!i || o === void 0) continue;
1383
+ const a = i.startsWith(J);
1384
+ let c;
1385
+ if (a) {
1386
+ if (o !== "1")
1387
+ throw new Error("Invalid empty-object DOTIFY entry");
1388
+ c = {};
1389
+ } else
1390
+ try {
1391
+ c = JSON.parse(decodeURIComponent(o));
1392
+ } catch {
1393
+ c = decodeURIComponent(o);
1394
+ }
1395
+ const u = St(i);
1396
+ if (u.some((h) => !Be(h))) continue;
1397
+ let d = e;
1398
+ for (let h = 0; h < u.length - 1; h++) {
1399
+ const b = u[h], O = d[b];
1400
+ (!Object.prototype.hasOwnProperty.call(d, b) || typeof O != "object" || O === null || Array.isArray(O)) && (d[b] = {}), d = d[b];
1267
1401
  }
1268
- return String(s);
1269
- });
1270
- return `${e}.${n.join(".")}`;
1402
+ const m = u[u.length - 1];
1403
+ Rt(d, m, c);
1404
+ }
1405
+ return e;
1271
1406
  }
1272
- function H(t) {
1273
- const e = D(t);
1274
- return { isDirectSchema: e, definition: e ? { schema: t } : t };
1407
+ function St(t) {
1408
+ const e = t.startsWith(J) ? J : We;
1409
+ if (!t.startsWith(e))
1410
+ throw new Error("Invalid DOTIFY path framing");
1411
+ const n = decodeURIComponent(t.slice(e.length)), s = JSON.parse(n);
1412
+ if (Array.isArray(s) && s.length > 0 && s.every((r) => typeof r == "string"))
1413
+ return s;
1414
+ throw new Error("Invalid DOTIFY path framing");
1415
+ }
1416
+ function xt(t) {
1417
+ return typeof t == "object" && t !== null && t.__type__ === "dotify" && typeof t.__value__ == "string";
1275
1418
  }
1276
- function Ie(t, e, n) {
1419
+ function It(t, e, n) {
1277
1420
  const s = {
1278
- ...R,
1421
+ ...D,
1279
1422
  ...e
1280
1423
  }, r = {};
1281
- for (const [i, o] of Object.entries(s)) {
1282
- const { definition: a } = H(o);
1283
- let c;
1284
- const l = a.alias, d = i in t, m = l && l in t;
1285
- if (d)
1286
- c = t[i];
1287
- else if (m)
1288
- c = t[l];
1289
- else if (a.value)
1290
- c = a.value(n);
1291
- else if (a.default !== void 0)
1292
- c = typeof a.default == "function" ? a.default(n) : a.default;
1293
- else if (a.schema && D(a.schema)) {
1294
- const h = a.schema["~standard"].validate(void 0);
1295
- !(h instanceof Promise) && !h.issues && (c = h.value);
1296
- }
1297
- c !== void 0 && a.decorate && (c = a.decorate({ value: c, props: r })), r[i] = c;
1424
+ for (const [i, o] of Object.entries(t)) {
1425
+ if (o === void 0) continue;
1426
+ const a = s[i];
1427
+ r[i] = vt(o, a, n);
1298
1428
  }
1299
1429
  return r;
1300
1430
  }
1301
- function T(t, e) {
1302
- const n = {
1303
- ...R,
1304
- ...e
1305
- };
1306
- for (const [s, r] of Object.entries(n)) {
1307
- const { isDirectSchema: i, definition: o } = H(r);
1308
- let a = t[s];
1309
- if (o.required && a === void 0)
1310
- throw new Error(`Prop "${s}" is required but was not provided`);
1311
- if (o.schema && D(o.schema))
1312
- (a !== void 0 || i) && (a = gt(o.schema, a, s), t[s] = a);
1313
- else if (a === void 0)
1314
- continue;
1315
- o.validate && o.validate({ value: a, props: t });
1431
+ function vt(t, e, n) {
1432
+ if (typeof t == "function")
1433
+ return n.serialize(t);
1434
+ const s = e?.serialization ?? k.JSON;
1435
+ if (s === k.BASE64 && typeof t == "object") {
1436
+ const r = JSON.stringify(t);
1437
+ return {
1438
+ __type__: "base64",
1439
+ __value__: btoa(encodeURIComponent(r))
1440
+ };
1316
1441
  }
1442
+ return s === k.DOTIFY && typeof t == "object" && t !== null && !Array.isArray(t) ? {
1443
+ __type__: "dotify",
1444
+ __value__: Ye(t)
1445
+ } : se(t, n);
1317
1446
  }
1318
- function Se(t, e, n, s) {
1319
- const r = {
1320
- ...R,
1447
+ function Tt(t, e, n, s, r, i) {
1448
+ const o = {
1449
+ ...D,
1321
1450
  ...e
1322
- }, i = {};
1323
- for (const [o, a] of Object.entries(r)) {
1324
- const { definition: c } = H(a), l = t[o];
1325
- if (c.sendToHost === !1 || c.sameDomain && !s) continue;
1326
- if (c.trustedDomains) {
1451
+ }, a = {};
1452
+ for (const [c, u] of Object.entries(t)) {
1453
+ if (!Be(c)) continue;
1454
+ const d = o[c];
1455
+ a[c] = Ht(
1456
+ u,
1457
+ d,
1458
+ n,
1459
+ s,
1460
+ r,
1461
+ i
1462
+ );
1463
+ }
1464
+ return a;
1465
+ }
1466
+ function Ht(t, e, n, s, r, i) {
1467
+ if (Ut(t))
1468
+ try {
1469
+ const o = decodeURIComponent(atob(t.__value__));
1470
+ return JSON.parse(o);
1471
+ } catch {
1472
+ return t;
1473
+ }
1474
+ if (xt(t))
1475
+ try {
1476
+ return Dt(t.__value__);
1477
+ } catch {
1478
+ return t;
1479
+ }
1480
+ return re(t, s, r, i);
1481
+ }
1482
+ function Ut(t) {
1483
+ return typeof t == "object" && t !== null && t.__type__ === "base64" && typeof t.__value__ == "string";
1484
+ }
1485
+ const v = /* @__PURE__ */ new Map(), Ft = 200;
1486
+ function Nt(t) {
1487
+ return t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1488
+ }
1489
+ function Je(t) {
1490
+ if (!t.includes("*"))
1491
+ return null;
1492
+ const e = v.get(t);
1493
+ if (e)
1494
+ return e;
1495
+ const n = t.split("*").map((r) => Nt(r)).join(".*"), s = new RegExp(`^${n}$`);
1496
+ if (v.size >= Ft) {
1497
+ const r = v.keys().next().value;
1498
+ r && v.delete(r);
1499
+ }
1500
+ return v.set(t, s), s;
1501
+ }
1502
+ function ie(t, e) {
1503
+ return t.global || t.sticky ? new RegExp(t.source, t.flags.replace(/[gy]/g, "")).test(e) : t.test(e);
1504
+ }
1505
+ function q(t = window) {
1506
+ try {
1507
+ return t.location.origin;
1508
+ } catch {
1509
+ return "";
1510
+ }
1511
+ }
1512
+ function qe(t, e = window) {
1513
+ try {
1514
+ return t.location.origin === e.location.origin;
1515
+ } catch {
1516
+ return !1;
1517
+ }
1518
+ }
1519
+ function X(t, e) {
1520
+ if (typeof t == "string") {
1521
+ if (t === "*") return !0;
1522
+ const n = Je(t);
1523
+ return n ? ie(n, e) : t === e;
1524
+ }
1525
+ return t instanceof RegExp ? ie(t, e) : Array.isArray(t) ? t.some((n) => X(n, e)) : !1;
1526
+ }
1527
+ function oe(t) {
1528
+ if (!t) return !0;
1529
+ try {
1530
+ return t.closed;
1531
+ } catch {
1532
+ return !0;
1533
+ }
1534
+ }
1535
+ function At(t = window) {
1536
+ try {
1537
+ return t.opener;
1538
+ } catch {
1539
+ return null;
1540
+ }
1541
+ }
1542
+ function $t(t = window) {
1543
+ try {
1544
+ const e = t.parent;
1545
+ return e && e !== t ? e : null;
1546
+ } catch {
1547
+ return null;
1548
+ }
1549
+ }
1550
+ function Mt(t = window) {
1551
+ try {
1552
+ return t.parent !== t;
1553
+ } catch {
1554
+ return !0;
1555
+ }
1556
+ }
1557
+ function zt(t = window) {
1558
+ try {
1559
+ return t.opener !== null && t.opener !== void 0;
1560
+ } catch {
1561
+ return !1;
1562
+ }
1563
+ }
1564
+ function x(t) {
1565
+ 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";
1566
+ }
1567
+ function Lt(t, e, n) {
1568
+ const s = t["~standard"].validate(e);
1569
+ if (s instanceof Promise)
1570
+ throw new Error(
1571
+ `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.`
1572
+ );
1573
+ if (s.issues) {
1574
+ const r = s.issues.map((i) => `${kt(i.path, n)}: ${i.message}`);
1575
+ throw new Error(`Validation failed: ${r.join("; ")}`);
1576
+ }
1577
+ return s.value;
1578
+ }
1579
+ function kt(t, e) {
1580
+ if (!t || t.length === 0)
1581
+ return e;
1582
+ const n = t.map((s) => {
1583
+ if (typeof s == "object" && s !== null) {
1584
+ if ("key" in s && s.key !== void 0)
1585
+ return String(s.key);
1586
+ if ("index" in s && typeof s.index == "number")
1587
+ return String(s.index);
1588
+ }
1589
+ return String(s);
1590
+ });
1591
+ return `${e}.${n.join(".")}`;
1592
+ }
1593
+ function N(t) {
1594
+ const e = x(t);
1595
+ return { isDirectSchema: e, definition: e ? { schema: t } : t };
1596
+ }
1597
+ function Ue(t, e, n) {
1598
+ const s = {
1599
+ ...D,
1600
+ ...e
1601
+ }, r = {};
1602
+ for (const [i, o] of Object.entries(s)) {
1603
+ const { definition: a } = N(o);
1604
+ let c;
1605
+ const u = a.alias, d = i in t, m = u && u in t;
1606
+ if (d)
1607
+ c = t[i];
1608
+ else if (m)
1609
+ c = t[u];
1610
+ else if (a.value)
1611
+ c = a.value(n);
1612
+ else if (a.default !== void 0)
1613
+ c = typeof a.default == "function" ? a.default(n) : a.default;
1614
+ else if (a.schema && x(a.schema)) {
1615
+ const h = a.schema["~standard"].validate(void 0);
1616
+ !(h instanceof Promise) && !h.issues && (c = h.value);
1617
+ }
1618
+ c !== void 0 && a.decorate && (c = a.decorate({ value: c, props: r })), r[i] = c;
1619
+ }
1620
+ return r;
1621
+ }
1622
+ function H(t, e) {
1623
+ const n = {
1624
+ ...D,
1625
+ ...e
1626
+ };
1627
+ for (const [s, r] of Object.entries(n)) {
1628
+ const { isDirectSchema: i, definition: o } = N(r);
1629
+ let a = t[s];
1630
+ if (o.required && a === void 0)
1631
+ throw new Error(`Prop "${s}" is required but was not provided`);
1632
+ if (o.schema && x(o.schema))
1633
+ (a !== void 0 || i) && (a = Lt(o.schema, a, s), t[s] = a);
1634
+ else if (a === void 0)
1635
+ continue;
1636
+ o.validate && o.validate({ value: a, props: t });
1637
+ }
1638
+ }
1639
+ function Fe(t, e, n, s) {
1640
+ const r = {
1641
+ ...D,
1642
+ ...e
1643
+ }, i = {};
1644
+ for (const [o, a] of Object.entries(r)) {
1645
+ const { definition: c } = N(a), u = t[o];
1646
+ if (c.sendToHost === !1 || c.sameDomain && !s) continue;
1647
+ if (c.trustedDomains) {
1327
1648
  const m = c.trustedDomains;
1328
- if (!U(m, n)) continue;
1649
+ if (!X(m, n)) continue;
1329
1650
  }
1330
- let d = l;
1331
- c.hostDecorate && l !== void 0 && (d = c.hostDecorate({ value: l, props: t })), i[o] = d;
1651
+ let d = u;
1652
+ c.hostDecorate && u !== void 0 && (d = c.hostDecorate({ value: u, props: t })), i[o] = d;
1332
1653
  }
1333
1654
  return i;
1334
1655
  }
1335
- function wt(t, e) {
1656
+ function Wt(t, e) {
1336
1657
  const n = new URLSearchParams(), s = {
1337
- ...R,
1658
+ ...D,
1338
1659
  ...e
1339
1660
  };
1340
1661
  for (const [r, i] of Object.entries(s)) {
1341
- const { definition: o } = H(i), a = t[r];
1662
+ const { definition: o } = N(i), a = t[r];
1342
1663
  if (a === void 0 || typeof a == "function" || !o.queryParam) continue;
1343
1664
  const c = typeof o.queryParam == "string" ? o.queryParam : r;
1344
- let l;
1345
- typeof o.queryParam == "function" ? l = o.queryParam({ value: a }) : typeof a == "object" ? l = JSON.stringify(a) : l = String(a), n.set(c, l);
1665
+ let u;
1666
+ typeof o.queryParam == "function" ? u = o.queryParam({ value: a }) : typeof a == "object" ? u = JSON.stringify(a) : u = String(a), n.set(c, u);
1346
1667
  }
1347
1668
  return n;
1348
1669
  }
1349
- function _t(t, e) {
1670
+ function jt(t, e) {
1350
1671
  const n = new URLSearchParams(), s = {
1351
- ...R,
1672
+ ...D,
1352
1673
  ...e
1353
1674
  };
1354
1675
  for (const [r, i] of Object.entries(s)) {
1355
- const { definition: o } = H(i), a = t[r];
1676
+ const { definition: o } = N(i), a = t[r];
1356
1677
  if (a === void 0 || typeof a == "function" || !o.bodyParam) continue;
1357
1678
  const c = typeof o.bodyParam == "string" ? o.bodyParam : r;
1358
- let l;
1359
- typeof o.bodyParam == "function" ? l = o.bodyParam({ value: a }) : typeof a == "object" ? l = JSON.stringify(a) : l = String(a), n.set(c, l);
1679
+ let u;
1680
+ typeof o.bodyParam == "function" ? u = o.bodyParam({ value: a }) : typeof a == "object" ? u = JSON.stringify(a) : u = String(a), n.set(c, u);
1360
1681
  }
1361
1682
  return n;
1362
1683
  }
1363
- const ve = 500, Pt = /* @__PURE__ */ new Set(["__proto__"]);
1364
- function ze(t) {
1365
- return !Pt.has(t);
1366
- }
1367
- class me {
1684
+ class Bt {
1368
1685
  /**
1369
- * Creates a new FunctionBridge instance.
1370
- *
1371
- * @param messenger - The messenger to use for cross-domain calls
1686
+ * Array of registered cleanup tasks awaiting execution.
1687
+ * @internal
1372
1688
  */
1373
- constructor(e) {
1374
- this.messenger = e, this.setupCallHandler();
1375
- }
1376
- /** @internal */
1377
- localFunctions = /* @__PURE__ */ new Map();
1378
- /** @internal */
1379
- remoteFunctions = /* @__PURE__ */ new Map();
1689
+ tasks = [];
1380
1690
  /**
1381
- * Tracks function IDs from the current serialization batch.
1382
- * Used for cleanup of stale references when props are updated.
1691
+ * Flag indicating whether cleanup has already been performed.
1383
1692
  * @internal
1384
1693
  */
1385
- currentBatchIds = /* @__PURE__ */ new Set();
1694
+ cleaned = !1;
1386
1695
  /**
1387
- * Serializes a local function to a transferable reference.
1696
+ * Registers a cleanup task to be executed when {@link cleanup} is called.
1388
1697
  *
1389
- * @param fn - The function to serialize
1390
- * @param name - Optional name for debugging
1391
- * @returns A function reference that can be sent across domains
1698
+ * @param task - The cleanup function to register
1699
+ *
1700
+ * @remarks
1701
+ * If cleanup has already been performed, the task is scheduled on a microtask
1702
+ * and executed asynchronously rather than being registered. This ensures
1703
+ * late-registered tasks are still handled appropriately while safely capturing
1704
+ * both sync and async task failures.
1705
+ *
1706
+ * @example
1707
+ * ```typescript
1708
+ * cleanup.register(() => {
1709
+ * eventEmitter.removeAllListeners();
1710
+ * });
1711
+ *
1712
+ * cleanup.register(async () => {
1713
+ * await database.close();
1714
+ * });
1715
+ * ```
1716
+ *
1717
+ * @public
1392
1718
  */
1393
- serialize(e, n) {
1394
- if (this.localFunctions.size >= ve) {
1395
- const r = this.localFunctions.keys().next().value;
1396
- r && this.localFunctions.delete(r);
1719
+ register(e) {
1720
+ if (this.cleaned) {
1721
+ Promise.resolve().then(() => e()).catch((n) => {
1722
+ console.error("Error in cleanup task:", n);
1723
+ });
1724
+ return;
1397
1725
  }
1398
- const s = k();
1399
- return this.localFunctions.set(s, e), this.currentBatchIds.add(s), {
1400
- __type__: "function",
1401
- __id__: s,
1402
- __name__: n || e.name || "anonymous"
1403
- };
1726
+ this.tasks.push(e);
1404
1727
  }
1405
1728
  /**
1406
- * Deserializes a function reference to a callable wrapper.
1729
+ * Executes all registered cleanup tasks in LIFO order.
1730
+ *
1731
+ * @returns A Promise that resolves when all cleanup tasks have completed
1407
1732
  *
1408
1733
  * @remarks
1409
- * The returned function, when called, will invoke the original function
1410
- * in the remote window via postMessage and return the result.
1734
+ * Tasks are executed in reverse order of registration (LIFO pattern).
1735
+ * Each task is awaited individually, and errors are caught and logged
1736
+ * to prevent one failing task from blocking subsequent cleanup operations.
1737
+ * Calling this method multiple times has no effect after the first call.
1411
1738
  *
1412
- * @param ref - The function reference to deserialize
1413
- * @param targetWin - The window containing the original function
1414
- * @param targetDomain - The origin of the target window
1415
- * @returns A callable wrapper function
1739
+ * @example
1740
+ * ```typescript
1741
+ * // In a component's destroy lifecycle
1742
+ * async destroy() {
1743
+ * await this.cleanupManager.cleanup();
1744
+ * }
1745
+ * ```
1746
+ *
1747
+ * @public
1416
1748
  */
1417
- deserialize(e, n, s) {
1418
- const r = `${e.__id__}`, i = this.remoteFunctions.get(r);
1419
- if (i) return i;
1420
- if (this.remoteFunctions.size >= ve) {
1421
- const a = this.remoteFunctions.keys().next().value;
1422
- a && this.remoteFunctions.delete(a);
1423
- }
1424
- const o = async (...a) => this.messenger.send(n, s, u.CALL, {
1425
- id: e.__id__,
1426
- args: a
1427
- });
1428
- return Object.defineProperty(o, "name", {
1429
- value: e.__name__,
1430
- configurable: !0
1431
- }), this.remoteFunctions.set(r, o), o;
1749
+ async cleanup() {
1750
+ if (this.cleaned) return;
1751
+ this.cleaned = !0;
1752
+ const e = this.tasks.reverse();
1753
+ this.tasks = [];
1754
+ for (const n of e)
1755
+ try {
1756
+ await n();
1757
+ } catch (s) {
1758
+ console.error("Error in cleanup task:", s);
1759
+ }
1432
1760
  }
1433
1761
  /**
1434
- * Type guard to check if a value is a function reference.
1435
- *
1436
- * @param value - The value to check
1437
- * @returns True if the value is a FunctionRef
1438
- */
1439
- static isFunctionRef(e) {
1440
- return typeof e == "object" && e !== null && e.__type__ === "function" && typeof e.__id__ == "string";
1441
- }
1442
- /**
1443
- * Sets up the handler for incoming function call messages.
1444
- * @internal
1445
- */
1446
- setupCallHandler() {
1447
- this.messenger.on(
1448
- u.CALL,
1449
- async ({ id: e, args: n }) => {
1450
- const s = this.localFunctions.get(e);
1451
- if (!s)
1452
- throw new Error(`Function with id "${e}" not found`);
1453
- return s(...n);
1454
- }
1455
- );
1456
- }
1457
- /**
1458
- * Removes a local function reference.
1459
- *
1460
- * @param id - The function reference ID to remove
1461
- */
1462
- removeLocal(e) {
1463
- this.localFunctions.delete(e);
1464
- }
1465
- /**
1466
- * Starts a new serialization batch.
1762
+ * Checks whether cleanup has already been performed.
1467
1763
  *
1468
- * @remarks
1469
- * Call this before serializing a new set of props. After serialization,
1470
- * call {@link finishBatch} to clean up functions from previous batches.
1764
+ * @returns `true` if {@link cleanup} has been called, `false` otherwise
1471
1765
  *
1472
1766
  * @example
1473
1767
  * ```typescript
1474
- * bridge.startBatch();
1475
- * const serialized = serializeFunctions(props, bridge);
1476
- * bridge.finishBatch();
1768
+ * if (!cleanupManager.isCleaned()) {
1769
+ * // Safe to register more tasks
1770
+ * cleanupManager.register(myTask);
1771
+ * }
1477
1772
  * ```
1773
+ *
1774
+ * @public
1478
1775
  */
1479
- startBatch() {
1480
- this.currentBatchIds.clear();
1776
+ isCleaned() {
1777
+ return this.cleaned;
1481
1778
  }
1482
1779
  /**
1483
- * Finishes the current batch and removes functions not in this batch.
1780
+ * Resets the manager to its initial state, allowing it to be reused.
1484
1781
  *
1485
1782
  * @remarks
1486
- * This cleans up function references from previous prop updates that
1487
- * are no longer needed, preventing memory leaks.
1783
+ * This method clears all registered tasks and resets the cleaned flag.
1784
+ * It is primarily intended for testing scenarios or cases where the
1785
+ * manager needs to be reused after cleanup.
1488
1786
  *
1489
- * @param keepPrevious - If true, keeps previous batch functions (default: false)
1490
- */
1491
- finishBatch(e = !1) {
1492
- if (e) {
1493
- this.currentBatchIds.clear();
1494
- return;
1495
- }
1496
- for (const n of this.localFunctions.keys())
1497
- this.currentBatchIds.has(n) || this.localFunctions.delete(n);
1498
- this.currentBatchIds.clear();
1499
- }
1500
- /**
1501
- * Clears all remote function references.
1787
+ * @example
1788
+ * ```typescript
1789
+ * // In a test teardown
1790
+ * afterEach(() => {
1791
+ * cleanupManager.reset();
1792
+ * });
1793
+ * ```
1502
1794
  *
1503
- * @remarks
1504
- * Call this when the remote window is no longer accessible
1505
- * (e.g., closed or navigated away).
1506
- */
1507
- clearRemote() {
1508
- this.remoteFunctions.clear();
1509
- }
1510
- /**
1511
- * Returns the current number of registered local functions.
1512
- * Useful for debugging and monitoring.
1513
- */
1514
- get localFunctionCount() {
1515
- return this.localFunctions.size;
1516
- }
1517
- /**
1518
- * Returns the current number of cached remote functions.
1519
- * Useful for debugging and monitoring.
1520
- */
1521
- get remoteFunctionCount() {
1522
- return this.remoteFunctions.size;
1523
- }
1524
- /**
1525
- * Cleans up all function references.
1795
+ * @public
1526
1796
  */
1527
- destroy() {
1528
- this.localFunctions.clear(), this.remoteFunctions.clear(), this.currentBatchIds.clear();
1529
- }
1530
- }
1531
- function re(t, e, n = /* @__PURE__ */ new WeakSet()) {
1532
- if (typeof t == "function")
1533
- return e.serialize(t);
1534
- if (Array.isArray(t)) {
1535
- if (n.has(t))
1536
- throw new Error("Circular reference detected in props - arrays cannot contain circular references");
1537
- n.add(t);
1538
- try {
1539
- return t.map((s) => re(s, e, n));
1540
- } finally {
1541
- n.delete(t);
1542
- }
1543
- }
1544
- if (typeof t == "object" && t !== null) {
1545
- if (n.has(t))
1546
- throw new Error("Circular reference detected in props - objects cannot contain circular references");
1547
- n.add(t);
1548
- try {
1549
- const s = {};
1550
- for (const [r, i] of Object.entries(t))
1551
- ze(r) && (s[r] = re(i, e, n));
1552
- return s;
1553
- } finally {
1554
- n.delete(t);
1555
- }
1556
- }
1557
- return t;
1558
- }
1559
- function ie(t, e, n, s, r = /* @__PURE__ */ new WeakSet()) {
1560
- if (me.isFunctionRef(t))
1561
- return e.deserialize(t, n, s);
1562
- if (Array.isArray(t)) {
1563
- if (r.has(t))
1564
- throw new Error("Circular reference detected in serialized props");
1565
- r.add(t);
1566
- try {
1567
- return t.map(
1568
- (i) => ie(i, e, n, s, r)
1569
- );
1570
- } finally {
1571
- r.delete(t);
1572
- }
1573
- }
1574
- if (typeof t == "object" && t !== null) {
1575
- if (r.has(t))
1576
- throw new Error("Circular reference detected in serialized props");
1577
- r.add(t);
1578
- try {
1579
- const i = {};
1580
- for (const [o, a] of Object.entries(t))
1581
- ze(o) && (i[o] = ie(a, e, n, s, r));
1582
- return i;
1583
- } finally {
1584
- r.delete(t);
1585
- }
1586
- }
1587
- return t;
1588
- }
1589
- const Et = /* @__PURE__ */ new Set(["__proto__"]), ke = "__forgeframe.dotify_path__:", J = "__forgeframe.dotify_empty_object_path__:", We = "__forgeframe.dotify_empty_object__";
1590
- function je(t) {
1591
- return !Et.has(t);
1592
- }
1593
- function Te(t) {
1594
- if (t === null || typeof t != "object" || Array.isArray(t))
1595
- return !1;
1596
- const e = Object.getPrototypeOf(t);
1597
- return e === Object.prototype || e === null;
1598
- }
1599
- function Be(t, e = ke) {
1600
- return `${e}${encodeURIComponent(JSON.stringify(t))}`;
1601
- }
1602
- function bt(t) {
1603
- return encodeURIComponent(JSON.stringify(t));
1604
- }
1605
- function Ot(t, e) {
1606
- return `${Be(t)}=${bt(e)}`;
1607
- }
1608
- function Ct(t) {
1609
- return `${Be(t, J)}=1`;
1610
- }
1611
- function Rt(t, e, n) {
1612
- Object.defineProperty(t, e, {
1613
- configurable: !0,
1614
- enumerable: !0,
1615
- writable: !0,
1616
- value: n
1617
- });
1618
- }
1619
- function Ve(t, e = []) {
1620
- const n = Object.entries(t);
1621
- if (n.length === 0 && Te(t))
1622
- return e.length === 0 ? We : Ct(e);
1623
- const s = [];
1624
- for (const [r, i] of n) {
1625
- if (i === void 0) continue;
1626
- const o = [...e, r];
1627
- Te(i) ? s.push(Ve(i, o)) : s.push(Ot(o, i));
1628
- }
1629
- return s.filter(Boolean).join("&");
1630
- }
1631
- function xt(t) {
1632
- const e = {};
1633
- if (!t || t === We) return e;
1634
- const n = t.split("&");
1635
- for (const s of n) {
1636
- const r = s.indexOf("=");
1637
- if (r === -1) continue;
1638
- const i = s.slice(0, r), o = s.slice(r + 1);
1639
- if (!i || o === void 0) continue;
1640
- const a = i.startsWith(J);
1641
- let c;
1642
- if (a) {
1643
- if (o !== "1")
1644
- throw new Error("Invalid empty-object DOTIFY entry");
1645
- c = {};
1646
- } else
1647
- try {
1648
- c = JSON.parse(decodeURIComponent(o));
1649
- } catch {
1650
- c = decodeURIComponent(o);
1651
- }
1652
- const l = Dt(i);
1653
- if (l.some((h) => !je(h))) continue;
1654
- let d = e;
1655
- for (let h = 0; h < l.length - 1; h++) {
1656
- const E = l[h], O = d[E];
1657
- (!Object.prototype.hasOwnProperty.call(d, E) || typeof O != "object" || O === null || Array.isArray(O)) && (d[E] = {}), d = d[E];
1658
- }
1659
- const m = l[l.length - 1];
1660
- Rt(d, m, c);
1797
+ reset() {
1798
+ this.tasks = [], this.cleaned = !1;
1661
1799
  }
1662
- return e;
1663
1800
  }
1664
- function Dt(t) {
1665
- const e = t.startsWith(J) ? J : ke;
1666
- if (!t.startsWith(e))
1667
- throw new Error("Invalid DOTIFY path framing");
1668
- const n = decodeURIComponent(t.slice(e.length)), s = JSON.parse(n);
1669
- if (Array.isArray(s) && s.length > 0 && s.every((r) => typeof r == "string"))
1670
- return s;
1671
- throw new Error("Invalid DOTIFY path framing");
1672
- }
1673
- function It(t) {
1674
- return typeof t == "object" && t !== null && t.__type__ === "dotify" && typeof t.__value__ == "string";
1675
- }
1676
- function St(t, e, n) {
1677
- const s = {
1678
- ...R,
1679
- ...e
1680
- }, r = {};
1681
- for (const [i, o] of Object.entries(t)) {
1682
- if (o === void 0) continue;
1683
- const a = s[i];
1684
- r[i] = vt(o, a, n);
1685
- }
1686
- return r;
1801
+ const Ne = 100, C = /* @__PURE__ */ new Map();
1802
+ function Vt() {
1803
+ const t = [];
1804
+ for (const [e, n] of C.entries())
1805
+ oe(n) && t.push(e);
1806
+ for (const e of t)
1807
+ C.delete(e);
1687
1808
  }
1688
- function vt(t, e, n) {
1689
- if (typeof t == "function")
1690
- return n.serialize(t);
1691
- const s = e?.serialization ?? z.JSON;
1692
- if (s === z.BASE64 && typeof t == "object") {
1693
- const r = JSON.stringify(t);
1694
- return {
1695
- __type__: "base64",
1696
- __value__: btoa(encodeURIComponent(r))
1697
- };
1809
+ function Yt(t, e) {
1810
+ if (C.size >= Ne && Vt(), C.size >= Ne) {
1811
+ const n = C.keys().next().value;
1812
+ n && C.delete(n);
1698
1813
  }
1699
- return s === z.DOTIFY && typeof t == "object" && t !== null && !Array.isArray(t) ? {
1700
- __type__: "dotify",
1701
- __value__: Ve(t)
1702
- } : re(t, n);
1814
+ C.set(t, e);
1703
1815
  }
1704
- function Ue(t, e, n, s, r, i) {
1705
- const o = {
1706
- ...R,
1707
- ...e
1708
- }, a = {};
1709
- for (const [c, l] of Object.entries(t)) {
1710
- if (!je(c)) continue;
1711
- const d = o[c];
1712
- a[c] = Tt(
1713
- l,
1714
- d,
1715
- n,
1716
- s,
1717
- r,
1718
- i
1719
- );
1720
- }
1721
- return a;
1816
+ function Jt(t) {
1817
+ C.delete(t);
1722
1818
  }
1723
- function Tt(t, e, n, s, r, i) {
1724
- if (Ut(t))
1725
- try {
1726
- const o = decodeURIComponent(atob(t.__value__));
1727
- return JSON.parse(o);
1728
- } catch {
1729
- return t;
1730
- }
1731
- if (It(t))
1819
+ function w(t, e, ...n) {
1820
+ const s = t[e];
1821
+ if (typeof s == "function")
1732
1822
  try {
1733
- return xt(t.__value__);
1734
- } catch {
1735
- return t;
1823
+ const r = s(...n);
1824
+ r && typeof r == "object" && "catch" in r && typeof r.catch == "function" && r.catch((i) => {
1825
+ console.error(`Error in async ${e} callback:`, i);
1826
+ });
1827
+ } catch (r) {
1828
+ console.error(`Error in ${e} callback:`, r);
1736
1829
  }
1737
- return ie(t, s, r, i);
1738
1830
  }
1739
- function Ut(t) {
1740
- return typeof t == "object" && t !== null && t.__type__ === "base64" && typeof t.__value__ == "string";
1831
+ function L(t, e, n) {
1832
+ t.emit(g.ERROR, n), w(e, "onError", n);
1833
+ }
1834
+ function qt(t, e) {
1835
+ if (!t.children)
1836
+ return;
1837
+ const n = t.children({ props: e }), s = {};
1838
+ for (const [r, i] of Object.entries(n)) {
1839
+ const o = Fn(i);
1840
+ if (!o)
1841
+ throw new Error(`Nested component "${r}" is missing component metadata`);
1842
+ if (typeof o.url != "string")
1843
+ throw new Error(
1844
+ `Nested component "${r}" must use a static string URL. Function URLs are not supported in children.`
1845
+ );
1846
+ s[r] = {
1847
+ tag: o.tag,
1848
+ url: o.url,
1849
+ props: o.props,
1850
+ dimensions: typeof o.dimensions == "function" ? void 0 : o.dimensions,
1851
+ defaultContext: o.defaultContext
1852
+ };
1853
+ }
1854
+ return Object.keys(s).length > 0 ? s : void 0;
1741
1855
  }
1742
- class Nt {
1856
+ class Kt {
1743
1857
  constructor(e, n, s) {
1744
1858
  this.options = e, this.createPropContext = s, this.inputProps = { ...n };
1745
1859
  const r = this.inputProps, i = this.createPropContext(r);
1746
- this.props = Ie(r, this.options.props, i);
1860
+ this.props = Ue(r, this.options.props, i);
1747
1861
  }
1748
1862
  /** Current normalized prop snapshot. */
1749
1863
  props;
@@ -1755,8 +1869,8 @@ class Nt {
1755
1869
  * Builds and validates the next props snapshot.
1756
1870
  */
1757
1871
  buildNextProps(e) {
1758
- const n = { ...this.inputProps, ...e }, s = { ...this.props, ...e }, r = this.createPropContext(s), i = Ie(s, this.options.props, r);
1759
- return T(i, this.options.props), this.options.validate?.({ props: i }), { nextInputProps: n, nextProps: i };
1872
+ const n = { ...this.inputProps, ...e }, s = { ...this.props, ...e }, r = this.createPropContext(s), i = Ue(s, this.options.props, r);
1873
+ return H(i, this.options.props), this.options.validate?.({ props: i }), { nextInputProps: n, nextProps: i };
1760
1874
  }
1761
1875
  /**
1762
1876
  * Applies a props update and synchronizes it to the host when connected.
@@ -1805,44 +1919,44 @@ class Nt {
1805
1919
  });
1806
1920
  }
1807
1921
  }
1808
- function x(t, e = "100%") {
1922
+ function S(t, e = "100%") {
1809
1923
  return t === void 0 ? e : typeof t == "number" ? `${t}px` : t;
1810
1924
  }
1811
- function q(t, e) {
1925
+ function K(t, e) {
1812
1926
  if (t === void 0) return e;
1813
1927
  if (typeof t == "number") return t;
1814
1928
  const n = parseInt(t, 10);
1815
1929
  return isNaN(n) ? e : n;
1816
1930
  }
1817
- function Ft(t) {
1931
+ function Xt(t) {
1818
1932
  const { name: e, dimensions: n, attributes: s = {}, style: r = {} } = t, i = document.createElement("iframe");
1819
- return i.name = e, i.setAttribute("frameborder", "0"), i.setAttribute("allowtransparency", "true"), i.setAttribute("scrolling", "auto"), Ye(i, n), zt(i, s), Mt(i, r), kt(i, s), i;
1933
+ return i.name = e, i.setAttribute("frameborder", "0"), i.setAttribute("allowtransparency", "true"), i.setAttribute("scrolling", "auto"), Ke(i, n), nn(i, s), tn(i, r), sn(i, s), i;
1820
1934
  }
1821
- function Ht(t) {
1935
+ function Gt(t) {
1822
1936
  try {
1823
1937
  t.src = "about:blank", t.parentNode?.removeChild(t);
1824
1938
  } catch {
1825
1939
  }
1826
1940
  }
1827
- function $t(t, e) {
1828
- Ye(t, e);
1941
+ function Zt(t, e) {
1942
+ Ke(t, e);
1829
1943
  }
1830
- function At(t) {
1944
+ function Qt(t) {
1831
1945
  t.style.display = "", t.style.visibility = "visible";
1832
1946
  }
1833
- function Ne(t) {
1947
+ function Ae(t) {
1834
1948
  t.style.display = "none", t.style.visibility = "hidden";
1835
1949
  }
1836
- function Lt(t) {
1950
+ function en(t) {
1837
1951
  try {
1838
1952
  t.focus(), t.contentWindow?.focus();
1839
1953
  } catch {
1840
1954
  }
1841
1955
  }
1842
- function Ye(t, e) {
1843
- e.width !== void 0 && (t.style.width = x(e.width)), e.height !== void 0 && (t.style.height = x(e.height));
1956
+ function Ke(t, e) {
1957
+ e.width !== void 0 && (t.style.width = S(e.width)), e.height !== void 0 && (t.style.height = S(e.height));
1844
1958
  }
1845
- function Mt(t, e) {
1959
+ function tn(t, e) {
1846
1960
  for (const [n, s] of Object.entries(e)) {
1847
1961
  if (s === void 0) continue;
1848
1962
  const r = typeof s == "number" ? `${s}px` : s;
@@ -1852,7 +1966,7 @@ function Mt(t, e) {
1852
1966
  );
1853
1967
  }
1854
1968
  }
1855
- function zt(t, e) {
1969
+ function nn(t, e) {
1856
1970
  for (const [n, s] of Object.entries(e))
1857
1971
  if (s !== void 0) {
1858
1972
  if (typeof s == "boolean") {
@@ -1862,19 +1976,19 @@ function zt(t, e) {
1862
1976
  t.setAttribute(n, s);
1863
1977
  }
1864
1978
  }
1865
- function kt(t, e) {
1979
+ function sn(t, e) {
1866
1980
  e.sandbox === void 0 && t.setAttribute(
1867
1981
  "sandbox",
1868
1982
  "allow-scripts allow-same-origin allow-forms allow-popups"
1869
1983
  );
1870
1984
  }
1871
- class Je extends Error {
1985
+ class Xe extends Error {
1872
1986
  constructor(e = "Popup blocked by browser") {
1873
1987
  super(e), this.name = "PopupOpenError";
1874
1988
  }
1875
1989
  }
1876
- function Wt(t) {
1877
- 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 = [
1990
+ function rn(t) {
1991
+ const { url: e, name: n, dimensions: s } = t, r = K(s.width, 500), i = K(s.height, 500), o = Math.floor(window.screenX + (window.outerWidth - r) / 2), a = Math.floor(window.screenY + (window.outerHeight - i) / 2), c = [
1878
1992
  `width=${r}`,
1879
1993
  `height=${i}`,
1880
1994
  `left=${o}`,
@@ -1886,24 +2000,24 @@ function Wt(t) {
1886
2000
  "status=no",
1887
2001
  "resizable=yes",
1888
2002
  "scrollbars=yes"
1889
- ].join(","), l = window.open(e, n, c);
1890
- if (!l || Vt(l))
1891
- throw new Je();
1892
- return l;
2003
+ ].join(","), u = window.open(e, n, c);
2004
+ if (!u || cn(u))
2005
+ throw new Xe();
2006
+ return u;
1893
2007
  }
1894
- function jt(t) {
2008
+ function on(t) {
1895
2009
  try {
1896
2010
  t.closed || t.close();
1897
2011
  } catch {
1898
2012
  }
1899
2013
  }
1900
- function Bt(t) {
2014
+ function an(t) {
1901
2015
  try {
1902
2016
  t.closed || t.focus();
1903
2017
  } catch {
1904
2018
  }
1905
2019
  }
1906
- function Vt(t) {
2020
+ function cn(t) {
1907
2021
  if (!t) return !0;
1908
2022
  try {
1909
2023
  return !!(t.closed || t.innerHeight === 0 || t.innerWidth === 0);
@@ -1911,7 +2025,7 @@ function Vt(t) {
1911
2025
  return !0;
1912
2026
  }
1913
2027
  }
1914
- function Yt(t, e, n = {}) {
2028
+ function un(t, e, n = {}) {
1915
2029
  const {
1916
2030
  initialInterval: s = 100,
1917
2031
  // Start fast to catch quick closes
@@ -1921,7 +2035,7 @@ function Yt(t, e, n = {}) {
1921
2035
  // Exponential backoff multiplier
1922
2036
  } = n;
1923
2037
  let o = s, a, c = !1;
1924
- const l = () => {
2038
+ const u = () => {
1925
2039
  try {
1926
2040
  e();
1927
2041
  } catch (m) {
@@ -1931,11 +2045,11 @@ function Yt(t, e, n = {}) {
1931
2045
  if (!c) {
1932
2046
  try {
1933
2047
  if (t.closed) {
1934
- l();
2048
+ u();
1935
2049
  return;
1936
2050
  }
1937
2051
  } catch {
1938
- l();
2052
+ u();
1939
2053
  return;
1940
2054
  }
1941
2055
  o = Math.min(o * i, r), a = setTimeout(d, o);
@@ -1945,9 +2059,9 @@ function Yt(t, e, n = {}) {
1945
2059
  c = !0, clearTimeout(a);
1946
2060
  };
1947
2061
  }
1948
- function Jt(t, e) {
2062
+ function ln(t, e) {
1949
2063
  try {
1950
- const n = q(e.width, t.outerWidth), s = q(
2064
+ const n = K(e.width, t.outerWidth), s = K(
1951
2065
  e.height,
1952
2066
  t.outerHeight
1953
2067
  );
@@ -1955,9 +2069,9 @@ function Jt(t, e) {
1955
2069
  } catch {
1956
2070
  }
1957
2071
  }
1958
- const Fe = "forgeframe-spinner-style";
1959
- function qt(t, e) {
1960
- const n = t.getElementById(Fe);
2072
+ const $e = "forgeframe-spinner-style";
2073
+ function dn(t, e) {
2074
+ const n = t.getElementById($e);
1961
2075
  if (n) {
1962
2076
  const r = n.getAttribute("nonce");
1963
2077
  if (!e || r === e)
@@ -1965,32 +2079,32 @@ function qt(t, e) {
1965
2079
  n.remove();
1966
2080
  }
1967
2081
  const s = t.createElement("style");
1968
- s.id = Fe, e && s.setAttribute("nonce", e), s.textContent = `
2082
+ s.id = $e, e && s.setAttribute("nonce", e), s.textContent = `
1969
2083
  @keyframes forgeframe-spin {
1970
2084
  to { transform: rotate(360deg); }
1971
2085
  }
1972
2086
  `, (t.head ?? t.documentElement).appendChild(s);
1973
2087
  }
1974
- function Kt(t) {
2088
+ function hn(t) {
1975
2089
  const { doc: e, dimensions: n, uid: s, tag: r } = t, i = e.createElement("div");
1976
2090
  return i.id = `forgeframe-container-${s}`, i.setAttribute("data-forgeframe-tag", r), Object.assign(i.style, {
1977
2091
  display: "inline-block",
1978
2092
  position: "relative",
1979
- width: x(n.width),
1980
- height: x(n.height),
2093
+ width: S(n.width),
2094
+ height: S(n.height),
1981
2095
  overflow: "hidden"
1982
2096
  }), i;
1983
2097
  }
1984
- function Xt(t) {
2098
+ function pn(t) {
1985
2099
  const { doc: e, dimensions: n, cspNonce: s } = t;
1986
- qt(e, s);
2100
+ dn(e, s);
1987
2101
  const r = e.createElement("div");
1988
2102
  Object.assign(r.style, {
1989
2103
  display: "flex",
1990
2104
  alignItems: "center",
1991
2105
  justifyContent: "center",
1992
- width: x(n.width),
1993
- height: x(n.height),
2106
+ width: S(n.width),
2107
+ height: S(n.height),
1994
2108
  backgroundColor: "#f5f5f5",
1995
2109
  position: "absolute",
1996
2110
  top: "0",
@@ -2007,20 +2121,20 @@ function Xt(t) {
2007
2121
  animation: "forgeframe-spin 1s linear infinite"
2008
2122
  }), r.appendChild(i), r;
2009
2123
  }
2010
- function Gt(t, e = 200) {
2124
+ function fn(t, e = 200) {
2011
2125
  return new Promise((n) => {
2012
2126
  t.style.opacity = "0", t.style.transition = `opacity ${e}ms ease-in`, t.offsetHeight, t.style.opacity = "1", setTimeout(n, e);
2013
2127
  });
2014
2128
  }
2015
- function Zt(t, e = 200) {
2129
+ function mn(t, e = 200) {
2016
2130
  return new Promise((n) => {
2017
2131
  t.style.transition = `opacity ${e}ms ease-out`, t.style.opacity = "0", setTimeout(n, e);
2018
2132
  });
2019
2133
  }
2020
- async function Qt(t, e, n) {
2021
- e && (await Zt(e, 150), e.remove()), n.style.display = "", n.style.visibility = "visible", n.style.opacity = "0", await Gt(n, 150);
2134
+ async function gn(t, e, n) {
2135
+ e && (await mn(e, 150), e.remove()), n.style.display = "", n.style.visibility = "visible", n.style.opacity = "0", await fn(n, 150);
2022
2136
  }
2023
- class en {
2137
+ class yn {
2024
2138
  constructor(e, n, s, r, i) {
2025
2139
  this.options = e, this.uid = n, this.getProps = s, this.resolveDimensions = r, this.callbacks = i, this.context = this.options.defaultContext;
2026
2140
  }
@@ -2055,12 +2169,12 @@ class en {
2055
2169
  if (!this.container) return;
2056
2170
  const s = this.container;
2057
2171
  this.ownedContainer = null;
2058
- const r = this.getProps(), i = this.options.prerenderTemplate ?? Xt, o = this.options.containerTemplate ?? Kt, a = this.resolveDimensions(), c = r.cspNonce;
2172
+ const r = this.getProps(), i = this.options.prerenderTemplate ?? pn, o = this.options.containerTemplate ?? hn, a = this.resolveDimensions(), c = r.cspNonce;
2059
2173
  if (this.context === f.IFRAME) {
2060
2174
  const h = n();
2061
- this.iframe = e(h), Ne(this.iframe);
2175
+ this.iframe = e(h), Ae(this.iframe);
2062
2176
  }
2063
- const l = {
2177
+ const u = {
2064
2178
  uid: this.uid,
2065
2179
  tag: this.options.tag,
2066
2180
  context: this.context,
@@ -2074,7 +2188,7 @@ class en {
2074
2188
  focus: () => this.callbacks.focus(),
2075
2189
  cspNonce: c
2076
2190
  };
2077
- this.prerenderElement = i(l);
2191
+ this.prerenderElement = i(u);
2078
2192
  const d = {
2079
2193
  uid: this.uid,
2080
2194
  tag: this.options.tag,
@@ -2103,7 +2217,7 @@ class en {
2103
2217
  */
2104
2218
  createIframeElement(e) {
2105
2219
  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 ?? {};
2106
- return Ft({
2220
+ return Xt({
2107
2221
  name: e,
2108
2222
  dimensions: n,
2109
2223
  attributes: r,
@@ -2120,13 +2234,13 @@ class en {
2120
2234
  throw new Error("Iframe not created during prerender");
2121
2235
  return r ? e.submitBodyForm(this.iframe.name, n, s) : this.iframe.src = n, this.iframe.contentWindow;
2122
2236
  }
2123
- const i = e.buildWindowName(), o = Wt({
2237
+ const i = e.buildWindowName(), o = rn({
2124
2238
  url: r ? "about:blank" : n,
2125
2239
  name: i,
2126
2240
  dimensions: this.resolveDimensions()
2127
2241
  });
2128
2242
  r && e.submitBodyForm(i, n, s);
2129
- const a = Yt(o, () => {
2243
+ const a = un(o, () => {
2130
2244
  e.onPopupClose();
2131
2245
  });
2132
2246
  return e.registerCleanup(a), o;
@@ -2135,7 +2249,7 @@ class en {
2135
2249
  * Swaps prerender content with the live iframe after host initialization.
2136
2250
  */
2137
2251
  async swapPrerenderContentIfNeeded() {
2138
- this.context === f.IFRAME && this.iframe && this.container && (await Qt(this.container, this.prerenderElement, this.iframe), this.prerenderElement = null);
2252
+ this.context === f.IFRAME && this.iframe && this.container && (await gn(this.container, this.prerenderElement, this.iframe), this.prerenderElement = null);
2139
2253
  }
2140
2254
  /**
2141
2255
  * Submits a hidden form to navigate a target window via POST.
@@ -2147,8 +2261,8 @@ class en {
2147
2261
  const o = r.createElement("form");
2148
2262
  o.method = "POST", o.action = n, o.target = e, o.style.display = "none";
2149
2263
  for (const [a, c] of s.entries()) {
2150
- const l = r.createElement("input");
2151
- l.type = "hidden", l.name = a, l.value = c, o.appendChild(l);
2264
+ const u = r.createElement("input");
2265
+ u.type = "hidden", u.name = a, u.value = c, o.appendChild(u);
2152
2266
  }
2153
2267
  i.appendChild(o);
2154
2268
  try {
@@ -2161,59 +2275,96 @@ class en {
2161
2275
  * Focuses iframe/popup context.
2162
2276
  */
2163
2277
  focus(e) {
2164
- this.context === f.IFRAME && this.iframe ? Lt(this.iframe) : this.context === f.POPUP && e && Bt(e);
2278
+ this.context === f.IFRAME && this.iframe ? en(this.iframe) : this.context === f.POPUP && e && an(e);
2165
2279
  }
2166
2280
  /**
2167
2281
  * Resizes iframe/popup context.
2168
2282
  */
2169
2283
  resize(e, n) {
2170
- this.context === f.IFRAME && this.iframe ? $t(this.iframe, e) : this.context === f.POPUP && n && Jt(n, e);
2284
+ this.context === f.IFRAME && this.iframe ? Zt(this.iframe, e) : this.context === f.POPUP && n && ln(n, e);
2171
2285
  }
2172
2286
  /**
2173
2287
  * Shows iframe context.
2174
2288
  */
2175
2289
  show() {
2176
- this.context === f.IFRAME && this.iframe && At(this.iframe);
2290
+ this.context === f.IFRAME && this.iframe && Qt(this.iframe);
2177
2291
  }
2178
2292
  /**
2179
2293
  * Hides iframe context.
2180
2294
  */
2181
2295
  hide() {
2182
- this.context === f.IFRAME && this.iframe && Ne(this.iframe);
2296
+ this.context === f.IFRAME && this.iframe && Ae(this.iframe);
2183
2297
  }
2184
2298
  /**
2185
2299
  * Destroys rendered iframe/popup DOM artifacts.
2186
2300
  */
2187
2301
  destroy(e) {
2188
- this.iframe && (Ht(this.iframe), this.iframe = null), this.context === f.POPUP && e && jt(e), this.prerenderElement && (this.prerenderElement.remove(), this.prerenderElement = null), this.ownedContainer && (this.ownedContainer.remove(), this.ownedContainer = null), this.container = null;
2302
+ this.iframe && (Gt(this.iframe), this.iframe = null), this.context === f.POPUP && e && on(e), this.prerenderElement && (this.prerenderElement.remove(), this.prerenderElement = null), this.ownedContainer && (this.ownedContainer.remove(), this.ownedContainer = null), this.container = null;
2303
+ }
2304
+ }
2305
+ function wn(t) {
2306
+ const e = [];
2307
+ if (t.options?.anyConsumer) {
2308
+ for (const n of Un())
2309
+ n.instance.uid !== t.uid && e.push({
2310
+ uid: n.instance.uid,
2311
+ tag: n.tag,
2312
+ exports: n.instance.exports
2313
+ });
2314
+ return e;
2189
2315
  }
2316
+ for (const n of Hn(t.tag))
2317
+ n.uid !== t.uid && e.push({
2318
+ uid: n.uid,
2319
+ tag: t.tag,
2320
+ exports: n.exports
2321
+ });
2322
+ return e;
2323
+ }
2324
+ function Ge() {
2325
+ let t, e;
2326
+ return { promise: new Promise((s, r) => {
2327
+ t = s, e = r;
2328
+ }), resolve: t, reject: e };
2329
+ }
2330
+ function _n(t, e, n = "Operation timed out") {
2331
+ return new Promise((s, r) => {
2332
+ const i = setTimeout(() => {
2333
+ r(new Error(`${n} (${e}ms)`));
2334
+ }, e);
2335
+ t.then((o) => {
2336
+ clearTimeout(i), s(o);
2337
+ }).catch((o) => {
2338
+ clearTimeout(i), r(o);
2339
+ });
2340
+ });
2190
2341
  }
2191
- const oe = "forgeframe:";
2192
- function ee(t) {
2193
- return oe + JSON.stringify(t);
2342
+ const ae = "forgeframe:";
2343
+ function ne(t) {
2344
+ return ae + JSON.stringify(t);
2194
2345
  }
2195
- function tn(t) {
2196
- if (typeof t != "string" || !t.startsWith(oe)) return null;
2346
+ function Pn(t) {
2347
+ if (typeof t != "string" || !t.startsWith(ae)) return null;
2197
2348
  try {
2198
- const e = t.slice(oe.length), n = JSON.parse(e);
2349
+ const e = t.slice(ae.length), n = JSON.parse(e);
2199
2350
  return !n.id || !n.type || !n.name || !n.source ? null : n;
2200
2351
  } catch {
2201
2352
  return null;
2202
2353
  }
2203
2354
  }
2204
- function He(t, e, n, s) {
2355
+ function Me(t, e, n, s) {
2205
2356
  return {
2206
2357
  id: t,
2207
- type: W.REQUEST,
2358
+ type: j.REQUEST,
2208
2359
  name: e,
2209
2360
  data: n,
2210
2361
  source: s
2211
2362
  };
2212
2363
  }
2213
- function nn(t, e, n, s) {
2364
+ function En(t, e, n, s) {
2214
2365
  return {
2215
2366
  id: t,
2216
- type: W.RESPONSE,
2367
+ type: j.RESPONSE,
2217
2368
  name: "response",
2218
2369
  data: e,
2219
2370
  source: n,
@@ -2223,22 +2374,10 @@ function nn(t, e, n, s) {
2223
2374
  } : void 0
2224
2375
  };
2225
2376
  }
2226
- function sn(t) {
2227
- return t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2228
- }
2229
- function rn(t) {
2230
- if (!t.includes("*"))
2231
- return null;
2232
- const e = t.split("*").map((n) => sn(n)).join(".*");
2233
- return new RegExp(`^${e}$`);
2234
- }
2235
- function on(t, e) {
2236
- return t.global || t.sticky ? new RegExp(t.source, t.flags.replace(/[gy]/g, "")).test(e) : t.test(e);
2237
- }
2238
- function an(t, e, n) {
2377
+ function bn(t, e, n) {
2239
2378
  return e !== t.targetWin ? !1 : t.expectedOrigin === "*" ? !0 : n === t.expectedOrigin;
2240
2379
  }
2241
- function cn(t, e) {
2380
+ function Cn(t, e) {
2242
2381
  if (t === "*")
2243
2382
  return "*";
2244
2383
  if (t === "/")
@@ -2249,7 +2388,7 @@ function cn(t, e) {
2249
2388
  return t;
2250
2389
  }
2251
2390
  }
2252
- class qe {
2391
+ class Ze {
2253
2392
  /**
2254
2393
  * Creates a new Messenger instance.
2255
2394
  *
@@ -2289,7 +2428,7 @@ class qe {
2289
2428
  else if (e instanceof RegExp)
2290
2429
  this.allowedOriginPatterns.push(e);
2291
2430
  else {
2292
- const n = rn(e);
2431
+ const n = Je(e);
2293
2432
  n ? this.wildcardPatternRegistry.has(e) || (this.wildcardPatternRegistry.set(e, n), this.allowedOriginPatterns.push(n)) : this.allowedOrigins.add(e);
2294
2433
  }
2295
2434
  }
@@ -2322,7 +2461,7 @@ class qe {
2322
2461
  if (this.allowedOrigins.has(e))
2323
2462
  return !0;
2324
2463
  for (const n of this.allowedOriginPatterns)
2325
- if (on(n, e))
2464
+ if (ie(n, e))
2326
2465
  return !0;
2327
2466
  return !1;
2328
2467
  }
@@ -2333,9 +2472,9 @@ class qe {
2333
2472
  resolveVerifiedSource(e, n, s) {
2334
2473
  const r = e, i = this.sourceUidRegistry.get(r);
2335
2474
  if (i)
2336
- return { uid: i, domain: n };
2337
- const o = s && typeof s.uid == "string" && s.uid.length > 0 ? s.uid : k();
2338
- return this.sourceUidRegistry.set(r, o), { uid: o, domain: n };
2475
+ return { uid: i, domain: n, window: e };
2476
+ const o = s && typeof s.uid == "string" && s.uid.length > 0 ? s.uid : W();
2477
+ return this.sourceUidRegistry.set(r, o), { uid: o, domain: n, window: e };
2339
2478
  }
2340
2479
  /**
2341
2480
  * Sends a message and waits for a response.
@@ -2353,22 +2492,22 @@ class qe {
2353
2492
  async send(e, n, s, r, i = 1e4) {
2354
2493
  if (this.destroyed)
2355
2494
  throw new Error("Messenger has been destroyed");
2356
- const o = k(), a = He(o, s, r, {
2495
+ const o = W(), a = Me(o, s, r, {
2357
2496
  uid: this.uid,
2358
2497
  domain: this.domain
2359
- }), c = Le(), l = setTimeout(() => {
2498
+ }), c = Ge(), u = setTimeout(() => {
2360
2499
  this.pending.delete(o), c.reject(new Error(`Message "${s}" timed out after ${i}ms`));
2361
2500
  }, i);
2362
2501
  this.pending.set(o, {
2363
2502
  deferred: c,
2364
- timeout: l,
2503
+ timeout: u,
2365
2504
  targetWin: e,
2366
- expectedOrigin: cn(n, this.domain)
2505
+ expectedOrigin: Cn(n, this.domain)
2367
2506
  });
2368
2507
  try {
2369
- e.postMessage(ee(a), n);
2508
+ e.postMessage(ne(a), n);
2370
2509
  } catch (d) {
2371
- throw this.pending.delete(o), clearTimeout(l), d;
2510
+ throw this.pending.delete(o), clearTimeout(u), d;
2372
2511
  }
2373
2512
  return c.promise;
2374
2513
  }
@@ -2385,11 +2524,11 @@ class qe {
2385
2524
  post(e, n, s, r) {
2386
2525
  if (this.destroyed)
2387
2526
  throw new Error("Messenger has been destroyed");
2388
- const i = k(), o = He(i, s, r, {
2527
+ const i = W(), o = Me(i, s, r, {
2389
2528
  uid: this.uid,
2390
2529
  domain: this.domain
2391
2530
  });
2392
- e.postMessage(ee(o), n);
2531
+ e.postMessage(ne(o), n);
2393
2532
  }
2394
2533
  /**
2395
2534
  * Registers a handler for incoming messages of a specific type.
@@ -2411,7 +2550,7 @@ class qe {
2411
2550
  this.listener = (e) => {
2412
2551
  if (e.source === this.win || !this.isOriginTrusted(e.origin))
2413
2552
  return;
2414
- const n = tn(e.data);
2553
+ const n = Pn(e.data);
2415
2554
  if (!n) return;
2416
2555
  const s = e.source;
2417
2556
  !s || typeof s.postMessage != "function" || this.handleMessage(n, s, e.origin);
@@ -2422,10 +2561,10 @@ class qe {
2422
2561
  * @internal
2423
2562
  */
2424
2563
  async handleMessage(e, n, s) {
2425
- if (e.type === W.RESPONSE) {
2564
+ if (e.type === j.RESPONSE) {
2426
2565
  const r = this.pending.get(e.id);
2427
2566
  if (r) {
2428
- if (!an(r, n, s))
2567
+ if (!bn(r, n, s))
2429
2568
  return;
2430
2569
  if (this.pending.delete(e.id), clearTimeout(r.timeout), e.error) {
2431
2570
  const i = new Error(e.error.message);
@@ -2435,7 +2574,7 @@ class qe {
2435
2574
  }
2436
2575
  return;
2437
2576
  }
2438
- if (e.type === W.REQUEST) {
2577
+ if (e.type === j.REQUEST) {
2439
2578
  const r = this.handlers.get(e.name);
2440
2579
  if (!r)
2441
2580
  return;
@@ -2450,14 +2589,14 @@ class qe {
2450
2589
  } catch (c) {
2451
2590
  o = c instanceof Error ? c : new Error(String(c));
2452
2591
  }
2453
- const a = nn(
2592
+ const a = En(
2454
2593
  e.id,
2455
2594
  i,
2456
2595
  { uid: this.uid, domain: this.domain },
2457
2596
  o
2458
2597
  );
2459
2598
  try {
2460
- n.postMessage(ee(a), s);
2599
+ n.postMessage(ne(a), s);
2461
2600
  } catch {
2462
2601
  }
2463
2602
  }
@@ -2486,105 +2625,11 @@ class qe {
2486
2625
  return this.destroyed;
2487
2626
  }
2488
2627
  }
2489
- const ln = [
2490
- "init",
2491
- "close",
2492
- "resize",
2493
- "show",
2494
- "hide",
2495
- "onError",
2496
- "updateProps",
2497
- "export"
2498
- ], $e = 32 * 1024;
2499
- function un(t) {
2500
- const e = gn(t);
2501
- return `${j}${e}`;
2502
- }
2503
- function Ke(t) {
2504
- if (!t || !t.startsWith(j))
2505
- return null;
2506
- const e = t.slice(j.length);
2507
- return yn(e);
2508
- }
2509
- function C(t) {
2510
- return typeof t == "object" && t !== null;
2511
- }
2512
- function hn(t) {
2513
- return C(t);
2514
- }
2515
- function dn(t) {
2516
- return C(t) && ln.every(
2517
- (e) => typeof t[e] == "string" && t[e].length > 0
2518
- );
2519
- }
2520
- function pn(t) {
2521
- if (!C(t) || typeof t.tag != "string" || t.tag.length === 0 || typeof t.url != "string" || t.url.length === 0 || t.props !== void 0 && !C(t.props) || t.defaultContext !== void 0 && t.defaultContext !== f.IFRAME && t.defaultContext !== f.POPUP)
2522
- return !1;
2523
- if (t.dimensions !== void 0) {
2524
- if (!C(t.dimensions))
2525
- return !1;
2526
- const { width: e, height: n } = t.dimensions;
2527
- if (e !== void 0 && typeof e != "string" && typeof e != "number" || n !== void 0 && typeof n != "string" && typeof n != "number")
2528
- return !1;
2529
- }
2530
- return !0;
2531
- }
2532
- function fn(t) {
2533
- return C(t) ? Object.values(t).every((e) => pn(e)) : !1;
2534
- }
2535
- function mn(t) {
2536
- return !(!C(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 !== ae || t.context !== f.IFRAME && t.context !== f.POPUP || typeof t.consumerDomain != "string" || t.consumerDomain.length === 0 || !hn(t.props) || !dn(t.exports) || t.children !== void 0 && !fn(t.children));
2537
- }
2538
- function ge(t = window) {
2539
- try {
2540
- return t.name.startsWith(j);
2541
- } catch {
2542
- return !1;
2543
- }
2544
- }
2545
- function te(t, e = window) {
2546
- return Ke(e.name)?.tag === t;
2547
- }
2548
- function gn(t) {
2549
- try {
2550
- const e = JSON.stringify(t), n = btoa(encodeURIComponent(e)), s = new Blob([n]).size;
2551
- if (s > $e)
2552
- throw new Error(
2553
- `Payload size (${Math.round(s / 1024)}KB) exceeds maximum allowed size (${$e / 1024}KB). Consider reducing the amount of data passed via props.`
2554
- );
2555
- return n;
2556
- } catch (e) {
2557
- throw e instanceof Error && e.message.includes("Payload size") ? e : new Error(`Failed to encode payload: ${e}`);
2558
- }
2559
- }
2560
- function yn(t) {
2561
- try {
2562
- const e = decodeURIComponent(atob(t)), n = JSON.parse(e);
2563
- return mn(n) ? n : null;
2564
- } catch {
2565
- return null;
2566
- }
2567
- }
2568
- function wn(t) {
2569
- return {
2570
- uid: t.uid,
2571
- tag: t.tag,
2572
- version: ae,
2573
- context: t.context,
2574
- consumerDomain: t.consumerDomain,
2575
- props: t.props,
2576
- exports: t.exports,
2577
- children: t.children
2578
- };
2579
- }
2580
- function _n(t = window) {
2581
- return Ke(t.name);
2582
- }
2583
- class Pn {
2628
+ class On {
2584
2629
  constructor(e, n, s, r) {
2585
2630
  this.uid = e, this.options = n, this.resolveUrl = s, this.resolveUrlOrigin = r;
2586
2631
  const i = this.buildTrustedDomains();
2587
- this.messenger = new qe(this.uid, window, B(), i), this.bridge = new me(this.messenger);
2632
+ this.messenger = new Ze(this.uid, window, q(), i), this.bridge = new de(this.messenger);
2588
2633
  }
2589
2634
  /** Messenger for host communication. */
2590
2635
  messenger;
@@ -2612,7 +2657,7 @@ class Pn {
2612
2657
  * Returns true when the domain option explicitly includes this origin.
2613
2658
  */
2614
2659
  isExplicitDomainTrust(e) {
2615
- return this.options.domain ? U(this.options.domain, e) : !1;
2660
+ return this.options.domain ? X(this.options.domain, e) : !1;
2616
2661
  }
2617
2662
  /**
2618
2663
  * Ensures the messenger trusts the origin for a resolved host URL.
@@ -2634,7 +2679,7 @@ class Pn {
2634
2679
  * Returns true when the host window is connected and not closed.
2635
2680
  */
2636
2681
  isHostConnected() {
2637
- return !!(this.hostWindow && !se(this.hostWindow));
2682
+ return !!(this.hostWindow && !oe(this.hostWindow));
2638
2683
  }
2639
2684
  /**
2640
2685
  * Serializes host props while keeping function bridge references in sync.
@@ -2643,7 +2688,7 @@ class Pn {
2643
2688
  this.bridge.startBatch();
2644
2689
  const r = s?.finishBatch ?? !0;
2645
2690
  try {
2646
- const i = St(e, n, this.bridge);
2691
+ const i = It(e, n, this.bridge);
2647
2692
  return r && this.bridge.finishBatch(), i;
2648
2693
  } catch (i) {
2649
2694
  throw this.bridge.finishBatch(!0), i;
@@ -2653,13 +2698,13 @@ class Pn {
2653
2698
  * Sends the current props snapshot to the host window when available.
2654
2699
  */
2655
2700
  async sendPropsUpdateToHost(e, n) {
2656
- if (!this.hostWindow || se(this.hostWindow))
2701
+ if (!this.hostWindow || oe(this.hostWindow))
2657
2702
  return;
2658
- const s = this.getHostDomain(), r = Se(
2703
+ const s = this.getHostDomain(), r = Fe(
2659
2704
  e,
2660
2705
  n,
2661
2706
  s,
2662
- Me(this.hostWindow)
2707
+ qe(this.hostWindow)
2663
2708
  ), i = this.serializePropsForHost(
2664
2709
  r,
2665
2710
  n,
@@ -2669,7 +2714,7 @@ class Pn {
2669
2714
  await this.messenger.send(
2670
2715
  this.hostWindow,
2671
2716
  s,
2672
- u.PROPS,
2717
+ l.PROPS,
2673
2718
  i
2674
2719
  ), this.bridge.finishBatch();
2675
2720
  } catch (o) {
@@ -2680,7 +2725,7 @@ class Pn {
2680
2725
  * Builds the window.name payload for host initialization.
2681
2726
  */
2682
2727
  buildWindowName(e) {
2683
- const n = e.hostDomain ?? this.getHostDomain(), s = Se(
2728
+ const n = e.hostDomain ?? this.getHostDomain(), s = Fe(
2684
2729
  e.props,
2685
2730
  e.propDefinitions,
2686
2731
  n,
@@ -2688,16 +2733,16 @@ class Pn {
2688
2733
  ), r = this.serializePropsForHost(
2689
2734
  s,
2690
2735
  e.propDefinitions
2691
- ), i = wn({
2736
+ ), i = gt({
2692
2737
  uid: this.uid,
2693
2738
  tag: e.tag,
2694
2739
  context: e.context,
2695
- consumerDomain: B(),
2740
+ consumerDomain: q(),
2696
2741
  props: r,
2697
2742
  exports: e.exports,
2698
2743
  children: e.children
2699
2744
  });
2700
- return un(i);
2745
+ return at(i);
2701
2746
  }
2702
2747
  /**
2703
2748
  * Waits for the host to send the initialization handshake.
@@ -2705,10 +2750,10 @@ class Pn {
2705
2750
  async waitForHost(e, n, s) {
2706
2751
  if (this.hostInitialized)
2707
2752
  return;
2708
- const r = Le();
2753
+ const r = Ge();
2709
2754
  this.initPromise = r;
2710
2755
  try {
2711
- await st(
2756
+ await _n(
2712
2757
  r.promise,
2713
2758
  e,
2714
2759
  `Host component "${n}" (uid: ${this.uid}) did not initialize within ${e}ms. Check that the host page loads correctly and calls the initialization code.`
@@ -2723,17 +2768,28 @@ class Pn {
2723
2768
  * Sets up host message handlers.
2724
2769
  */
2725
2770
  setupMessageHandlers(e) {
2726
- this.messenger.on(u.INIT, () => (this.hostInitialized = !0, this.initPromise && this.initPromise.resolve(), e.onInit && queueMicrotask(() => {
2727
- Promise.resolve(e.onInit?.()).catch((n) => {
2728
- e.onError(n);
2771
+ this.messenger.on(l.INIT, (n, s) => this.isHostControlSource(s) ? (this.hostInitialized = !0, this.initPromise && this.initPromise.resolve(), e.onInit && queueMicrotask(() => {
2772
+ Promise.resolve(e.onInit?.()).catch((r) => {
2773
+ e.onError(r);
2729
2774
  });
2730
- }), { success: !0 })), this.messenger.on(u.CLOSE, async () => (await e.onClose(), { success: !0 })), this.messenger.on(u.RESIZE, async (n) => (await e.onResize(n), { success: !0 })), this.messenger.on(u.FOCUS, async () => (await e.onFocus(), { success: !0 })), this.messenger.on(u.SHOW, async () => (await e.onShow(), { success: !0 })), this.messenger.on(u.HIDE, async () => (await e.onHide(), { success: !0 })), this.messenger.on(
2731
- u.ERROR,
2732
- async (n) => {
2733
- const s = new Error(n.message);
2734
- return s.stack = n.stack, e.onError(s), { success: !0 };
2775
+ }), { success: !0 }) : { success: !1 }), this.messenger.on(l.CLOSE, async (n, s) => this.isHostControlSource(s) ? (await e.onClose(), { success: !0 }) : { success: !1 }), this.messenger.on(l.RESIZE, async (n, s) => this.isHostControlSource(s) ? (await e.onResize(n), { success: !0 }) : { success: !1 }), this.messenger.on(l.FOCUS, async (n, s) => this.isHostControlSource(s) ? (await e.onFocus(), { success: !0 }) : { success: !1 }), this.messenger.on(l.SHOW, async (n, s) => this.isHostControlSource(s) ? (await e.onShow(), { success: !0 }) : { success: !1 }), this.messenger.on(l.HIDE, async (n, s) => this.isHostControlSource(s) ? (await e.onHide(), { success: !0 }) : { success: !1 }), this.messenger.on(
2776
+ l.ERROR,
2777
+ async (n, s) => {
2778
+ if (!this.isHostControlSource(s))
2779
+ return { success: !1 };
2780
+ const r = new Error(n.message);
2781
+ return r.stack = n.stack, e.onError(r), { success: !0 };
2735
2782
  }
2736
- ), this.messenger.on(u.EXPORT, async (n) => (e.onExport(n), { success: !0 })), this.messenger.on(u.CONSUMER_EXPORT, async (n) => (e.onConsumerExport(n), { success: !0 })), this.messenger.on(u.GET_SIBLINGS, async (n) => e.onGetSiblings(n));
2783
+ ), this.messenger.on(l.EXPORT, async (n, s) => this.isHostControlSource(s) ? (e.onExport(n), { success: !0 }) : { success: !1 }), this.messenger.on(l.CONSUMER_EXPORT, async (n, s) => this.isHostControlSource(s) ? (e.onConsumerExport(n), { success: !0 }) : { success: !1 }), this.messenger.on(
2784
+ l.GET_SIBLINGS,
2785
+ async (n, s) => this.isHostControlSource(s) ? e.onGetSiblings(n) : { success: !1 }
2786
+ );
2787
+ }
2788
+ /**
2789
+ * Returns true when a lifecycle/control message came from the opened host window.
2790
+ */
2791
+ isHostControlSource(e) {
2792
+ return !!(this.hostWindow && e.window === this.hostWindow);
2737
2793
  }
2738
2794
  /**
2739
2795
  * Destroys transport resources.
@@ -2742,7 +2798,7 @@ class Pn {
2742
2798
  this.messenger.destroy(), this.bridge.destroy();
2743
2799
  }
2744
2800
  }
2745
- class ye {
2801
+ class _e {
2746
2802
  /** Event emitter for lifecycle events. */
2747
2803
  event;
2748
2804
  /** Arbitrary state storage for the component instance. */
@@ -2776,106 +2832,6 @@ class ye {
2776
2832
  destroyed = !1;
2777
2833
  /** @internal */
2778
2834
  closing = !1;
2779
- /** @internal */
2780
- get props() {
2781
- return this.propsPipeline ? this.propsPipeline.props : {};
2782
- }
2783
- /** @internal */
2784
- set props(e) {
2785
- this.propsPipeline && (this.propsPipeline.props = e);
2786
- }
2787
- /** @internal */
2788
- get inputProps() {
2789
- return this.propsPipeline ? this.propsPipeline.inputProps : {};
2790
- }
2791
- /** @internal */
2792
- set inputProps(e) {
2793
- this.propsPipeline && (this.propsPipeline.inputProps = e);
2794
- }
2795
- /** @internal */
2796
- get pendingPropsUpdate() {
2797
- return this.propsPipeline ? this.propsPipeline.pendingPropsUpdate : null;
2798
- }
2799
- /** @internal */
2800
- set pendingPropsUpdate(e) {
2801
- this.propsPipeline && (this.propsPipeline.pendingPropsUpdate = e);
2802
- }
2803
- /** @internal */
2804
- get context() {
2805
- return this.renderer ? this.renderer.context : this.options.defaultContext;
2806
- }
2807
- /** @internal */
2808
- set context(e) {
2809
- this.renderer && (this.renderer.context = e);
2810
- }
2811
- /** @internal */
2812
- get hostWindow() {
2813
- return this.transport ? this.transport.hostWindow : null;
2814
- }
2815
- /** @internal */
2816
- set hostWindow(e) {
2817
- this.transport && (this.transport.hostWindow = e);
2818
- }
2819
- /** @internal */
2820
- get openedHostDomain() {
2821
- return this.transport ? this.transport.openedHostDomain : null;
2822
- }
2823
- /** @internal */
2824
- set openedHostDomain(e) {
2825
- this.transport && (this.transport.openedHostDomain = e);
2826
- }
2827
- /** @internal */
2828
- get dynamicUrlTrustedOrigin() {
2829
- return this.transport ? this.transport.dynamicUrlTrustedOrigin : null;
2830
- }
2831
- /** @internal */
2832
- set dynamicUrlTrustedOrigin(e) {
2833
- this.transport && (this.transport.dynamicUrlTrustedOrigin = e);
2834
- }
2835
- /** @internal */
2836
- get iframe() {
2837
- return this.renderer ? this.renderer.iframe : null;
2838
- }
2839
- /** @internal */
2840
- set iframe(e) {
2841
- this.renderer && (this.renderer.iframe = e);
2842
- }
2843
- /** @internal */
2844
- get container() {
2845
- return this.renderer ? this.renderer.container : null;
2846
- }
2847
- /** @internal */
2848
- set container(e) {
2849
- this.renderer && (this.renderer.container = e);
2850
- }
2851
- /** @internal */
2852
- get initPromise() {
2853
- return this.transport ? this.transport.initPromise : null;
2854
- }
2855
- /** @internal */
2856
- set initPromise(e) {
2857
- this.transport && (this.transport.initPromise = e);
2858
- }
2859
- /** @internal */
2860
- get hostInitialized() {
2861
- return this.transport ? this.transport.hostInitialized : !1;
2862
- }
2863
- /** @internal */
2864
- set hostInitialized(e) {
2865
- this.transport && (this.transport.hostInitialized = e);
2866
- }
2867
- /** @internal */
2868
- get messenger() {
2869
- if (!this.transport)
2870
- throw new Error("Consumer transport is not initialized");
2871
- return this.transport.messenger;
2872
- }
2873
- /** @internal */
2874
- get bridge() {
2875
- if (!this.transport)
2876
- throw new Error("Consumer transport is not initialized");
2877
- return this.transport.bridge;
2878
- }
2879
2835
  /**
2880
2836
  * Creates a new ConsumerComponent instance.
2881
2837
  *
@@ -2883,25 +2839,25 @@ class ye {
2883
2839
  * @param props - Initial props to pass to the component
2884
2840
  */
2885
2841
  constructor(e, n = {}) {
2886
- this._uid = tt(), this.options = this.normalizeOptions(e), this.event = new Ae(), this.cleanup = new nt(), this.renderer = new en(
2842
+ this._uid = wt(), this.options = this.normalizeOptions(e), this.event = new Le(), this.cleanup = new Bt(), this.renderer = new yn(
2887
2843
  this.options,
2888
2844
  this.uid,
2889
- () => this.props,
2845
+ () => this.propsPipeline.props,
2890
2846
  () => this.resolveDimensions(),
2891
2847
  {
2892
2848
  close: () => this.close(),
2893
2849
  focus: () => this.focus()
2894
2850
  }
2895
- ), this.propsPipeline = new Nt(
2851
+ ), this.propsPipeline = new Kt(
2896
2852
  this.options,
2897
2853
  { ...n },
2898
2854
  (s) => this.createPropContext(s)
2899
- ), this.transport = new Pn(
2855
+ ), !this.destroyed && (this.transport = new On(
2900
2856
  this.uid,
2901
2857
  this.options,
2902
2858
  () => this.resolveUrl(),
2903
2859
  (s) => this.resolveUrlOrigin(s)
2904
- ), this.setupMessageHandlers(), this.setupCleanup();
2860
+ ), this.setupMessageHandlers(), this.setupCleanup());
2905
2861
  }
2906
2862
  /**
2907
2863
  * Renders the component into a DOM container.
@@ -2926,14 +2882,14 @@ class ye {
2926
2882
  throw new Error("Component has been destroyed");
2927
2883
  if (this.rendered)
2928
2884
  throw new Error("Component has already been rendered");
2929
- this.context = n ?? this.options.defaultContext, this.checkEligibility(), T(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");
2885
+ this.renderer.context = n ?? this.options.defaultContext, this.checkEligibility(), H(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");
2930
2886
  try {
2931
- await this.open(), await this.waitForHost(), this.context === f.IFRAME && this.iframe && await this.renderer.swapPrerenderContentIfNeeded();
2887
+ await this.open(), await this.waitForHost(), this.renderer.context === f.IFRAME && this.renderer.iframe && await this.renderer.swapPrerenderContentIfNeeded();
2932
2888
  } catch (s) {
2933
2889
  throw await this.destroy().catch(() => {
2934
2890
  }), s;
2935
2891
  }
2936
- this.rendered = !0, this.event.emit(g.RENDERED), this.callPropCallback("onRendered"), this.event.emit(g.DISPLAY), this.callPropCallback("onDisplay");
2892
+ this.rendered = !0, this.event.emit(g.RENDERED), w(this.propsPipeline.props, "onRendered"), this.event.emit(g.DISPLAY), w(this.propsPipeline.props, "onDisplay");
2937
2893
  }
2938
2894
  /**
2939
2895
  * Renders the component into a container in a different window.
@@ -2961,7 +2917,8 @@ class ye {
2961
2917
  if (!(this.destroyed || this.closing)) {
2962
2918
  this.closing = !0;
2963
2919
  try {
2964
- this.event.emit(g.CLOSE), this.callPropCallback("onClose"), await this.destroy();
2920
+ const e = this.propsPipeline ? this.propsPipeline.props : {};
2921
+ this.event.emit(g.CLOSE), w(e, "onClose"), await this.destroy();
2965
2922
  } finally {
2966
2923
  this.closing = !1;
2967
2924
  }
@@ -2974,7 +2931,8 @@ class ye {
2974
2931
  * For iframes, focuses the iframe element. For popups, brings the window to front.
2975
2932
  */
2976
2933
  async focus() {
2977
- this.renderer.focus(this.hostWindow), this.event.emit(g.FOCUS), this.callPropCallback("onFocus");
2934
+ const e = this.transport ? this.transport.hostWindow : null, n = this.propsPipeline ? this.propsPipeline.props : {};
2935
+ this.renderer.focus(e), this.event.emit(g.FOCUS), w(n, "onFocus");
2978
2936
  }
2979
2937
  /**
2980
2938
  * Resizes the component to the specified dimensions.
@@ -2982,7 +2940,12 @@ class ye {
2982
2940
  * @param dimensions - New width and height for the component
2983
2941
  */
2984
2942
  async resize(e) {
2985
- this.renderer.resize(e, this.hostWindow), this.event.emit(g.RESIZE, e), this.callPropCallback("onResize", e);
2943
+ const n = this.transport ? this.transport.hostWindow : null, s = this.propsPipeline ? this.propsPipeline.props : {};
2944
+ this.renderer.resize(e, n), this.event.emit(g.RESIZE, e), w(
2945
+ s,
2946
+ "onResize",
2947
+ e
2948
+ );
2986
2949
  }
2987
2950
  /**
2988
2951
  * Shows the component if hidden.
@@ -3024,9 +2987,15 @@ class ye {
3024
2987
  assertStableRenderedOrigin: (s) => this.assertStableRenderedOrigin(s),
3025
2988
  isRendered: () => this.rendered,
3026
2989
  syncTrustedDomainForUrl: (s) => this.syncTrustedDomainForUrl(s),
3027
- shouldSendPropsToHost: () => this.transport.isHostConnected(),
2990
+ shouldSendPropsToHost: () => this.transport ? this.transport.isHostConnected() : !1,
3028
2991
  sendPropsUpdateToHost: (s) => this.sendPropsUpdateToHost(s),
3029
- emitPropsUpdated: () => this.emitPropsUpdated()
2992
+ emitPropsUpdated: (s) => {
2993
+ this.event.emit(g.PROPS, s), w(
2994
+ s,
2995
+ "onProps",
2996
+ s
2997
+ );
2998
+ }
3030
2999
  };
3031
3000
  await this.propsPipeline.updateProps(e, n);
3032
3001
  }
@@ -3035,9 +3004,10 @@ class ye {
3035
3004
  * @internal
3036
3005
  */
3037
3006
  assertStableRenderedOrigin(e) {
3038
- if (this.rendered && this.openedHostDomain && e && e !== this.openedHostDomain)
3007
+ const n = this.transport?.openedHostDomain;
3008
+ if (this.rendered && n && e && e !== n)
3039
3009
  throw new Error(
3040
- `Cannot change component URL origin after render (from "${this.openedHostDomain}" to "${e}")`
3010
+ `Cannot change component URL origin after render (from "${n}" to "${e}")`
3041
3011
  );
3042
3012
  }
3043
3013
  /**
@@ -3045,14 +3015,7 @@ class ye {
3045
3015
  * @internal
3046
3016
  */
3047
3017
  async sendPropsUpdateToHost(e) {
3048
- await this.transport.sendPropsUpdateToHost(e, this.options.props);
3049
- }
3050
- /**
3051
- * Emits prop update lifecycle hooks.
3052
- * @internal
3053
- */
3054
- emitPropsUpdated() {
3055
- this.event.emit(g.PROPS, this.props), this.callPropCallback("onProps", this.props);
3018
+ this.transport && await this.transport.sendPropsUpdateToHost(e, this.options.props);
3056
3019
  }
3057
3020
  /**
3058
3021
  * Creates a clone of this instance with the same props.
@@ -3060,8 +3023,8 @@ class ye {
3060
3023
  * @returns A new unrendered component instance with identical configuration
3061
3024
  */
3062
3025
  clone() {
3063
- const e = new ye(this.options, this.props);
3064
- return e.inputProps = { ...this.inputProps }, e;
3026
+ const e = new _e(this.options, this.propsPipeline.props);
3027
+ return e.propsPipeline.inputProps = { ...this.propsPipeline.inputProps }, e;
3065
3028
  }
3066
3029
  /**
3067
3030
  * Checks if the component is eligible to render based on the eligible option.
@@ -3069,7 +3032,7 @@ class ye {
3069
3032
  * @returns True if eligible or no eligibility check defined
3070
3033
  */
3071
3034
  isEligible() {
3072
- return this.options.eligible ? this.options.eligible({ props: this.props }).eligible : !0;
3035
+ return this.options.eligible ? this.options.eligible({ props: this.propsPipeline.props }).eligible : !0;
3073
3036
  }
3074
3037
  /**
3075
3038
  * Normalizes component options with default values.
@@ -3089,7 +3052,7 @@ class ye {
3089
3052
  * Resolves the host URL from static or function options.
3090
3053
  * @internal
3091
3054
  */
3092
- resolveUrl(e = this.props) {
3055
+ resolveUrl(e = this.propsPipeline.props) {
3093
3056
  return typeof this.options.url == "function" ? this.options.url(e) : this.options.url;
3094
3057
  }
3095
3058
  /**
@@ -3097,7 +3060,7 @@ class ye {
3097
3060
  * @internal
3098
3061
  */
3099
3062
  resolveDimensions() {
3100
- return typeof this.options.dimensions == "function" ? this.options.dimensions(this.props) : this.options.dimensions;
3063
+ return typeof this.options.dimensions == "function" ? this.options.dimensions(this.propsPipeline.props) : this.options.dimensions;
3101
3064
  }
3102
3065
  /**
3103
3066
  * Resolves a URL to an origin, supporting relative URLs.
@@ -3115,7 +3078,7 @@ class ye {
3115
3078
  * @internal
3116
3079
  */
3117
3080
  isExplicitDomainTrust(e) {
3118
- return this.transport.isExplicitDomainTrust(e);
3081
+ return this.transport ? this.transport.isExplicitDomainTrust(e) : !1;
3119
3082
  }
3120
3083
  /**
3121
3084
  * Ensures the messenger trusts the origin for a resolved host URL.
@@ -3123,20 +3086,25 @@ class ye {
3123
3086
  */
3124
3087
  syncTrustedDomainForUrl(e) {
3125
3088
  const n = this.resolveUrlOrigin(e);
3126
- n && this.isExplicitDomainTrust(n), this.transport.syncTrustedDomainForUrl(e);
3089
+ n && this.isExplicitDomainTrust(n), this.transport && this.transport.syncTrustedDomainForUrl(e);
3127
3090
  }
3128
3091
  /**
3129
3092
  * Creates the prop context passed to prop callbacks and validators.
3130
3093
  * @internal
3131
3094
  */
3132
- createPropContext(e = this.props) {
3095
+ createPropContext(e) {
3096
+ const n = e ?? this.propsPipeline?.props ?? {};
3133
3097
  return {
3134
- props: e,
3098
+ props: n,
3135
3099
  state: this.state,
3136
3100
  close: () => this.close(),
3137
3101
  focus: () => this.focus(),
3138
- onError: (n) => this.handleError(n),
3139
- container: this.container,
3102
+ onError: (s) => L(
3103
+ this.event,
3104
+ this.propsPipeline?.props ?? n,
3105
+ s
3106
+ ),
3107
+ container: this.renderer.container,
3140
3108
  uid: this.uid,
3141
3109
  tag: this.options.tag
3142
3110
  };
@@ -3154,7 +3122,7 @@ class ye {
3154
3122
  */
3155
3123
  checkEligibility() {
3156
3124
  if (!this.options.eligible) return;
3157
- const e = this.options.eligible({ props: this.props });
3125
+ const e = this.options.eligible({ props: this.propsPipeline.props });
3158
3126
  if (!e.eligible)
3159
3127
  throw new Error(`Component not eligible: ${e.reason ?? "Unknown reason"}`);
3160
3128
  }
@@ -3182,7 +3150,7 @@ class ye {
3182
3150
  */
3183
3151
  async open() {
3184
3152
  const e = this.resolveUrl();
3185
- this.syncTrustedDomainForUrl(e), this.openedHostDomain = this.resolveUrlOrigin(e), this.hostWindow = this.renderer.open({
3153
+ this.syncTrustedDomainForUrl(e), this.transport.openedHostDomain = this.resolveUrlOrigin(e), this.transport.hostWindow = this.renderer.open({
3186
3154
  baseUrl: e,
3187
3155
  buildUrl: (n) => this.buildUrl(n),
3188
3156
  buildBodyParams: () => this.buildBodyParams(),
@@ -3194,14 +3162,14 @@ class ye {
3194
3162
  registerCleanup: (n) => {
3195
3163
  this.cleanup.register(n);
3196
3164
  }
3197
- }), this.hostWindow && pt(this.uid, this.hostWindow);
3165
+ }), this.transport.hostWindow && Yt(this.uid, this.transport.hostWindow);
3198
3166
  }
3199
3167
  /**
3200
3168
  * Builds the URL for the host window including query parameters.
3201
3169
  * @internal
3202
3170
  */
3203
3171
  buildUrl(e = this.resolveUrl()) {
3204
- const s = wt(this.props, this.options.props).toString();
3172
+ const s = Wt(this.propsPipeline.props, this.options.props).toString();
3205
3173
  if (!s) return e;
3206
3174
  const r = e.includes("?") ? "&" : "?";
3207
3175
  return `${e}${r}${s}`;
@@ -3211,7 +3179,7 @@ class ye {
3211
3179
  * @internal
3212
3180
  */
3213
3181
  buildBodyParams() {
3214
- return _t(this.props, this.options.props);
3182
+ return jt(this.propsPipeline.props, this.options.props);
3215
3183
  }
3216
3184
  /**
3217
3185
  * Submits a hidden form to navigate a target window via POST.
@@ -3227,53 +3195,28 @@ class ye {
3227
3195
  buildWindowName() {
3228
3196
  return this.transport.buildWindowName({
3229
3197
  tag: this.options.tag,
3230
- context: this.context,
3231
- props: this.props,
3198
+ context: this.renderer.context,
3199
+ props: this.propsPipeline.props,
3232
3200
  propDefinitions: this.options.props,
3233
3201
  hostDomain: this.getHostDomain(),
3234
- children: this.buildNestedHostRefs(),
3202
+ children: qt(this.options, this.propsPipeline.props),
3235
3203
  exports: this.createConsumerExports()
3236
3204
  });
3237
3205
  }
3238
- /**
3239
- * Builds component references for nested host components.
3240
- * @internal
3241
- */
3242
- buildNestedHostRefs() {
3243
- if (!this.options.children) return;
3244
- const e = this.options.children({ props: this.props }), n = {};
3245
- for (const [s, r] of Object.entries(e)) {
3246
- const i = Nn(r);
3247
- if (!i)
3248
- throw new Error(`Nested component "${s}" is missing component metadata`);
3249
- if (typeof i.url != "string")
3250
- throw new Error(
3251
- `Nested component "${s}" must use a static string URL. Function URLs are not supported in children.`
3252
- );
3253
- n[s] = {
3254
- tag: i.tag,
3255
- url: i.url,
3256
- props: i.props,
3257
- dimensions: typeof i.dimensions == "function" ? void 0 : i.dimensions,
3258
- defaultContext: i.defaultContext
3259
- };
3260
- }
3261
- return Object.keys(n).length > 0 ? n : void 0;
3262
- }
3263
3206
  /**
3264
3207
  * Creates the exports object sent to the host.
3265
3208
  * @internal
3266
3209
  */
3267
3210
  createConsumerExports() {
3268
3211
  return {
3269
- init: u.INIT,
3270
- close: u.CLOSE,
3271
- resize: u.RESIZE,
3272
- show: u.SHOW,
3273
- hide: u.HIDE,
3274
- onError: u.ERROR,
3275
- updateProps: u.PROPS,
3276
- export: u.EXPORT
3212
+ init: l.INIT,
3213
+ close: l.CLOSE,
3214
+ resize: l.RESIZE,
3215
+ show: l.SHOW,
3216
+ hide: l.HIDE,
3217
+ onError: l.ERROR,
3218
+ updateProps: l.PROPS,
3219
+ export: l.EXPORT
3277
3220
  };
3278
3221
  }
3279
3222
  /**
@@ -3291,7 +3234,11 @@ class ye {
3291
3234
  await this.transport.waitForHost(
3292
3235
  this.options.timeout,
3293
3236
  this.options.tag,
3294
- (e) => this.handleError(e)
3237
+ (e) => L(
3238
+ this.event,
3239
+ this.propsPipeline.props,
3240
+ e
3241
+ )
3295
3242
  );
3296
3243
  }
3297
3244
  /**
@@ -3306,14 +3253,18 @@ class ye {
3306
3253
  onFocus: async () => this.focus(),
3307
3254
  onShow: async () => this.show(),
3308
3255
  onHide: async () => this.hide(),
3309
- onError: (e) => this.handleError(e),
3256
+ onError: (e) => L(
3257
+ this.event,
3258
+ this.propsPipeline.props,
3259
+ e
3260
+ ),
3310
3261
  onExport: (e) => {
3311
3262
  this.exports = e;
3312
3263
  },
3313
3264
  onConsumerExport: (e) => {
3314
3265
  this.consumerExports = e;
3315
3266
  },
3316
- onGetSiblings: (e) => this.getSiblingInstances(e)
3267
+ onGetSiblings: (e) => wn(e)
3317
3268
  });
3318
3269
  }
3319
3270
  /**
@@ -3321,14 +3272,18 @@ class ye {
3321
3272
  * @internal
3322
3273
  */
3323
3274
  async syncSameDomainPropsAfterInit() {
3324
- if (!(!this.hostWindow || !this.transport.isHostConnected()) && Me(this.hostWindow) && this.hasSameDomainPropDefinition())
3275
+ if (!(!this.transport.hostWindow || !this.transport.isHostConnected()) && qe(this.transport.hostWindow) && this.hasSameDomainPropDefinition())
3325
3276
  try {
3326
3277
  await this.propsPipeline.syncCurrentPropsToHost({
3327
3278
  shouldSendPropsToHost: () => this.transport.isHostConnected(),
3328
3279
  sendPropsUpdateToHost: (e) => this.sendPropsUpdateToHost(e)
3329
3280
  });
3330
3281
  } catch (e) {
3331
- this.handleError(e);
3282
+ L(
3283
+ this.event,
3284
+ this.propsPipeline.props,
3285
+ e
3286
+ );
3332
3287
  }
3333
3288
  }
3334
3289
  /**
@@ -3336,30 +3291,7 @@ class ye {
3336
3291
  * @internal
3337
3292
  */
3338
3293
  hasSameDomainPropDefinition() {
3339
- return Object.values(this.options.props).some((e) => !e || D(e) ? !1 : e.sameDomain === !0);
3340
- }
3341
- /**
3342
- * Gets sibling component instances for a request.
3343
- * @internal
3344
- */
3345
- getSiblingInstances(e) {
3346
- const n = [];
3347
- if (e.options?.anyConsumer) {
3348
- for (const s of Un())
3349
- s.instance.uid !== e.uid && n.push({
3350
- uid: s.instance.uid,
3351
- tag: s.tag,
3352
- exports: s.instance.exports
3353
- });
3354
- return n;
3355
- }
3356
- for (const s of Tn(e.tag))
3357
- s.uid !== e.uid && n.push({
3358
- uid: s.uid,
3359
- tag: e.tag,
3360
- exports: s.exports
3361
- });
3362
- return n;
3294
+ return Object.values(this.options.props).some((e) => !e || x(e) ? !1 : e.sameDomain === !0);
3363
3295
  }
3364
3296
  /**
3365
3297
  * Registers cleanup handlers for the instance.
@@ -3367,66 +3299,126 @@ class ye {
3367
3299
  */
3368
3300
  setupCleanup() {
3369
3301
  this.cleanup.register(() => {
3370
- this.messenger.destroy(), this.bridge.destroy(), ft(this.uid);
3302
+ this.transport.destroy(), Jt(this.uid);
3371
3303
  });
3372
3304
  }
3373
- /**
3374
- * Handles errors by emitting events and calling callbacks.
3375
- * @internal
3376
- */
3377
- handleError(e) {
3378
- this.event.emit(g.ERROR, e), this.callPropCallback("onError", e);
3379
- }
3380
- /**
3381
- * Calls a prop callback if it exists.
3382
- * @internal
3383
- */
3384
- callPropCallback(e, ...n) {
3385
- const s = this.props[e];
3386
- if (typeof s == "function")
3387
- try {
3388
- const r = s(...n);
3389
- r && typeof r == "object" && "catch" in r && typeof r.catch == "function" && r.catch((i) => {
3390
- console.error(`Error in async ${e} callback:`, i);
3391
- });
3392
- } catch (r) {
3393
- console.error(`Error in ${e} callback:`, r);
3394
- }
3395
- }
3396
3305
  /**
3397
3306
  * Destroys the component and cleans up all resources.
3398
3307
  * @internal
3399
3308
  */
3400
3309
  async destroy() {
3401
- this.destroyed || (this.destroyed = !0, this.initPromise && (this.initPromise.reject(
3310
+ if (this.destroyed) return;
3311
+ this.destroyed = !0;
3312
+ const e = this.propsPipeline ? this.propsPipeline.props : {}, n = this.transport ? this.transport.hostWindow : null;
3313
+ this.transport && this.transport.initPromise && (this.transport.initPromise.reject(
3402
3314
  new Error(
3403
3315
  `Component "${this.options.tag}" was destroyed before initialization completed`
3404
3316
  )
3405
- ), 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());
3317
+ ), 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();
3406
3318
  }
3407
3319
  }
3408
- const N = /* @__PURE__ */ new Map(), F = /* @__PURE__ */ new Map();
3409
- function En(t, e) {
3320
+ const U = /* @__PURE__ */ new Map(), F = /* @__PURE__ */ new Map();
3321
+ function Rn(t, e) {
3410
3322
  const n = e;
3411
- N.get(n.uid) && Xe(n.uid);
3323
+ U.get(n.uid) && Qe(n.uid);
3412
3324
  let r = F.get(t);
3413
- r || (r = /* @__PURE__ */ new Map(), F.set(t, r)), r.set(n.uid, n), N.set(n.uid, { tag: t, instance: n });
3325
+ r || (r = /* @__PURE__ */ new Map(), F.set(t, r)), r.set(n.uid, n), U.set(n.uid, { tag: t, instance: n });
3326
+ }
3327
+ function Qe(t) {
3328
+ const e = U.get(t);
3329
+ if (!e)
3330
+ return;
3331
+ U.delete(t);
3332
+ const n = F.get(e.tag);
3333
+ n && (n.delete(t), n.size === 0 && F.delete(e.tag));
3334
+ }
3335
+ function Dn(t) {
3336
+ return Array.from(F.get(t)?.values() ?? []);
3337
+ }
3338
+ function Sn() {
3339
+ return Array.from(U.values());
3340
+ }
3341
+ function xn() {
3342
+ return le();
3343
+ }
3344
+ function In() {
3345
+ return le();
3346
+ }
3347
+ function vn() {
3348
+ return window.hostProps;
3349
+ }
3350
+ const G = /* @__PURE__ */ new Map(), et = /* @__PURE__ */ Symbol("forgeframe.component.options");
3351
+ function Tn(t) {
3352
+ if (!t.tag)
3353
+ throw new Error("Component tag is required");
3354
+ if (!/^[a-z][a-z0-9-]*$/.test(t.tag))
3355
+ throw new Error(
3356
+ `Invalid component tag "${t.tag}". Must start with lowercase letter and contain only lowercase letters, numbers, and hyphens.`
3357
+ );
3358
+ if (!t.url)
3359
+ throw new Error("Component url is required");
3360
+ if (typeof t.url == "string")
3361
+ try {
3362
+ const e = ce() ? window.location.origin : "https://forgeframe.invalid";
3363
+ new URL(t.url, e);
3364
+ } catch {
3365
+ throw new Error(
3366
+ `Invalid component URL "${t.url}". Must be a valid absolute or relative URL.`
3367
+ );
3368
+ }
3369
+ if (G.has(t.tag))
3370
+ throw new Error(`Component "${t.tag}" is already registered`);
3371
+ }
3372
+ function tt(t) {
3373
+ Tn(t);
3374
+ const e = [];
3375
+ let n;
3376
+ const s = () => ce() && pt(t.tag), r = () => {
3377
+ if (n)
3378
+ return n;
3379
+ if (!s())
3380
+ return;
3381
+ const a = Ee(t.props, t.allowedConsumerDomains);
3382
+ if (a)
3383
+ return n = a.hostProps, n;
3384
+ };
3385
+ r();
3386
+ const i = () => (r(), n !== void 0 || s()), o = function(a = {}) {
3387
+ const c = new _e(t, a);
3388
+ return c.destroyed || (e.push(c), Rn(t.tag, c), c.event.once("destroy", () => {
3389
+ const d = e.indexOf(c);
3390
+ d !== -1 && e.splice(d, 1), Qe(c.uid);
3391
+ })), c;
3392
+ };
3393
+ return o.instances = e, o.isHost = () => i(), o.isEmbedded = () => i(), Object.defineProperty(o, "hostProps", {
3394
+ configurable: !0,
3395
+ enumerable: !0,
3396
+ get: () => r()
3397
+ }), o[et] = t, o.canRenderTo = async (a) => a === window, G.set(t.tag, o), o;
3398
+ }
3399
+ function Hn(t) {
3400
+ return Dn(t);
3401
+ }
3402
+ function Un() {
3403
+ return Sn();
3414
3404
  }
3415
- function Xe(t) {
3416
- const e = N.get(t);
3417
- if (!e)
3418
- return;
3419
- N.delete(t);
3420
- const n = F.get(e.tag);
3421
- n && (n.delete(t), n.size === 0 && F.delete(e.tag));
3405
+ function Fn(t) {
3406
+ return t[et];
3422
3407
  }
3423
- function bn(t) {
3424
- return Array.from(F.get(t)?.values() ?? []);
3408
+ async function Nn(t) {
3409
+ await t.close();
3410
+ }
3411
+ async function nt(t) {
3412
+ const e = G.get(t);
3413
+ if (!e) return;
3414
+ const n = [...e.instances];
3415
+ await Promise.all(n.map((s) => s.close()));
3425
3416
  }
3426
- function On() {
3427
- return Array.from(N.values());
3417
+ async function An() {
3418
+ const t = Array.from(G.keys());
3419
+ await Promise.all(t.map((e) => nt(e)));
3428
3420
  }
3429
- const Ge = "Could not resolve consumer window", ne = "Could not verify consumer origin", Cn = /* @__PURE__ */ new Set([
3421
+ const $n = /* @__PURE__ */ new Set([
3430
3422
  "uid",
3431
3423
  "tag",
3432
3424
  "close",
@@ -3443,89 +3435,52 @@ const Ge = "Could not resolve consumer window", ne = "Could not verify consumer
3443
3435
  "getPeerInstances",
3444
3436
  "children"
3445
3437
  ]);
3446
- function v(t) {
3438
+ function T(t) {
3447
3439
  const e = {};
3448
3440
  for (const [n, s] of Object.entries(t))
3449
- Cn.has(n) || (e[n] = s);
3441
+ $n.has(n) || (e[n] = s);
3450
3442
  return e;
3451
3443
  }
3452
- class Rn {
3453
- /**
3454
- * Creates a new HostComponent instance.
3455
- *
3456
- * @param payload - The payload parsed from window.name
3457
- * @param propDefinitions - Optional prop definitions for deserialization
3458
- * @param allowedConsumerDomains - Optional allowlist of consumer domains
3459
- * @param deferInit - Whether to defer INIT until a later explicit flush
3460
- */
3461
- constructor(e, n = {}, s, r = !1) {
3462
- this.propDefinitions = n, this.allowedConsumerDomains = s, this.deferInit = r, this.uid = e.uid, this.tag = e.tag, this.event = new Ae();
3463
- let i = null, o = null;
3464
- try {
3465
- this.consumerWindow = this.resolveConsumerWindow(), this.consumerDomain = this.resolveConsumerDomain(e.consumerDomain), o = new qe(this.uid, window, B(), this.consumerDomain), this.messenger = o, this.setupMessageHandlers(), i = new me(this.messenger), this.bridge = i, this.hostProps = this.buildHostProps(e), this.exposeHostProps(), this.deferInit || this.flushInit();
3466
- } catch (a) {
3467
- throw i?.destroy(), o?.destroy(), this.event.removeAllListeners(), this.propsHandlers.clear(), a;
3468
- }
3444
+ class Mn {
3445
+ constructor(e = {}, n) {
3446
+ this.propDefinitions = e, this.options = n;
3469
3447
  }
3470
- /** The hostProps object containing props and control methods passed from the consumer. */
3471
3448
  hostProps;
3472
- /** Event emitter for lifecycle events. */
3473
- event;
3474
- /** @internal */
3475
- uid;
3476
- /** @internal */
3477
- tag;
3478
- /** @internal */
3479
- consumerWindow;
3480
- /** @internal */
3481
- consumerDomain;
3482
- /** @internal */
3483
- consumerDomainVerified = !1;
3484
- /** @internal */
3485
- messenger;
3486
- /** @internal */
3487
- bridge;
3488
- /** @internal */
3489
- propsHandlers = /* @__PURE__ */ new Set();
3490
- /** @internal */
3491
3449
  consumerProps;
3492
- /** @internal */
3493
- initError = null;
3494
- /** @internal */
3495
- destroyed = !1;
3496
- /** @internal */
3497
- initSent = !1;
3498
- /** @internal */
3499
- deferredInitFlushScheduled = !1;
3500
- /**
3501
- * Ensures the INIT handshake is sent at most once.
3502
- * @internal
3503
- */
3504
- flushInit() {
3505
- this.destroyed || this.initSent || (this.initSent = !0, this.sendInit());
3506
- }
3507
- /**
3508
- * Schedules deferred INIT flush on the next microtask.
3509
- * This preserves legacy hostProps-only usage while giving same-tick
3510
- * host configuration a chance to run allowlist checks first.
3511
- * @internal
3512
- */
3513
- scheduleDeferredInitFlush() {
3514
- this.deferredInitFlushScheduled || this.destroyed || this.initSent || (this.deferredInitFlushScheduled = !0, queueMicrotask(() => {
3515
- this.deferredInitFlushScheduled = !1, this.flushInit();
3516
- }));
3450
+ propsHandlers = /* @__PURE__ */ new Set();
3451
+ initializeHostProps(e) {
3452
+ const n = this.deserialize(e.props);
3453
+ H(n, this.getBootstrapValidationDefinitions()), this.consumerProps = n;
3454
+ const s = T(n);
3455
+ return this.hostProps = {
3456
+ ...s,
3457
+ uid: this.options.uid,
3458
+ tag: this.options.tag,
3459
+ close: () => this.options.controls.close(),
3460
+ focus: () => this.options.controls.focus(),
3461
+ resize: (r) => this.options.controls.resize(r),
3462
+ show: () => this.options.controls.show(),
3463
+ hide: () => this.options.controls.hide(),
3464
+ onProps: (r) => this.onProps(r),
3465
+ onError: (r) => this.options.controls.onError(r),
3466
+ getConsumer: () => this.options.getConsumerWindow(),
3467
+ getConsumerDomain: () => this.options.getConsumerDomain(),
3468
+ export: (r) => this.options.controls.exportData(r),
3469
+ consumer: {
3470
+ props: this.consumerProps,
3471
+ export: (r) => this.options.controls.consumerExport(r)
3472
+ },
3473
+ getPeerInstances: (r) => this.options.controls.getPeerInstances(r),
3474
+ children: this.buildNestedComponents(e.children)
3475
+ }, this.hostProps;
3517
3476
  }
3518
- /**
3519
- * Exposes hostProps on window and lazily flushes deferred init on first access.
3520
- * @internal
3521
- */
3522
3477
  exposeHostProps() {
3523
3478
  const e = window;
3524
3479
  try {
3525
3480
  Object.defineProperty(e, "hostProps", {
3526
3481
  configurable: !0,
3527
3482
  enumerable: !0,
3528
- get: () => (this.deferInit && !this.initSent && !this.destroyed && this.scheduleDeferredInitFlush(), this.hostProps),
3483
+ get: () => (this.options.onFirstHostPropsAccess(), this.hostProps),
3529
3484
  set: (n) => {
3530
3485
  n && (this.hostProps = n);
3531
3486
  }
@@ -3534,579 +3489,411 @@ class Rn {
3534
3489
  e.hostProps = this.hostProps;
3535
3490
  }
3536
3491
  }
3537
- /**
3538
- * Validates that the consumer domain is allowed.
3539
- * @internal
3540
- */
3541
- validateConsumerDomain() {
3542
- if (this.allowedConsumerDomains) {
3543
- if (!this.consumerDomain)
3544
- throw new Error(
3545
- `${ne} for component "${this.tag}"`
3546
- );
3547
- if (!U(this.allowedConsumerDomains, this.consumerDomain))
3548
- throw new Error(
3549
- `Consumer domain "${this.consumerDomain}" is not allowed for component "${this.tag}"`
3550
- );
3551
- }
3552
- }
3553
- /**
3554
- * Reads a browser-verifiable consumer origin when available.
3555
- * @internal
3556
- */
3557
- getVerifiedConsumerOrigin() {
3558
- return this.getReferrerOrigin() ?? this.getAccessibleConsumerOrigin();
3559
- }
3560
- /**
3561
- * Updates the tracked consumer origin and keeps trusted messaging origins in sync.
3562
- * @internal
3563
- */
3564
- setConsumerDomain(e, n) {
3565
- const s = this.consumerDomain;
3566
- this.consumerDomain = e, this.consumerDomainVerified = n, !(!this.messenger || !s || s === e) && (this.messenger.removeTrustedDomain(s), this.messenger.addTrustedDomain(e));
3567
- }
3568
- /**
3569
- * Applies host configuration that may arrive after deferred pre-initialization.
3570
- * @internal
3571
- */
3572
- applyHostConfiguration(e, n) {
3573
- n !== void 0 && (this.allowedConsumerDomains = n), e !== void 0 && (this.propDefinitions = e, T(this.consumerProps, this.getBootstrapValidationDefinitions()), Object.assign(this.hostProps, v(this.consumerProps)), this.hostProps.consumer.props = this.consumerProps);
3574
- }
3575
- /**
3576
- * Resolves the consumer origin from browser-provided context and falls back to the
3577
- * claimed bootstrap origin only when no explicit allowlist is configured.
3578
- * @internal
3579
- */
3580
- resolveConsumerDomain(e) {
3581
- const n = this.getVerifiedConsumerOrigin();
3582
- if (n)
3583
- return this.consumerDomainVerified = !0, this.consumerDomain = n, this.validateConsumerDomain(), n;
3584
- if (this.consumerDomainVerified = !1, this.allowedConsumerDomains)
3585
- throw new Error(
3586
- `${ne} for component "${this.tag}"`
3587
- );
3588
- return e;
3589
- }
3590
- /**
3591
- * Rechecks allowlist constraints against a browser-verified consumer origin.
3592
- * @internal
3593
- */
3594
- assertAllowedConsumerDomain(e) {
3595
- const n = this.getVerifiedConsumerOrigin();
3596
- if (n && this.setConsumerDomain(n, !0), !this.consumerDomainVerified)
3597
- throw new Error(
3598
- `${ne} for component "${this.tag}"`
3599
- );
3600
- if (!U(e, this.consumerDomain))
3601
- throw new Error(
3602
- `Consumer domain "${this.consumerDomain}" is not allowed for component "${this.tag}"`
3603
- );
3604
- }
3605
- /**
3606
- * Reads the consumer origin from the browser-provided referrer when available.
3607
- * @internal
3608
- */
3609
- getReferrerOrigin() {
3610
- if (!document.referrer)
3611
- return null;
3612
- try {
3613
- return new URL(document.referrer, window.location.href).origin;
3614
- } catch {
3615
- return null;
3616
- }
3492
+ applyHostConfiguration(e) {
3493
+ this.propDefinitions = e, H(this.consumerProps, this.getBootstrapValidationDefinitions()), Object.assign(this.hostProps, T(this.consumerProps)), this.hostProps.consumer.props = this.consumerProps;
3617
3494
  }
3618
- /**
3619
- * Reads the consumer origin directly when same-origin access is available.
3620
- * @internal
3621
- */
3622
- getAccessibleConsumerOrigin() {
3495
+ applySerializedProps(e) {
3623
3496
  try {
3624
- return this.consumerWindow.location.origin;
3625
- } catch {
3626
- return null;
3497
+ const n = this.consumerProps, s = this.deserialize(e);
3498
+ H(s, this.propDefinitions), this.removeStaleHostProps(n, s), this.consumerProps = s, Object.assign(this.hostProps, T(s)), this.hostProps.consumer.props = this.consumerProps;
3499
+ for (const r of this.propsHandlers)
3500
+ try {
3501
+ r(s);
3502
+ } catch (i) {
3503
+ console.error("Error in props handler:", i);
3504
+ }
3505
+ return this.options.event.emit(g.PROPS, s), { success: !0 };
3506
+ } catch (n) {
3507
+ const s = n instanceof Error ? n : new Error(String(n));
3508
+ throw console.error("Error deserializing props:", s), this.options.event.emit(g.ERROR, s), s;
3627
3509
  }
3628
3510
  }
3629
- /**
3630
- * Returns the hostProps object.
3631
- *
3632
- * @returns The hostProps object with props and control methods
3633
- */
3634
- getProps() {
3635
- return this.hostProps;
3511
+ destroy() {
3512
+ this.propsHandlers.clear();
3636
3513
  }
3637
- /**
3638
- * Resolves the consumer window reference (iframe parent or popup opener).
3639
- * @internal
3640
- */
3641
- resolveConsumerWindow() {
3642
- if (ut()) {
3643
- const e = lt();
3644
- if (e) return e;
3645
- }
3646
- if (ht()) {
3647
- const e = ct();
3648
- if (e) return e;
3649
- }
3650
- throw new Error(Ge);
3514
+ onProps(e) {
3515
+ return this.propsHandlers.add(e), {
3516
+ cancel: () => this.propsHandlers.delete(e)
3517
+ };
3651
3518
  }
3652
- /**
3653
- * Builds the hostProps object with deserialized props and control methods.
3654
- * @internal
3655
- */
3656
- buildHostProps(e) {
3657
- const n = Ue(
3658
- e.props,
3519
+ deserialize(e) {
3520
+ return Tt(
3521
+ e,
3659
3522
  this.propDefinitions,
3660
- this.messenger,
3661
- this.bridge,
3662
- this.consumerWindow,
3663
- this.consumerDomain
3523
+ this.options.getMessenger(),
3524
+ this.options.getBridge(),
3525
+ this.options.getConsumerWindow(),
3526
+ this.options.getConsumerDomain()
3664
3527
  );
3665
- return T(n, this.getBootstrapValidationDefinitions()), this.consumerProps = n, {
3666
- ...v(n),
3667
- uid: this.uid,
3668
- tag: this.tag,
3669
- close: () => this.close(),
3670
- focus: () => this.focus(),
3671
- resize: (r) => this.resize(r),
3672
- show: () => this.show(),
3673
- hide: () => this.hide(),
3674
- onProps: (r) => this.onProps(r),
3675
- onError: (r) => this.onError(r),
3676
- getConsumer: () => this.consumerWindow,
3677
- getConsumerDomain: () => this.consumerDomain,
3678
- export: (r) => this.exportData(r),
3679
- consumer: {
3680
- props: this.consumerProps,
3681
- export: (r) => this.consumerExport(r)
3682
- },
3683
- getPeerInstances: (r) => this.getPeerInstances(r),
3684
- children: this.buildNestedComponents(e.children)
3685
- };
3686
3528
  }
3687
- /**
3688
- * Relaxes required sameDomain props during bootstrap for verified same-origin hosts.
3689
- * Those props are synchronized after INIT through the live messaging channel.
3690
- * @internal
3691
- */
3692
3529
  getBootstrapValidationDefinitions() {
3693
- if (!this.consumerDomainVerified || this.consumerDomain !== B())
3530
+ if (!this.options.isConsumerDomainVerified() || this.options.getConsumerDomain() !== q())
3694
3531
  return this.propDefinitions;
3695
3532
  let e = !1;
3696
3533
  const n = {
3697
3534
  ...this.propDefinitions
3698
3535
  };
3699
3536
  for (const [s, r] of Object.entries(this.propDefinitions))
3700
- !r || D(r) || !r.sameDomain || (e = !0, n[s] = {
3537
+ !r || x(r) || !r.sameDomain || (e = !0, n[s] = {
3701
3538
  ...r,
3702
3539
  required: !1
3703
3540
  });
3704
3541
  return e ? n : this.propDefinitions;
3705
3542
  }
3706
- /**
3707
- * Sends initialization message to the consumer.
3708
- * @internal
3709
- */
3543
+ buildNestedComponents(e) {
3544
+ if (!e)
3545
+ return;
3546
+ const n = {};
3547
+ for (const [s, r] of Object.entries(e))
3548
+ try {
3549
+ n[s] = tt({
3550
+ tag: r.tag,
3551
+ url: r.url,
3552
+ props: r.props,
3553
+ dimensions: r.dimensions,
3554
+ defaultContext: r.defaultContext
3555
+ });
3556
+ } catch (i) {
3557
+ console.warn(`Failed to create nested component "${s}":`, i);
3558
+ }
3559
+ return Object.keys(n).length > 0 ? n : void 0;
3560
+ }
3561
+ removeStaleHostProps(e, n) {
3562
+ const s = T(e), r = T(n);
3563
+ for (const i of Object.keys(s))
3564
+ i in r || delete this.hostProps[i];
3565
+ }
3566
+ }
3567
+ const st = "Could not resolve consumer window", Pe = "Could not verify consumer origin";
3568
+ function rt(t, e, n) {
3569
+ if (!e)
3570
+ throw new Error(
3571
+ `${Pe} for component "${n}"`
3572
+ );
3573
+ if (!X(t, e))
3574
+ throw new Error(
3575
+ `Consumer domain "${e}" is not allowed for component "${n}"`
3576
+ );
3577
+ }
3578
+ function zn(t = window) {
3579
+ if (Mt(t)) {
3580
+ const e = $t(t);
3581
+ if (e)
3582
+ return e;
3583
+ }
3584
+ if (zt(t)) {
3585
+ const e = At(t);
3586
+ if (e)
3587
+ return e;
3588
+ }
3589
+ throw new Error(st);
3590
+ }
3591
+ function Ln(t = document, e = window) {
3592
+ if (!t.referrer)
3593
+ return null;
3594
+ try {
3595
+ return new URL(t.referrer, e.location.href).origin;
3596
+ } catch {
3597
+ return null;
3598
+ }
3599
+ }
3600
+ function kn(t) {
3601
+ try {
3602
+ return t.location.origin;
3603
+ } catch {
3604
+ return null;
3605
+ }
3606
+ }
3607
+ function it(t, e = document, n = window) {
3608
+ return Ln(e, n) ?? kn(t);
3609
+ }
3610
+ function Wn(t) {
3611
+ const e = it(t.consumerWindow);
3612
+ if (e)
3613
+ return t.allowedConsumerDomains && rt(
3614
+ t.allowedConsumerDomains,
3615
+ e,
3616
+ t.tag
3617
+ ), {
3618
+ consumerDomain: e,
3619
+ consumerDomainVerified: !0
3620
+ };
3621
+ if (t.allowedConsumerDomains)
3622
+ throw new Error(
3623
+ `${Pe} for component "${t.tag}"`
3624
+ );
3625
+ return {
3626
+ consumerDomain: t.claimedConsumerDomain,
3627
+ consumerDomainVerified: !1
3628
+ };
3629
+ }
3630
+ function jn(t) {
3631
+ const e = it(t.consumerWindow);
3632
+ let n = t.consumerDomain, s = t.consumerDomainVerified;
3633
+ if (e && (e !== n && t.onConsumerDomainChange?.(n, e), n = e, s = !0), !s)
3634
+ throw new Error(
3635
+ `${Pe} for component "${t.tag}"`
3636
+ );
3637
+ return rt(
3638
+ t.allowedConsumerDomains,
3639
+ n,
3640
+ t.tag
3641
+ ), {
3642
+ consumerDomain: n,
3643
+ consumerDomainVerified: s
3644
+ };
3645
+ }
3646
+ class Bn {
3647
+ constructor(e) {
3648
+ this.options = e, this.messenger = new Ze(
3649
+ this.options.uid,
3650
+ window,
3651
+ q(),
3652
+ this.options.consumerDomain
3653
+ ), this.bridge = new de(this.messenger);
3654
+ }
3655
+ messenger;
3656
+ bridge;
3657
+ destroyed = !1;
3658
+ initSent = !1;
3659
+ initError = null;
3660
+ deferredInitFlushScheduled = !1;
3661
+ registerPropsHandler(e) {
3662
+ this.messenger.on(l.PROPS, (n, s) => e.isConsumerSource(s) ? e.applySerializedProps(n) : { success: !1 });
3663
+ }
3664
+ handleHostPropsAccess() {
3665
+ this.options.deferInit && !this.initSent && !this.destroyed && this.scheduleDeferredInitFlush();
3666
+ }
3667
+ flushInit() {
3668
+ this.destroyed || this.initSent || (this.initSent = !0, this.sendInit());
3669
+ }
3670
+ getInitError() {
3671
+ return this.initError;
3672
+ }
3673
+ updateTrustedConsumerDomain(e, n) {
3674
+ !e || e === n || (this.messenger.removeTrustedDomain(e), this.messenger.addTrustedDomain(n));
3675
+ }
3676
+ async close() {
3677
+ await this.sendMessage(l.CLOSE, {});
3678
+ }
3679
+ async focus() {
3680
+ window.focus(), await this.sendMessage(l.FOCUS, {});
3681
+ }
3682
+ async resize(e) {
3683
+ await this.sendMessage(l.RESIZE, e);
3684
+ }
3685
+ async show() {
3686
+ await this.sendMessage(l.SHOW, {});
3687
+ }
3688
+ async hide() {
3689
+ await this.sendMessage(l.HIDE, {});
3690
+ }
3691
+ async onError(e) {
3692
+ await this.sendMessage(l.ERROR, {
3693
+ message: e.message,
3694
+ stack: e.stack
3695
+ });
3696
+ }
3697
+ async exportData(e) {
3698
+ await this.sendMessage(l.EXPORT, e);
3699
+ }
3700
+ async consumerExport(e) {
3701
+ await this.sendMessage(l.CONSUMER_EXPORT, e);
3702
+ }
3703
+ async getPeerInstances(e) {
3704
+ return await this.messenger.send(
3705
+ this.options.consumerWindow,
3706
+ this.options.getConsumerDomain(),
3707
+ l.GET_SIBLINGS,
3708
+ {
3709
+ uid: this.options.uid,
3710
+ tag: this.options.tag,
3711
+ options: e
3712
+ }
3713
+ ) ?? [];
3714
+ }
3715
+ destroy() {
3716
+ this.destroyed || (this.destroyed = !0, this.deferredInitFlushScheduled = !1, this.messenger.destroy(), this.bridge.destroy());
3717
+ }
3718
+ scheduleDeferredInitFlush() {
3719
+ this.deferredInitFlushScheduled || this.destroyed || this.initSent || (this.deferredInitFlushScheduled = !0, queueMicrotask(() => {
3720
+ this.deferredInitFlushScheduled = !1, this.flushInit();
3721
+ }));
3722
+ }
3710
3723
  async sendInit() {
3711
3724
  try {
3712
- await this.messenger.send(
3713
- this.consumerWindow,
3714
- this.consumerDomain,
3715
- u.INIT,
3716
- { uid: this.uid, tag: this.tag }
3717
- );
3725
+ await this.sendMessage(l.INIT, {
3726
+ uid: this.options.uid,
3727
+ tag: this.options.tag
3728
+ });
3718
3729
  } catch (e) {
3719
3730
  const n = e instanceof Error ? e : new Error(String(e));
3720
- this.initError = n, this.event.emit(g.ERROR, {
3731
+ this.initError = n, this.options.event.emit(g.ERROR, {
3721
3732
  type: "init_failed",
3722
3733
  message: `Failed to initialize host component: ${n.message}`,
3723
3734
  error: n
3724
3735
  }), console.error("Failed to send init message:", e);
3725
3736
  }
3726
3737
  }
3727
- /**
3728
- * Returns the initialization error if one occurred.
3729
- *
3730
- * @returns The initialization error or null if successful
3731
- */
3732
- getInitError() {
3733
- return this.initError;
3734
- }
3735
- /**
3736
- * Requests the consumer to close this component.
3737
- * @internal
3738
- */
3739
- async close() {
3740
- await this.messenger.send(
3741
- this.consumerWindow,
3742
- this.consumerDomain,
3743
- u.CLOSE,
3744
- {}
3745
- );
3746
- }
3747
- /**
3748
- * Focuses this window and notifies the consumer.
3749
- * @internal
3750
- */
3751
- async focus() {
3752
- window.focus(), await this.messenger.send(
3753
- this.consumerWindow,
3754
- this.consumerDomain,
3755
- u.FOCUS,
3756
- {}
3757
- );
3758
- }
3759
- /**
3760
- * Requests the consumer to resize this component.
3761
- * @internal
3762
- */
3763
- async resize(e) {
3764
- await this.messenger.send(
3765
- this.consumerWindow,
3766
- this.consumerDomain,
3767
- u.RESIZE,
3768
- e
3769
- );
3770
- }
3771
- /**
3772
- * Requests the consumer to show this component.
3773
- * @internal
3774
- */
3775
- async show() {
3738
+ async sendMessage(e, n) {
3776
3739
  await this.messenger.send(
3777
- this.consumerWindow,
3778
- this.consumerDomain,
3779
- u.SHOW,
3780
- {}
3740
+ this.options.consumerWindow,
3741
+ this.options.getConsumerDomain(),
3742
+ e,
3743
+ n
3781
3744
  );
3782
3745
  }
3783
- /**
3784
- * Requests the consumer to hide this component.
3785
- * @internal
3786
- */
3787
- async hide() {
3788
- await this.messenger.send(
3789
- this.consumerWindow,
3790
- this.consumerDomain,
3791
- u.HIDE,
3792
- {}
3793
- );
3746
+ }
3747
+ class Vn {
3748
+ event;
3749
+ uid;
3750
+ tag;
3751
+ consumerWindow;
3752
+ consumerDomain;
3753
+ consumerDomainVerified = !1;
3754
+ allowedConsumerDomains;
3755
+ transport;
3756
+ propsRuntime;
3757
+ destroyed = !1;
3758
+ constructor(e, n = {}, s, r = !1) {
3759
+ this.uid = e.uid, this.tag = e.tag, this.event = new Le(), this.allowedConsumerDomains = s;
3760
+ let i = null, o = null;
3761
+ try {
3762
+ this.consumerWindow = zn();
3763
+ const a = Wn({
3764
+ consumerWindow: this.consumerWindow,
3765
+ claimedConsumerDomain: e.consumerDomain,
3766
+ allowedConsumerDomains: this.allowedConsumerDomains,
3767
+ tag: this.tag
3768
+ });
3769
+ this.consumerDomain = a.consumerDomain, this.consumerDomainVerified = a.consumerDomainVerified, i = new Bn({
3770
+ uid: this.uid,
3771
+ tag: this.tag,
3772
+ event: this.event,
3773
+ consumerWindow: this.consumerWindow,
3774
+ consumerDomain: this.consumerDomain,
3775
+ getConsumerDomain: () => this.consumerDomain,
3776
+ deferInit: r
3777
+ }), this.transport = i, o = new Mn(n, {
3778
+ uid: this.uid,
3779
+ tag: this.tag,
3780
+ event: this.event,
3781
+ controls: {
3782
+ close: () => this.transport.close(),
3783
+ focus: () => this.transport.focus(),
3784
+ resize: (c) => this.transport.resize(c),
3785
+ show: () => this.transport.show(),
3786
+ hide: () => this.transport.hide(),
3787
+ onError: (c) => this.transport.onError(c),
3788
+ exportData: (c) => this.transport.exportData(c),
3789
+ consumerExport: (c) => this.transport.consumerExport(c),
3790
+ getPeerInstances: (c) => this.transport.getPeerInstances(c)
3791
+ },
3792
+ getConsumerWindow: () => this.consumerWindow,
3793
+ getConsumerDomain: () => this.consumerDomain,
3794
+ isConsumerDomainVerified: () => this.consumerDomainVerified,
3795
+ getMessenger: () => this.transport.messenger,
3796
+ getBridge: () => this.transport.bridge,
3797
+ onFirstHostPropsAccess: () => this.transport.handleHostPropsAccess()
3798
+ }), this.propsRuntime = o, Object.defineProperties(this, {
3799
+ messenger: {
3800
+ configurable: !0,
3801
+ get: () => this.transport.messenger
3802
+ },
3803
+ bridge: {
3804
+ configurable: !0,
3805
+ get: () => this.transport.bridge
3806
+ },
3807
+ consumerProps: {
3808
+ configurable: !0,
3809
+ get: () => this.propsRuntime.consumerProps
3810
+ },
3811
+ propsHandlers: {
3812
+ configurable: !0,
3813
+ get: () => this.propsRuntime.propsHandlers
3814
+ }
3815
+ }), this.transport.registerPropsHandler({
3816
+ isConsumerSource: (c) => c.window === this.consumerWindow,
3817
+ applySerializedProps: (c) => this.propsRuntime.applySerializedProps(c)
3818
+ }), this.hostProps = this.propsRuntime.initializeHostProps(e), this.propsRuntime.exposeHostProps(), r || this.flushInit();
3819
+ } catch (a) {
3820
+ throw o?.destroy(), i?.destroy(), this.event.removeAllListeners(), a;
3821
+ }
3794
3822
  }
3795
- /**
3796
- * Subscribes to prop updates from the consumer.
3797
- * @internal
3798
- */
3799
- onProps(e) {
3800
- return this.propsHandlers.add(e), {
3801
- cancel: () => this.propsHandlers.delete(e)
3802
- };
3823
+ get hostProps() {
3824
+ return this.propsRuntime.hostProps;
3803
3825
  }
3804
- /**
3805
- * Reports an error to the consumer.
3806
- * @internal
3807
- */
3808
- async onError(e) {
3809
- await this.messenger.send(
3810
- this.consumerWindow,
3811
- this.consumerDomain,
3812
- u.ERROR,
3813
- {
3814
- message: e.message,
3815
- stack: e.stack
3816
- }
3817
- );
3826
+ set hostProps(e) {
3827
+ this.propsRuntime.hostProps = e;
3818
3828
  }
3819
- /**
3820
- * Exports data or methods to the consumer.
3821
- * @internal
3822
- */
3823
- async exportData(e) {
3824
- await this.messenger.send(
3825
- this.consumerWindow,
3826
- this.consumerDomain,
3827
- u.EXPORT,
3828
- e
3829
- );
3829
+ flushInit() {
3830
+ this.transport.flushInit();
3830
3831
  }
3831
- /**
3832
- * Exports data to the consumer for bidirectional communication.
3833
- * @internal
3834
- */
3835
- async consumerExport(e) {
3836
- await this.messenger.send(
3837
- this.consumerWindow,
3838
- this.consumerDomain,
3839
- u.CONSUMER_EXPORT,
3840
- e
3841
- );
3832
+ getProps() {
3833
+ return this.hostProps;
3842
3834
  }
3843
- /**
3844
- * Gets information about peer component instances.
3845
- * @internal
3846
- */
3847
- async getPeerInstances(e) {
3848
- return await this.messenger.send(
3849
- this.consumerWindow,
3850
- this.consumerDomain,
3851
- u.GET_SIBLINGS,
3852
- { uid: this.uid, tag: this.tag, options: e }
3853
- ) ?? [];
3835
+ getInitError() {
3836
+ return this.transport.getInitError();
3854
3837
  }
3855
- /**
3856
- * Builds nested component factories from refs passed by the consumer.
3857
- * @internal
3858
- */
3859
- buildNestedComponents(e) {
3860
- if (!e) return;
3861
- const n = {};
3862
- for (const [s, r] of Object.entries(e))
3863
- try {
3864
- n[s] = Qe({
3865
- tag: r.tag,
3866
- url: r.url,
3867
- props: r.props,
3868
- dimensions: r.dimensions,
3869
- defaultContext: r.defaultContext
3870
- });
3871
- } catch (i) {
3872
- console.warn(`Failed to create nested component "${s}":`, i);
3873
- }
3874
- return Object.keys(n).length > 0 ? n : void 0;
3838
+ applyHostConfiguration(e, n) {
3839
+ n !== void 0 && (this.allowedConsumerDomains = n), e !== void 0 && this.propsRuntime.applyHostConfiguration(e);
3875
3840
  }
3876
- /**
3877
- * Sets up message handlers for consumer communication.
3878
- * @internal
3879
- */
3880
- setupMessageHandlers() {
3881
- this.messenger.on(u.PROPS, (e) => {
3882
- try {
3883
- const n = this.consumerProps, s = Ue(
3884
- e,
3885
- this.propDefinitions,
3886
- this.messenger,
3887
- this.bridge,
3888
- this.consumerWindow,
3889
- this.consumerDomain
3890
- );
3891
- T(s, this.propDefinitions), this.removeStaleHostProps(n, s), this.consumerProps = s, Object.assign(this.hostProps, v(s)), this.hostProps.consumer.props = this.consumerProps;
3892
- for (const r of this.propsHandlers)
3893
- try {
3894
- r(s);
3895
- } catch (i) {
3896
- console.error("Error in props handler:", i);
3897
- }
3898
- return this.event.emit(g.PROPS, s), { success: !0 };
3899
- } catch (n) {
3900
- const s = n instanceof Error ? n : new Error(String(n));
3901
- throw console.error("Error deserializing props:", s), this.event.emit(g.ERROR, s), s;
3841
+ assertAllowedConsumerDomain(e) {
3842
+ const n = jn({
3843
+ consumerWindow: this.consumerWindow,
3844
+ consumerDomain: this.consumerDomain,
3845
+ consumerDomainVerified: this.consumerDomainVerified,
3846
+ allowedConsumerDomains: e,
3847
+ tag: this.tag,
3848
+ onConsumerDomainChange: (s, r) => {
3849
+ this.transport.updateTrustedConsumerDomain(s, r);
3902
3850
  }
3903
3851
  });
3852
+ this.consumerDomain = n.consumerDomain, this.consumerDomainVerified = n.consumerDomainVerified;
3904
3853
  }
3905
- /**
3906
- * Removes stale prop keys that are no longer present in the latest consumer payload.
3907
- * @internal
3908
- */
3909
- removeStaleHostProps(e, n) {
3910
- const s = v(e), r = v(n);
3911
- for (const i of Object.keys(s))
3912
- i in r || delete this.hostProps[i];
3913
- }
3914
- /**
3915
- * Destroys the host component and cleans up resources.
3916
- */
3917
3854
  destroy() {
3918
- this.destroyed || (this.destroyed = !0, this.deferredInitFlushScheduled = !1, this.messenger.destroy(), this.bridge.destroy(), this.event.removeAllListeners(), this.propsHandlers.clear());
3855
+ this.destroyed || (this.destroyed = !0, this.transport.destroy(), this.event.removeAllListeners(), this.propsRuntime.destroy());
3919
3856
  }
3920
3857
  }
3921
- let w = null;
3922
- function we(t, e, n = {}) {
3923
- if (w) {
3858
+ let _ = null;
3859
+ function Ee(t, e, n = {}) {
3860
+ if (_) {
3924
3861
  try {
3925
- w.applyHostConfiguration(
3862
+ _.applyHostConfiguration(
3926
3863
  t,
3927
3864
  e
3928
- ), e && w.assertAllowedConsumerDomain(e);
3865
+ ), e && _.assertAllowedConsumerDomain(e);
3929
3866
  } catch (r) {
3930
- throw Sn(), r;
3867
+ throw Yn(), r;
3931
3868
  }
3932
- return n.deferInit || w.flushInit(), w;
3869
+ return n.deferInit || _.flushInit(), _;
3933
3870
  }
3934
- if (!ge())
3871
+ if (!le())
3935
3872
  return null;
3936
- const s = _n();
3873
+ const s = yt();
3937
3874
  if (!s)
3938
3875
  return console.error("Failed to parse ForgeFrame payload from window.name"), null;
3939
3876
  try {
3940
- w = new Rn(
3877
+ _ = new Vn(
3941
3878
  s,
3942
3879
  t,
3943
3880
  e,
3944
3881
  n.deferInit ?? !1
3945
3882
  );
3946
3883
  } catch (r) {
3947
- if (r instanceof Error && r.message === Ge)
3884
+ if (r instanceof Error && r.message === st)
3948
3885
  return null;
3949
3886
  throw r;
3950
3887
  }
3951
- return w;
3952
- }
3953
- function xn() {
3954
- return ge();
3955
- }
3956
- function Dn() {
3957
- return ge();
3958
- }
3959
- function In() {
3960
- return window.hostProps;
3961
- }
3962
- function Sn() {
3963
- w && (w.destroy(), w = null), delete window.hostProps;
3964
- }
3965
- const K = /* @__PURE__ */ new Map(), Ze = /* @__PURE__ */ Symbol("forgeframe.component.options");
3966
- function vn(t) {
3967
- if (!t.tag)
3968
- throw new Error("Component tag is required");
3969
- if (!/^[a-z][a-z0-9-]*$/.test(t.tag))
3970
- throw new Error(
3971
- `Invalid component tag "${t.tag}". Must start with lowercase letter and contain only lowercase letters, numbers, and hyphens.`
3972
- );
3973
- if (!t.url)
3974
- throw new Error("Component url is required");
3975
- if (typeof t.url == "string")
3976
- try {
3977
- new URL(t.url, window.location.origin);
3978
- } catch {
3979
- throw new Error(
3980
- `Invalid component URL "${t.url}". Must be a valid absolute or relative URL.`
3981
- );
3982
- }
3983
- if (K.has(t.tag))
3984
- throw new Error(`Component "${t.tag}" is already registered`);
3985
- }
3986
- function Qe(t) {
3987
- vn(t);
3988
- const e = [];
3989
- let n;
3990
- if (te(t.tag)) {
3991
- const r = we(t.props, t.allowedConsumerDomains);
3992
- r && (n = r.hostProps);
3993
- }
3994
- const s = function(r = {}) {
3995
- const i = new ye(t, r);
3996
- return e.push(i), En(t.tag, i), i.event.once("destroy", () => {
3997
- const o = e.indexOf(i);
3998
- o !== -1 && e.splice(o, 1), Xe(i.uid);
3999
- }), i;
4000
- };
4001
- return s.instances = e, s.isHost = () => te(t.tag), s.isEmbedded = () => te(t.tag), s.hostProps = n, s[Ze] = t, s.canRenderTo = async (r) => r === window, K.set(t.tag, s), s;
4002
- }
4003
- function Tn(t) {
4004
- return bn(t);
4005
- }
4006
- function Un() {
4007
- return On();
4008
- }
4009
- function Nn(t) {
4010
- return t[Ze];
4011
- }
4012
- async function Fn(t) {
4013
- await t.close();
4014
- }
4015
- async function et(t) {
4016
- const e = K.get(t);
4017
- if (!e) return;
4018
- const n = [...e.instances];
4019
- await Promise.all(n.map((s) => s.close()));
4020
- }
4021
- async function Hn() {
4022
- const t = Array.from(K.keys());
4023
- await Promise.all(t.map((e) => et(e)));
4024
- }
4025
- function $n(t, e) {
4026
- const n = Object.keys(t), s = Object.keys(e);
4027
- if (n.length !== s.length)
4028
- return !1;
4029
- for (const r of n)
4030
- if (!Object.prototype.hasOwnProperty.call(e, r) || !Object.is(t[r], e[r]))
4031
- return !1;
4032
- return !0;
3888
+ return _;
4033
3889
  }
4034
- function An(t, e) {
4035
- const { React: n } = e, { createElement: s, useRef: r, useEffect: i, useState: o, forwardRef: a } = n, c = a(
4036
- function(m, h) {
4037
- const {
4038
- onRendered: E,
4039
- onError: O,
4040
- onClose: X,
4041
- context: _e,
4042
- className: Pe,
4043
- style: Ee,
4044
- ...G
4045
- } = m, Z = r(null), I = r(null), $ = r(null), be = r(E), A = r(O), Oe = r(X), [Ce, Re] = o(null);
4046
- return i(() => {
4047
- be.current = E, A.current = O, Oe.current = X;
4048
- }, [E, O, X]), i(() => {
4049
- const _ = Z.current;
4050
- if (!_) return;
4051
- Re(null);
4052
- const y = t(G);
4053
- I.current = y, $.current = G;
4054
- const L = y.event.once("rendered", () => {
4055
- be.current?.();
4056
- }), xe = y.event.once("close", () => {
4057
- Oe.current?.();
4058
- }), Q = y.event.on("error", (M) => {
4059
- A.current?.(M);
4060
- });
4061
- return y.render(_, _e).catch((M) => {
4062
- I.current === y && (Re(M), A.current?.(M));
4063
- }), () => {
4064
- y.close().catch(() => {
4065
- }), L(), xe(), Q(), I.current = null, $.current = null;
4066
- };
4067
- }, [_e]), i(() => {
4068
- const _ = I.current;
4069
- if (!_) return;
4070
- const y = G, L = $.current;
4071
- L && $n(L, y) || ($.current = y, _.updateProps(y).catch((Q) => {
4072
- I.current === _ && A.current?.(Q);
4073
- }));
4074
- }), i(() => {
4075
- const _ = Z.current;
4076
- if (typeof h == "function")
4077
- return h(_), () => {
4078
- h(null);
4079
- };
4080
- if (h && typeof h == "object")
4081
- return h.current = _, () => {
4082
- h.current = null;
4083
- };
4084
- }, [h]), Ce ? s(
4085
- "div",
4086
- {
4087
- className: Pe,
4088
- style: { color: "red", padding: "16px", ...Ee }
4089
- },
4090
- `Error: ${Ce.message}`
4091
- ) : s("div", {
4092
- ref: Z,
4093
- className: Pe,
4094
- style: {
4095
- display: "inline-block",
4096
- ...Ee
4097
- }
4098
- });
4099
- }
4100
- ), l = `ForgeFrame(${t.name || "Component"})`;
4101
- return c.displayName = l, c;
3890
+ function Yn() {
3891
+ _ && (_.destroy(), _ = null), delete window.hostProps;
4102
3892
  }
4103
- function Ln(t) {
4104
- return function(n) {
4105
- return An(n, { React: t });
4106
- };
3893
+ function Jn() {
3894
+ ce() && Ee(void 0, void 0, { deferInit: !0 });
4107
3895
  }
4108
- we(void 0, void 0, { deferInit: !0 });
4109
- const Mn = {
3896
+ const Xn = {
4110
3897
  /**
4111
3898
  * Create a new component definition.
4112
3899
  *
@@ -4131,23 +3918,23 @@ const Mn = {
4131
3918
  * await instance.render('#container');
4132
3919
  * ```
4133
3920
  */
4134
- create: Qe,
3921
+ create: tt,
4135
3922
  /**
4136
3923
  * Destroy a single component instance.
4137
3924
  *
4138
3925
  * @param instance - The component instance to destroy
4139
3926
  */
4140
- destroy: Fn,
3927
+ destroy: Nn,
4141
3928
  /**
4142
3929
  * Destroy all instances of a specific component by tag.
4143
3930
  *
4144
3931
  * @param tag - The component tag name
4145
3932
  */
4146
- destroyByTag: et,
3933
+ destroyByTag: nt,
4147
3934
  /**
4148
3935
  * Destroy all ForgeFrame component instances.
4149
3936
  */
4150
- destroyAll: Hn,
3937
+ destroyAll: An,
4151
3938
  /**
4152
3939
  * Check if the current window is a host component context.
4153
3940
  *
@@ -4166,7 +3953,7 @@ const Mn = {
4166
3953
  *
4167
3954
  * @returns True if running inside a ForgeFrame iframe/popup
4168
3955
  */
4169
- isEmbedded: Dn,
3956
+ isEmbedded: In,
4170
3957
  /**
4171
3958
  * Get hostProps from the current host window.
4172
3959
  *
@@ -4175,7 +3962,7 @@ const Mn = {
4175
3962
  *
4176
3963
  * @returns The hostProps object if in host context, undefined otherwise
4177
3964
  */
4178
- getHostProps: In,
3965
+ getHostProps: vn,
4179
3966
  /**
4180
3967
  * Flush host initialization in embedded contexts.
4181
3968
  *
@@ -4186,12 +3973,12 @@ const Mn = {
4186
3973
  *
4187
3974
  * @returns The host component instance if running embedded, otherwise null
4188
3975
  */
4189
- initHost: we,
3976
+ initHost: Ee,
4190
3977
  /**
4191
3978
  * Serialization strategy constants.
4192
3979
  * @see {@link PROP_SERIALIZATION}
4193
3980
  */
4194
- PROP_SERIALIZATION: z,
3981
+ PROP_SERIALIZATION: k,
4195
3982
  /**
4196
3983
  * Rendering context constants (IFRAME, POPUP).
4197
3984
  * @see {@link CONTEXT}
@@ -4205,11 +3992,11 @@ const Mn = {
4205
3992
  /**
4206
3993
  * Error thrown when popup window fails to open.
4207
3994
  */
4208
- PopupOpenError: Je,
3995
+ PopupOpenError: Xe,
4209
3996
  /**
4210
3997
  * Current library version.
4211
3998
  */
4212
- VERSION: ae,
3999
+ VERSION: ue,
4213
4000
  /**
4214
4001
  * Check if a value is a Standard Schema (Zod, Valibot, ArkType, etc.)
4215
4002
  *
@@ -4226,7 +4013,7 @@ const Mn = {
4226
4013
  * }
4227
4014
  * ```
4228
4015
  */
4229
- isStandardSchema: D,
4016
+ isStandardSchema: x,
4230
4017
  /**
4231
4018
  * Prop schema builders for defining component props.
4232
4019
  *
@@ -4251,34 +4038,118 @@ const Mn = {
4251
4038
  */
4252
4039
  prop: p
4253
4040
  };
4041
+ function qn(t, e) {
4042
+ const n = Object.keys(t), s = Object.keys(e);
4043
+ if (n.length !== s.length)
4044
+ return !1;
4045
+ for (const r of n)
4046
+ if (!Object.prototype.hasOwnProperty.call(e, r) || !Object.is(t[r], e[r]))
4047
+ return !1;
4048
+ return !0;
4049
+ }
4050
+ function Kn(t, e) {
4051
+ const { React: n } = e, { createElement: s, useRef: r, useEffect: i, useState: o, forwardRef: a } = n, c = a(
4052
+ function(m, h) {
4053
+ const {
4054
+ onRendered: b,
4055
+ onError: O,
4056
+ onClose: Z,
4057
+ context: be,
4058
+ className: Ce,
4059
+ style: Oe,
4060
+ ...Q
4061
+ } = m, ee = r(null), I = r(null), A = r(null), Re = r(b), $ = r(O), De = r(Z), [Se, xe] = o(null);
4062
+ return i(() => {
4063
+ Re.current = b, $.current = O, De.current = Z;
4064
+ }, [b, O, Z]), i(() => {
4065
+ const P = ee.current;
4066
+ if (!P) return;
4067
+ xe(null);
4068
+ const y = t(Q);
4069
+ I.current = y, A.current = Q;
4070
+ const M = y.event.once("rendered", () => {
4071
+ Re.current?.();
4072
+ }), Ie = y.event.once("close", () => {
4073
+ De.current?.();
4074
+ }), te = y.event.on("error", (z) => {
4075
+ $.current?.(z);
4076
+ });
4077
+ return y.render(P, be).catch((z) => {
4078
+ I.current === y && (xe(z), $.current?.(z));
4079
+ }), () => {
4080
+ y.close().catch(() => {
4081
+ }), M(), Ie(), te(), I.current = null, A.current = null;
4082
+ };
4083
+ }, [be]), i(() => {
4084
+ const P = I.current;
4085
+ if (!P) return;
4086
+ const y = Q, M = A.current;
4087
+ M && qn(M, y) || (A.current = y, P.updateProps(y).catch((te) => {
4088
+ I.current === P && $.current?.(te);
4089
+ }));
4090
+ }), i(() => {
4091
+ const P = ee.current;
4092
+ if (typeof h == "function")
4093
+ return h(P), () => {
4094
+ h(null);
4095
+ };
4096
+ if (h && typeof h == "object")
4097
+ return h.current = P, () => {
4098
+ h.current = null;
4099
+ };
4100
+ }, [h]), Se ? s(
4101
+ "div",
4102
+ {
4103
+ className: Ce,
4104
+ style: { color: "red", padding: "16px", ...Oe }
4105
+ },
4106
+ `Error: ${Se.message}`
4107
+ ) : s("div", {
4108
+ ref: ee,
4109
+ className: Ce,
4110
+ style: {
4111
+ display: "inline-block",
4112
+ ...Oe
4113
+ }
4114
+ });
4115
+ }
4116
+ ), u = `ForgeFrame(${t.name || "Component"})`;
4117
+ return c.displayName = u, c;
4118
+ }
4119
+ function Gn(t) {
4120
+ return function(n) {
4121
+ return Kn(n, { React: t });
4122
+ };
4123
+ }
4124
+ Jn();
4254
4125
  export {
4255
- fe as AnySchema,
4126
+ we as AnySchema,
4256
4127
  V as ArraySchema,
4257
- ue as BooleanSchema,
4128
+ fe as BooleanSchema,
4258
4129
  f as CONTEXT,
4259
4130
  g as EVENT,
4260
- pe as EnumSchema,
4261
- Mn as ForgeFrame,
4262
- he as FunctionSchema,
4263
- de as LiteralSchema,
4264
- le as NumberSchema,
4131
+ ye as EnumSchema,
4132
+ Xn as ForgeFrame,
4133
+ me as FunctionSchema,
4134
+ ge as LiteralSchema,
4135
+ pe as NumberSchema,
4265
4136
  Y as ObjectSchema,
4266
- z as PROP_SERIALIZATION,
4267
- Je as PopupOpenError,
4268
- P as PropSchema,
4269
- ce as StringSchema,
4270
- ae as VERSION,
4271
- Qe as create,
4272
- An as createReactComponent,
4273
- Mn as default,
4274
- Fn as destroy,
4275
- Hn as destroyAll,
4276
- et as destroyByTag,
4277
- In as getHostProps,
4278
- we as initHost,
4279
- Dn as isEmbedded,
4137
+ k as PROP_SERIALIZATION,
4138
+ Xe as PopupOpenError,
4139
+ E as PropSchema,
4140
+ he as StringSchema,
4141
+ ue as VERSION,
4142
+ tt as create,
4143
+ Kn as createReactComponent,
4144
+ Xn as default,
4145
+ Nn as destroy,
4146
+ An as destroyAll,
4147
+ nt as destroyByTag,
4148
+ vn as getHostProps,
4149
+ Ee as initHost,
4150
+ In as isEmbedded,
4280
4151
  xn as isHost,
4281
- D as isStandardSchema,
4152
+ x as isStandardSchema,
4282
4153
  p as prop,
4283
- Ln as withReactComponent
4154
+ Gn as withReactComponent
4284
4155
  };