@o3r/third-party
Version:
This module provides a bridge to communicate with third parties via an iFrame solution.
183 lines (177 loc) • 6.06 kB
TypeScript
import { Logger } from '@o3r/core';
import { Observable } from 'rxjs';
/**
* Shared interface with the A/B testing provider
*/
interface AbTestBridgeInterface<T> {
/**
* Start an AB testing experiment
*/
start(experiments: T | T[]): void;
/**
* Stop an AB testing experiment
*/
stop(experiments?: T | T[]): void;
}
/**
* Configure the A/B testing script interfaces with the application
*/
interface AbTestBridgeConfig {
/**
* Reference to communicate with the bridge from the window
* @default 'abTestBridge'
*/
bridgeName: string;
/**
* Debug logger
* @default console
*/
logger: Logger;
/**
* Event a third party can subscribe to before starting the communication with the bridge
* @default 'ab-test-ready'
*/
readyEventName: string;
}
/**
* Bridge between the application and a third party A/B testing provider.
* Exposes a start and stop methods to allow the external script to set the list of experiments to run over the
* application.
*
* Share the resulting list of experiments with the rest of the application via an observable.
*/
declare class AbTestBridge<T> implements AbTestBridgeInterface<T> {
private readonly isExperimentEqual;
/**
* Behaviour subject to control the experiments via the exposed interface
*/
private readonly experimentSubject$;
/**
* Options to configure the communication between the AB Testing bridge and third parties
*/
private readonly options;
/**
* Observable with the list of AB testing experiments currently applied
*/
experiments$: Observable<T[]>;
/**
* AbTestBridge constructor
* @param isExperimentEqual check two different experiments match to identify an experiment to start or to stop
* @param options configure the communication with the A/B testing third party provider
*/
constructor(isExperimentEqual: (value1?: T, value2?: T) => boolean, options?: Partial<AbTestBridgeConfig>);
/**
* Use configured logger to log AB testing related information
* @param args
*/
private log;
/**
* @inheritDoc
*/
start(experiments: T | T[]): void;
/**
* @inheritDoc
*/
stop(experiments?: T | T[]): void;
}
/**
* Represents messages exchanged between host and iFrame.
*/
interface IframeMessage {
/**
* String used to identify the type of action to perform.
*/
action: string;
/**
* The version of the action, to allow for backward and forward compatibility.
*/
version: string;
/**
* Payload of the message.
*/
data?: unknown;
}
interface InternalIframeMessage extends IframeMessage {
/**
* The ID associated to the channel Host <-> iFrame
*/
channelId: string;
/**
* ID used to handle messages that expect a response from the other party.
* No used for unidirectional messages.
*/
id?: string;
}
/**
* Options that can be passed to configure an IFrameBridge
*/
interface IFrameBridgeOptions {
/**
* Number of times the Host will try to handshake with the iFrame before failing.
*/
handshakeTries: number;
/**
* For a given handshake try, how long will the host wait for an answer before considering
* that the try failed.
*/
handshakeTimeout: number;
/**
* When sending a message that expects a response, how long should the Bridge wait before
* considering there will be answer.
*/
messageWithResponseTimeout: number;
}
/**
* Bridge that exposes an easy abstraction layer to communicate between a Host and an IFrame using the
* postMessage API.
*/
declare class IframeBridge {
private readonly child;
/** ID used to ensure that the Bridge only processes messages meant for this instance, since postMessage is global to the window. */
private readonly channelId;
/** Observable that emits all the messages received from the IFrame. */
private readonly internalMessages$;
/** Promise that will resolve once the handshake has been completed, undefined if it's already done. */
private readonly handshakePromise?;
/** Options to configure the behaviour of the Bridge. */
private readonly options;
/**
* Observable that emits all the messages received from the IFrame and that are
* not a direct response to a request.
*/
readonly messages$: Observable<InternalIframeMessage>;
constructor(parent: Window, child: HTMLIFrameElement, options?: Partial<IFrameBridgeOptions>);
private handshake;
private _sendMessage;
private _sendMessageAndWaitForResponse;
/**
* Method to send a message to the script run in the iframe
* @param message message object
* @param messageId message identifier
*/
sendMessage(message: IframeMessage, messageId?: string): Promise<void>;
/**
* Method to send a message to the script run in the iframe and wait for an answer
* @param message
* @param timeoutMilliseconds
*/
sendMessageAndWaitForResponse(message: IframeMessage, timeoutMilliseconds?: number): Promise<InternalIframeMessage>;
}
/**
* Default options for an IFrameBridge
*/
declare const IFRAME_BRIDGE_DEFAULT_OPTIONS: Readonly<IFrameBridgeOptions>;
/**
* Verifies if a message respects the format expected by an IFrameBridge
* @param message
*/
declare function isSupportedMessage(message: any): message is InternalIframeMessage;
/**
* Generates the html content of an iframe
* @param scriptUrl script to be executed inside the iframe
* @param additionalHeader custom html headers stringified
*/
declare function generateIFrameContent(scriptUrl: string, additionalHeader?: string): string;
export { AbTestBridge, IFRAME_BRIDGE_DEFAULT_OPTIONS, IframeBridge, generateIFrameContent, isSupportedMessage };
export type { AbTestBridgeConfig, AbTestBridgeInterface, IFrameBridgeOptions, IframeMessage, InternalIframeMessage };
//# sourceMappingURL=o3r-third-party.d.ts.map