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.
- package/dist/communication/bridge.d.ts +167 -0
- package/dist/communication/index.d.ts +12 -0
- package/dist/communication/messenger.d.ts +142 -0
- package/dist/communication/protocol.d.ts +75 -0
- package/dist/constants.d.ts +202 -0
- package/dist/core/child.d.ts +223 -0
- package/dist/core/component.d.ts +135 -0
- package/dist/core/index.d.ts +12 -0
- package/dist/core/parent.d.ts +262 -0
- package/dist/drivers/index.d.ts +18 -0
- package/dist/drivers/react.d.ts +225 -0
- package/dist/events/emitter.d.ts +150 -0
- package/dist/forgeframe.js +2419 -0
- package/dist/index.d.ts +169 -0
- package/dist/props/definitions.d.ts +72 -0
- package/dist/props/index.d.ts +11 -0
- package/dist/props/normalize.d.ts +59 -0
- package/dist/props/serialize.d.ts +60 -0
- package/dist/render/iframe.d.ts +213 -0
- package/dist/render/index.d.ts +38 -0
- package/dist/render/popup.d.ts +215 -0
- package/dist/render/templates.d.ts +202 -0
- package/dist/types.d.ts +906 -0
- package/dist/utils/cleanup.d.ts +122 -0
- package/dist/utils/dimension.d.ts +50 -0
- package/dist/utils/index.d.ts +37 -0
- package/dist/utils/promise.d.ts +155 -0
- package/dist/utils/uid.d.ts +60 -0
- package/dist/window/helpers.d.ts +316 -0
- package/dist/window/index.d.ts +13 -0
- package/dist/window/name-payload.d.ts +188 -0
- package/dist/window/proxy.d.ts +168 -0
- package/package.json +45 -0
package/dist/types.d.ts
ADDED
|
@@ -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
|
+
};
|