async-post-message
Version:
Asynchronous postMessage protocol for typed, promise-based windows and iFrame communication
101 lines (96 loc) • 4.05 kB
text/typescript
type UidType = string;
type CallbackType = {
resolve: (data: any) => void;
reject: (error: Error) => void;
};
/**
* The request object sent from the webview to the parent.
*/
type AsyncPostMessageRequest<PromisesInterface extends Promises> = {
uid: string;
functionName: keyof PromisesInterface & string;
args: Parameters<PromisesInterface[keyof PromisesInterface & string]>;
};
/**
* The response object sent from the parent to the webview.
*/
type AsyncPostMessageResponse<PromisesInterface extends Promises> = {
uid: string;
functionName: keyof PromisesInterface & string;
response: ReturnType<PromisesInterface[keyof PromisesInterface & string]> | null;
error?: string | null;
};
/**
* Base interface for the promise signatures.
*/
interface Promises {
[functionName: string]: (...args: any[]) => any;
}
type Unsubscribe = () => void;
declare const handleWebViewRequest: <PromisesInterface extends Promises>(target: {
postMessage: typeof window.postMessage;
}, handler: (request: AsyncPostMessageRequest<PromisesInterface>) => Promise<AsyncPostMessageResponse<PromisesInterface>>) => Unsubscribe;
/**
* A class for managing async postMessage requests and their promise wrappers. Each instance
* stores a map of callbacks for each unique ID. It does not wrap the `postMessage` API. Instead,
* it allows the client to set the listener and postMessage methods on their own.
*/
declare class RequestManager<PromisesInterface extends Promises> {
/**
* Map of callbacks for each promise's unique ID.
*/
private callbacks;
constructor();
/**
* Send a strongly typed async postMessage request.
*
* @param functionName The name of the function to call
* @param args The arguments to pass to the function
* @param options Options for the request. Defaults to a timeout of 10 seconds. If `0` is passed
* as the timeout, the request will not timeout.
* @returns A promise that resolves with the return value of the function
*/
send: <FnNameType extends keyof PromisesInterface & string>(functionName: FnNameType, args: Parameters<PromisesInterface[FnNameType]>, options?: {
timeoutMs: number;
}) => Promise<ReturnType<PromisesInterface[FnNameType]>>;
/**
* Handler for postMessages to the client.
*
* @param message Message payload received by the webview.
*/
onResponse(message: AsyncPostMessageResponse<PromisesInterface>): void;
/**
* Send a strongly typed async postMessage request to the target. This should be set by the
* client.
*
* @param _message Message payload to send to the target.
*/
postMessage(_message: AsyncPostMessageRequest<PromisesInterface>): void;
}
/**
* The Singleton class defines the `getInstance` method that lets clients access
* the unique singleton instance.
*/
declare class WebViewRequester<PromisesInterface extends Promises = any> {
private static instance;
private requestManager;
/**
* The Singleton's constructor should always be private to prevent direct
* construction calls with the `new` operator.
*/
private constructor();
/**
* The static method that controls the access to the global AsyncPostMessage instance.
*
* We use a singleton so that the client does not need to worry about creating multiple
* instances of the `AsyncPostMessage` class.
*/
static getInstance: <PromisesInterface_1 extends Promises>() => WebViewRequester<PromisesInterface_1>;
/**
* Execute a strongly typed promise that is executed in the parent process.
*/
execute: <FnNameType extends keyof PromisesInterface & string>(functionName: FnNameType, args: Parameters<PromisesInterface[FnNameType]>, options?: {
timeoutMs: number;
}) => Promise<ReturnType<PromisesInterface[FnNameType]>>;
}
export { AsyncPostMessageRequest, AsyncPostMessageResponse, CallbackType, Promises, RequestManager, UidType, WebViewRequester, handleWebViewRequest };