forgeframe 1.0.0

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.
@@ -0,0 +1,906 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Type definitions for ForgeFrame cross-domain component framework.
4
+ *
5
+ * @remarks
6
+ * This module exports all the TypeScript interfaces and types used throughout
7
+ * the ForgeFrame library. These types enable type-safe component creation,
8
+ * prop handling, and cross-domain communication.
9
+ */
10
+ import type { PropType, ContextType, SerializationType, EventType } from './constants';
11
+ /**
12
+ * Pattern for matching domains in security configurations.
13
+ *
14
+ * @remarks
15
+ * Can be a single domain string, a RegExp pattern, or an array of domain strings.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // Single domain
20
+ * const domain: DomainMatcher = 'https://example.com';
21
+ *
22
+ * // RegExp pattern
23
+ * const pattern: DomainMatcher = /^https:\/\/.*\.example\.com$/;
24
+ *
25
+ * // Multiple domains
26
+ * const domains: DomainMatcher = ['https://a.com', 'https://b.com'];
27
+ * ```
28
+ *
29
+ * @public
30
+ */
31
+ export type DomainMatcher = string | RegExp | string[];
32
+ /**
33
+ * Component dimension specification.
34
+ *
35
+ * @remarks
36
+ * Dimensions can be specified as CSS values (strings) or pixel numbers.
37
+ *
38
+ * @public
39
+ */
40
+ export interface Dimensions {
41
+ /** Width of the component (e.g., '100%', 400, '500px') */
42
+ width?: string | number;
43
+ /** Height of the component (e.g., '100%', 300, '400px') */
44
+ height?: string | number;
45
+ }
46
+ /**
47
+ * Configuration for automatic component resizing.
48
+ *
49
+ * @remarks
50
+ * When enabled, the parent will automatically resize the iframe
51
+ * based on the child content dimensions.
52
+ *
53
+ * @public
54
+ */
55
+ export interface AutoResizeOptions {
56
+ /** Enable automatic width resizing */
57
+ width?: boolean;
58
+ /** Enable automatic height resizing */
59
+ height?: boolean;
60
+ /** CSS selector of element to measure for auto-resize */
61
+ element?: string;
62
+ }
63
+ /**
64
+ * HTML attributes that can be applied to an iframe element.
65
+ *
66
+ * @remarks
67
+ * These attributes are passed directly to the iframe element when rendering.
68
+ *
69
+ * @public
70
+ */
71
+ export interface IframeAttributes {
72
+ /** Title attribute for accessibility */
73
+ title?: string;
74
+ /** Permissions policy (e.g., 'camera; microphone') */
75
+ allow?: string;
76
+ /** Allow fullscreen mode */
77
+ allowFullscreen?: boolean;
78
+ /** Loading strategy */
79
+ loading?: 'lazy' | 'eager';
80
+ /** Referrer policy */
81
+ referrerPolicy?: ReferrerPolicy;
82
+ /** Sandbox restrictions */
83
+ sandbox?: string;
84
+ /** Additional custom attributes */
85
+ [key: string]: string | boolean | undefined;
86
+ }
87
+ /**
88
+ * CSS styles that can be applied to the iframe element.
89
+ *
90
+ * @remarks
91
+ * These styles are applied directly to the iframe's style property.
92
+ * Common use cases include setting borders, shadows, border-radius, etc.
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * const styles: IframeStyles = {
97
+ * border: 'none',
98
+ * borderRadius: '8px',
99
+ * boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
100
+ * };
101
+ * ```
102
+ *
103
+ * @public
104
+ */
105
+ export interface IframeStyles {
106
+ /** CSS properties to apply to the iframe */
107
+ [key: string]: string | number | undefined;
108
+ }
109
+ /**
110
+ * Result of an eligibility check for component rendering.
111
+ *
112
+ * @public
113
+ */
114
+ export interface EligibilityResult {
115
+ /** Whether the component is eligible to render */
116
+ eligible: boolean;
117
+ /** Reason for ineligibility (if not eligible) */
118
+ reason?: string;
119
+ }
120
+ /**
121
+ * Context object passed to prop value functions and decorators.
122
+ *
123
+ * @typeParam P - The props type for the component
124
+ *
125
+ * @remarks
126
+ * This context provides access to component state and methods during
127
+ * prop normalization and decoration.
128
+ *
129
+ * @public
130
+ */
131
+ export interface PropContext<P> {
132
+ /** Current props values */
133
+ props: P;
134
+ /** Component state object */
135
+ state: Record<string, unknown>;
136
+ /** Close the component */
137
+ close: () => Promise<void>;
138
+ /** Focus the component */
139
+ focus: () => Promise<void>;
140
+ /** Report an error */
141
+ onError: (err: Error) => void;
142
+ /** Container element (null during prerender) */
143
+ container: HTMLElement | null;
144
+ /** Unique instance identifier */
145
+ uid: string;
146
+ /** Component tag name */
147
+ tag: string;
148
+ }
149
+ /**
150
+ * Definition for a single component prop.
151
+ *
152
+ * @typeParam T - The type of the prop value
153
+ * @typeParam P - The props type for the component
154
+ *
155
+ * @remarks
156
+ * Prop definitions control how individual props are validated, serialized,
157
+ * and passed between parent and child components.
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * const propDef: PropDefinition<string> = {
162
+ * type: PROP_TYPE.STRING,
163
+ * required: true,
164
+ * default: 'hello',
165
+ * validate: ({ value }) => {
166
+ * if (value.length > 100) throw new Error('Too long');
167
+ * },
168
+ * };
169
+ * ```
170
+ *
171
+ * @public
172
+ */
173
+ export interface PropDefinition<T = unknown, P = Record<string, unknown>> {
174
+ /** The prop type (STRING, NUMBER, FUNCTION, etc.) */
175
+ type: PropType;
176
+ /** Whether the prop is required */
177
+ required?: boolean;
178
+ /** Default value or function returning default value */
179
+ default?: T | ((ctx: PropContext<P>) => T);
180
+ /** Function to compute the prop value */
181
+ value?: (ctx: PropContext<P>) => T;
182
+ /** Whether to send this prop to the child window (default: true) */
183
+ sendToChild?: boolean;
184
+ /** Only send if parent and child are same domain */
185
+ sameDomain?: boolean;
186
+ /** List of trusted domains that can receive this prop */
187
+ trustedDomains?: DomainMatcher[];
188
+ /** Serialization strategy for cross-domain transfer */
189
+ serialization?: SerializationType;
190
+ /** Pass prop via URL query parameter */
191
+ queryParam?: boolean | string | ((opts: {
192
+ value: T;
193
+ }) => string);
194
+ /** Pass prop via POST body parameter */
195
+ bodyParam?: boolean | string | ((opts: {
196
+ value: T;
197
+ }) => string);
198
+ /** Validate the prop value (throw to reject) */
199
+ validate?: (opts: {
200
+ value: T;
201
+ props: P;
202
+ }) => void;
203
+ /** Transform the prop value in parent context */
204
+ decorate?: (opts: {
205
+ value: T;
206
+ props: P;
207
+ }) => T;
208
+ /** Transform the prop value in child context */
209
+ childDecorate?: (opts: {
210
+ value: T;
211
+ props: P;
212
+ }) => T;
213
+ /** Alternative name for the prop */
214
+ alias?: string;
215
+ }
216
+ /**
217
+ * Map of prop names to their definitions.
218
+ *
219
+ * @typeParam P - The props type for the component
220
+ *
221
+ * @public
222
+ */
223
+ export type PropsDefinition<P> = {
224
+ [K in keyof P]?: PropDefinition<P[K], P>;
225
+ };
226
+ /**
227
+ * Context object passed to container and prerender template functions.
228
+ *
229
+ * @typeParam P - The props type for the component
230
+ *
231
+ * @public
232
+ */
233
+ export interface TemplateContext<P = Record<string, unknown>> {
234
+ /** Unique instance identifier */
235
+ uid: string;
236
+ /** Component tag name */
237
+ tag: string;
238
+ /** Rendering context (iframe or popup) */
239
+ context: ContextType;
240
+ /** Component dimensions */
241
+ dimensions: Dimensions;
242
+ /** Current props */
243
+ props: P;
244
+ /** Document object for creating elements */
245
+ doc: Document;
246
+ /** Container element */
247
+ container: HTMLElement;
248
+ /** The iframe element (null for popup context) */
249
+ frame: HTMLIFrameElement | null;
250
+ /** The prerender/loading element (from prerenderTemplate) */
251
+ prerenderFrame: HTMLElement | null;
252
+ /** Close the component */
253
+ close: () => Promise<void>;
254
+ /** Focus the component */
255
+ focus: () => Promise<void>;
256
+ }
257
+ /**
258
+ * Function that creates a custom container element for the component.
259
+ *
260
+ * @typeParam P - The props type for the component
261
+ *
262
+ * @param ctx - Template context with component info
263
+ * @returns The container element or null to use default
264
+ *
265
+ * @public
266
+ */
267
+ export type ContainerTemplate<P = Record<string, unknown>> = (ctx: TemplateContext<P>) => HTMLElement | null;
268
+ /**
269
+ * Function that creates a custom prerender (loading) element.
270
+ *
271
+ * @typeParam P - The props type for the component
272
+ *
273
+ * @param ctx - Template context with component info
274
+ * @returns The prerender element or null for no prerender
275
+ *
276
+ * @public
277
+ */
278
+ export type PrerenderTemplate<P = Record<string, unknown>> = (ctx: TemplateContext<P>) => HTMLElement | null;
279
+ /**
280
+ * Function that returns child components for nested composition.
281
+ *
282
+ * @typeParam P - The props type for the parent component
283
+ *
284
+ * @remarks
285
+ * Child components can be rendered within the parent component's iframe/popup.
286
+ *
287
+ * @param props - Object containing the parent's props
288
+ * @returns Map of child component names to ForgeFrameComponent instances
289
+ *
290
+ * @public
291
+ */
292
+ export type ChildrenDefinition<P = Record<string, unknown>> = (props: {
293
+ props: P;
294
+ }) => Record<string, ForgeFrameComponent>;
295
+ /**
296
+ * Serializable reference to a child component for cross-domain transfer.
297
+ *
298
+ * @internal
299
+ */
300
+ export interface ChildComponentRef {
301
+ /** Component tag name */
302
+ tag: string;
303
+ /** Component URL (or stringified function) */
304
+ url: string | ((props: Record<string, unknown>) => string);
305
+ /** Prop definitions */
306
+ props?: PropsDefinition<Record<string, unknown>>;
307
+ /** Default dimensions */
308
+ dimensions?: Dimensions;
309
+ /** Default rendering context */
310
+ defaultContext?: ContextType;
311
+ }
312
+ /**
313
+ * Configuration options for creating a component.
314
+ *
315
+ * @typeParam P - The props type for the component
316
+ *
317
+ * @remarks
318
+ * These options are passed to `ForgeFrame.create()` to define a new component.
319
+ *
320
+ * @example
321
+ * ```typescript
322
+ * const options: ComponentOptions<MyProps> = {
323
+ * tag: 'my-component',
324
+ * url: 'https://example.com/component',
325
+ * props: {
326
+ * name: { type: PROP_TYPE.STRING, required: true },
327
+ * },
328
+ * dimensions: { width: 400, height: 300 },
329
+ * };
330
+ * ```
331
+ *
332
+ * @public
333
+ */
334
+ export interface ComponentOptions<P = Record<string, unknown>> {
335
+ /**
336
+ * Unique tag name for the component.
337
+ *
338
+ * @remarks
339
+ * Must start with a lowercase letter and contain only lowercase letters,
340
+ * numbers, and hyphens.
341
+ */
342
+ tag: string;
343
+ /**
344
+ * URL of the child component page, or function that returns URL based on props.
345
+ */
346
+ url: string | ((props: P) => string);
347
+ /**
348
+ * Prop definitions for type checking and serialization.
349
+ */
350
+ props?: PropsDefinition<P>;
351
+ /**
352
+ * Default dimensions for the component.
353
+ */
354
+ dimensions?: Dimensions | ((props: P) => Dimensions);
355
+ /**
356
+ * Configuration for automatic resizing based on content.
357
+ */
358
+ autoResize?: AutoResizeOptions;
359
+ /**
360
+ * Default rendering context (iframe or popup).
361
+ * @defaultValue 'iframe'
362
+ */
363
+ defaultContext?: ContextType;
364
+ /**
365
+ * Allowed child domains for security validation.
366
+ */
367
+ domain?: DomainMatcher;
368
+ /**
369
+ * Restrict which parent domains can embed this component.
370
+ */
371
+ allowedParentDomains?: DomainMatcher;
372
+ /**
373
+ * Custom container template function.
374
+ */
375
+ containerTemplate?: ContainerTemplate<P>;
376
+ /**
377
+ * Custom prerender (loading state) template function.
378
+ */
379
+ prerenderTemplate?: PrerenderTemplate<P>;
380
+ /**
381
+ * Function to check if component is eligible to render.
382
+ */
383
+ eligible?: (opts: {
384
+ props: P;
385
+ }) => EligibilityResult;
386
+ /**
387
+ * Function to validate props before rendering.
388
+ */
389
+ validate?: (opts: {
390
+ props: P;
391
+ }) => void;
392
+ /**
393
+ * Additional HTML attributes for the iframe/popup.
394
+ */
395
+ attributes?: IframeAttributes | ((props: P) => IframeAttributes);
396
+ /**
397
+ * CSS styles to apply to the iframe element.
398
+ *
399
+ * @example
400
+ * ```typescript
401
+ * style: {
402
+ * border: 'none',
403
+ * borderRadius: '8px',
404
+ * boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
405
+ * }
406
+ * ```
407
+ */
408
+ style?: IframeStyles | ((props: P) => IframeStyles);
409
+ /**
410
+ * Timeout in milliseconds for child initialization.
411
+ * @defaultValue 10000
412
+ */
413
+ timeout?: number;
414
+ /**
415
+ * Child components that can be rendered within this component.
416
+ */
417
+ children?: ChildrenDefinition<P>;
418
+ }
419
+ /**
420
+ * Handler function for component events.
421
+ *
422
+ * @typeParam T - The type of data passed to the handler
423
+ *
424
+ * @public
425
+ */
426
+ export type EventHandler<T = unknown> = (data: T) => void | Promise<void>;
427
+ /**
428
+ * Event emitter interface for component lifecycle events.
429
+ *
430
+ * @public
431
+ */
432
+ export interface EventEmitterInterface {
433
+ /**
434
+ * Subscribe to an event.
435
+ *
436
+ * @param event - Event name to listen for
437
+ * @param handler - Handler function to call
438
+ * @returns Unsubscribe function
439
+ */
440
+ on<T = unknown>(event: EventType | string, handler: EventHandler<T>): () => void;
441
+ /**
442
+ * Subscribe to an event for a single emission.
443
+ *
444
+ * @param event - Event name to listen for
445
+ * @param handler - Handler function to call
446
+ * @returns Unsubscribe function
447
+ */
448
+ once<T = unknown>(event: EventType | string, handler: EventHandler<T>): () => void;
449
+ /**
450
+ * Emit an event with optional data.
451
+ *
452
+ * @param event - Event name to emit
453
+ * @param data - Data to pass to handlers
454
+ */
455
+ emit<T = unknown>(event: EventType | string, data?: T): void;
456
+ /**
457
+ * Unsubscribe a handler from an event.
458
+ *
459
+ * @param event - Event name
460
+ * @param handler - Handler to remove (optional, removes all if not provided)
461
+ */
462
+ off(event: EventType | string, handler?: EventHandler): void;
463
+ /**
464
+ * Remove all event listeners.
465
+ */
466
+ removeAllListeners(): void;
467
+ }
468
+ /**
469
+ * Instance of a rendered component.
470
+ *
471
+ * @typeParam P - The props type for the component
472
+ * @typeParam X - The type of exports from the child
473
+ *
474
+ * @remarks
475
+ * Component instances are created by calling the component factory function
476
+ * and provide methods to control the rendered component.
477
+ *
478
+ * @example
479
+ * ```typescript
480
+ * const instance = MyComponent({ name: 'World' });
481
+ * await instance.render('#container');
482
+ * await instance.updateProps({ name: 'Updated' });
483
+ * await instance.close();
484
+ * ```
485
+ *
486
+ * @public
487
+ */
488
+ export interface ForgeFrameComponentInstance<P = Record<string, unknown>, X = unknown> {
489
+ /**
490
+ * Unique instance identifier.
491
+ */
492
+ readonly uid: string;
493
+ /**
494
+ * Render the component into a container.
495
+ *
496
+ * @param container - CSS selector or element to render into
497
+ * @param context - Override the default context (iframe/popup)
498
+ * @returns Promise that resolves when rendering is complete
499
+ */
500
+ render(container?: string | HTMLElement, context?: ContextType): Promise<void>;
501
+ /**
502
+ * Render into a different window's container.
503
+ *
504
+ * @param win - Target window
505
+ * @param container - CSS selector or element in target window
506
+ * @param context - Override the default context
507
+ * @returns Promise that resolves when rendering is complete
508
+ */
509
+ renderTo(win: Window, container?: string | HTMLElement, context?: ContextType): Promise<void>;
510
+ /**
511
+ * Close and destroy the component.
512
+ *
513
+ * @returns Promise that resolves when closed
514
+ */
515
+ close(): Promise<void>;
516
+ /**
517
+ * Focus the component window.
518
+ *
519
+ * @returns Promise that resolves when focused
520
+ */
521
+ focus(): Promise<void>;
522
+ /**
523
+ * Resize the component to new dimensions.
524
+ *
525
+ * @param dimensions - New dimensions
526
+ * @returns Promise that resolves when resized
527
+ */
528
+ resize(dimensions: Dimensions): Promise<void>;
529
+ /**
530
+ * Show the component (if hidden).
531
+ *
532
+ * @returns Promise that resolves when shown
533
+ */
534
+ show(): Promise<void>;
535
+ /**
536
+ * Hide the component.
537
+ *
538
+ * @returns Promise that resolves when hidden
539
+ */
540
+ hide(): Promise<void>;
541
+ /**
542
+ * Update the component's props.
543
+ *
544
+ * @param props - Partial props to merge with existing
545
+ * @returns Promise that resolves when props are updated
546
+ */
547
+ updateProps(props: Partial<P>): Promise<void>;
548
+ /**
549
+ * Create a copy of this instance with the same props.
550
+ *
551
+ * @returns New component instance
552
+ */
553
+ clone(): ForgeFrameComponentInstance<P, X>;
554
+ /**
555
+ * Check if the component is eligible to render.
556
+ *
557
+ * @returns Whether the component can render
558
+ */
559
+ isEligible(): boolean;
560
+ /**
561
+ * Event emitter for subscribing to lifecycle events.
562
+ */
563
+ event: EventEmitterInterface;
564
+ /**
565
+ * Mutable state object for the component.
566
+ */
567
+ state: Record<string, unknown>;
568
+ /**
569
+ * Data exported from the child component via `xprops.export()`.
570
+ */
571
+ exports?: X;
572
+ }
573
+ /**
574
+ * Component factory function and static properties.
575
+ *
576
+ * @typeParam P - The props type for the component
577
+ * @typeParam X - The type of exports from the child
578
+ *
579
+ * @remarks
580
+ * This is the return type of `ForgeFrame.create()`. It can be called as a
581
+ * function to create instances, and has static properties for child detection.
582
+ *
583
+ * @example
584
+ * ```typescript
585
+ * const MyComponent = ForgeFrame.create<MyProps>({ ... });
586
+ *
587
+ * // Create an instance
588
+ * const instance = MyComponent({ name: 'World' });
589
+ *
590
+ * // Check if we're in a child context
591
+ * if (MyComponent.isChild()) {
592
+ * const props = MyComponent.xprops;
593
+ * }
594
+ * ```
595
+ *
596
+ * @public
597
+ */
598
+ export interface ForgeFrameComponent<P = Record<string, unknown>, X = unknown> {
599
+ /**
600
+ * Create a new component instance with props.
601
+ *
602
+ * @param props - Props to pass to the component
603
+ * @returns New component instance
604
+ */
605
+ (props?: P): ForgeFrameComponentInstance<P, X>;
606
+ /**
607
+ * Check if current window is a child instance of this component.
608
+ *
609
+ * @returns True if in child context
610
+ */
611
+ isChild(): boolean;
612
+ /**
613
+ * Get xprops if in child context.
614
+ *
615
+ * @remarks
616
+ * Only available when `isChild()` returns true.
617
+ */
618
+ xprops?: ChildProps<P>;
619
+ /**
620
+ * Check if we can render to a target window.
621
+ *
622
+ * @param win - Target window to check
623
+ * @returns Promise resolving to whether rendering is allowed
624
+ */
625
+ canRenderTo(win: Window): Promise<boolean>;
626
+ /**
627
+ * All active instances of this component.
628
+ */
629
+ instances: ForgeFrameComponentInstance<P, X>[];
630
+ }
631
+ /**
632
+ * Parent namespace available in child via `xprops.parent`.
633
+ *
634
+ * @typeParam P - The props type for the component
635
+ *
636
+ * @remarks
637
+ * Provides bidirectional communication from child to parent.
638
+ *
639
+ * @public
640
+ */
641
+ export interface ParentNamespace<P = Record<string, unknown>> {
642
+ /**
643
+ * Access parent's props.
644
+ */
645
+ props: P;
646
+ /**
647
+ * Export data/methods from parent context.
648
+ *
649
+ * @param data - Data to export
650
+ * @returns Promise that resolves when export is complete
651
+ */
652
+ export: <T>(data: T) => Promise<void>;
653
+ }
654
+ /**
655
+ * Information about a sibling component instance.
656
+ *
657
+ * @public
658
+ */
659
+ export interface SiblingInfo {
660
+ /** Unique instance ID */
661
+ uid: string;
662
+ /** Component tag name */
663
+ tag: string;
664
+ /** Exports from sibling (if any) */
665
+ exports?: unknown;
666
+ }
667
+ /**
668
+ * Options for getting sibling components.
669
+ *
670
+ * @public
671
+ */
672
+ export interface GetSiblingsOptions {
673
+ /**
674
+ * If true, get siblings from any parent window (not just same parent).
675
+ * @defaultValue false
676
+ */
677
+ anyParent?: boolean;
678
+ }
679
+ /**
680
+ * Props object available in child window via `window.xprops`.
681
+ *
682
+ * @typeParam P - The props type for the component
683
+ *
684
+ * @remarks
685
+ * The xprops object contains all props passed from the parent, plus
686
+ * built-in methods for controlling the component and communicating
687
+ * with the parent.
688
+ *
689
+ * @example
690
+ * ```typescript
691
+ * // In child window
692
+ * const { name, onSubmit, close, resize } = window.xprops;
693
+ *
694
+ * // Use passed props
695
+ * console.log(name);
696
+ *
697
+ * // Call parent callbacks
698
+ * await onSubmit({ success: true });
699
+ *
700
+ * // Control the frame
701
+ * await resize({ width: 500, height: 400 });
702
+ * await close();
703
+ * ```
704
+ *
705
+ * @public
706
+ */
707
+ export interface ChildProps<P = Record<string, unknown>> {
708
+ /** User-defined props passed from parent */
709
+ [K: string]: unknown;
710
+ /** Unique instance ID */
711
+ uid: string;
712
+ /** Component tag name */
713
+ tag: string;
714
+ /**
715
+ * Close the component.
716
+ *
717
+ * @returns Promise that resolves when closed
718
+ */
719
+ close: () => Promise<void>;
720
+ /**
721
+ * Focus the component window.
722
+ *
723
+ * @returns Promise that resolves when focused
724
+ */
725
+ focus: () => Promise<void>;
726
+ /**
727
+ * Resize the component.
728
+ *
729
+ * @param dimensions - New dimensions
730
+ * @returns Promise that resolves when resized
731
+ */
732
+ resize: (dimensions: Dimensions) => Promise<void>;
733
+ /**
734
+ * Show the component (if hidden).
735
+ *
736
+ * @returns Promise that resolves when shown
737
+ */
738
+ show: () => Promise<void>;
739
+ /**
740
+ * Hide the component.
741
+ *
742
+ * @returns Promise that resolves when hidden
743
+ */
744
+ hide: () => Promise<void>;
745
+ /**
746
+ * Subscribe to prop updates from parent.
747
+ *
748
+ * @param handler - Function called when props change
749
+ * @returns Object with cancel function to unsubscribe
750
+ */
751
+ onProps: (handler: (props: P) => void) => {
752
+ cancel: () => void;
753
+ };
754
+ /**
755
+ * Report an error to the parent.
756
+ *
757
+ * @param err - Error to report
758
+ * @returns Promise that resolves when error is sent
759
+ */
760
+ onError: (err: Error) => Promise<void>;
761
+ /**
762
+ * Get a reference to the parent window.
763
+ *
764
+ * @returns Parent window object
765
+ */
766
+ getParent: () => Window;
767
+ /**
768
+ * Get the parent window's domain.
769
+ *
770
+ * @returns Parent domain string
771
+ */
772
+ getParentDomain: () => string;
773
+ /**
774
+ * Export data/methods to the parent.
775
+ *
776
+ * @param exports - Data to export
777
+ * @returns Promise that resolves when export is complete
778
+ */
779
+ export: <X>(exports: X) => Promise<void>;
780
+ /**
781
+ * Parent namespace for bidirectional communication.
782
+ */
783
+ parent: ParentNamespace<P>;
784
+ /**
785
+ * Get sibling component instances.
786
+ *
787
+ * @param options - Options for sibling discovery
788
+ * @returns Promise resolving to array of sibling info
789
+ */
790
+ getSiblings: (options?: GetSiblingsOptions) => Promise<SiblingInfo[]>;
791
+ /**
792
+ * Child components available for nested rendering.
793
+ */
794
+ children?: Record<string, ForgeFrameComponent>;
795
+ }
796
+ /**
797
+ * Payload encoded in window.name for initial parent-to-child data transfer.
798
+ *
799
+ * @typeParam _P - The props type (unused, for compatibility)
800
+ *
801
+ * @internal
802
+ */
803
+ export interface WindowNamePayload<_P = Record<string, unknown>> {
804
+ /** Parent component instance UID */
805
+ uid: string;
806
+ /** Component tag name */
807
+ tag: string;
808
+ /** ForgeFrame version */
809
+ version: string;
810
+ /** Rendering context */
811
+ context: ContextType;
812
+ /** Parent window domain */
813
+ parentDomain: string;
814
+ /** Serialized props */
815
+ props: SerializedProps;
816
+ /** Parent method message names */
817
+ exports: ParentExports;
818
+ /** Child component references */
819
+ children?: Record<string, ChildComponentRef>;
820
+ }
821
+ /**
822
+ * Serialized props ready for cross-domain transfer.
823
+ *
824
+ * @internal
825
+ */
826
+ export interface SerializedProps {
827
+ [key: string]: unknown;
828
+ }
829
+ /**
830
+ * Map of parent methods to their message names.
831
+ *
832
+ * @internal
833
+ */
834
+ export interface ParentExports {
835
+ /** Init message name */
836
+ init: string;
837
+ /** Close message name */
838
+ close: string;
839
+ /** Resize message name */
840
+ resize: string;
841
+ /** Show message name */
842
+ show: string;
843
+ /** Hide message name */
844
+ hide: string;
845
+ /** Error message name */
846
+ onError: string;
847
+ /** Update props message name */
848
+ updateProps: string;
849
+ /** Export message name */
850
+ export: string;
851
+ }
852
+ /**
853
+ * Serialized function reference for cross-domain calls.
854
+ *
855
+ * @internal
856
+ */
857
+ export interface FunctionRef {
858
+ /** Type marker */
859
+ __type__: 'function';
860
+ /** Unique function ID */
861
+ __id__: string;
862
+ /** Function name for debugging */
863
+ __name__: string;
864
+ }
865
+ /**
866
+ * Cross-domain message structure.
867
+ *
868
+ * @internal
869
+ */
870
+ export interface Message {
871
+ /** Unique message ID */
872
+ id: string;
873
+ /** Message type */
874
+ type: 'request' | 'response' | 'ack';
875
+ /** Message name/action */
876
+ name: string;
877
+ /** Message payload */
878
+ data?: unknown;
879
+ /** Error information (for error responses) */
880
+ error?: {
881
+ message: string;
882
+ stack?: string;
883
+ };
884
+ /** Message source info */
885
+ source: {
886
+ uid: string;
887
+ domain: string;
888
+ };
889
+ }
890
+ /**
891
+ * Reference to a window for cross-domain communication.
892
+ *
893
+ * @internal
894
+ */
895
+ export type WindowRef = {
896
+ type: 'opener';
897
+ } | {
898
+ type: 'parent';
899
+ distance: number;
900
+ } | {
901
+ type: 'global';
902
+ uid: string;
903
+ } | {
904
+ type: 'direct';
905
+ win: Window;
906
+ };