@trycourier/courier-js
Version:
A browser-safe API wrapper
164 lines (163 loc) • 6.2 kB
TypeScript
import { CourierClientOptions } from '../client/courier-client';
import { ServerMessage } from '../types/socket/protocol/messages';
import { Logger } from '../utils/logger';
/**
* Abstract base class for Courier WebSocket implementations.
*
* The base class handles the connection and close events, as well as retry logic.
* Application-specific logic should be implemented in the concrete classes.
*/
export declare abstract class CourierSocket {
/**
* The jitter factor for the backoff intervals.
*
* Backoff with jitter is calculated as a random value in the range:
* [BACKOFF_INTERVAL - BACKOFF_JITTER_FACTOR * BACKOFF_INTERVAL,
* BACKOFF_INTERVAL + BACKOFF_JITTER_FACTOR * BACKOFF_INTERVAL).
*/
private static readonly BACKOFF_JITTER_FACTOR;
/**
* The maximum number of retry attempts.
*/
private static readonly MAX_RETRY_ATTEMPTS;
/**
* Backoff intervals in milliseconds.
*
* Each represents an offset from the previous interval, rather than a
* absolute offset from the initial request time.
*/
private static readonly BACKOFF_INTERVALS_IN_MILLIS;
/**
* The key of the retry after time in the WebSocket close event reason.
*
* The Courier WebSocket server may send the close event reason in the following format:
*
* ```json
* {
* "Retry-After": "10" // The retry after time in seconds
* }
* ```
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/reason
*/
private static readonly RETRY_AFTER_KEY;
/** The WebSocket instance, which may be null if the connection is not established. */
private webSocket;
/** The number of connection retry attempts so far, reset after a successful connection. */
private retryAttempt;
/** The timeout ID for the current connectionretry attempt, reset when we attempt to connect. */
private retryTimeoutId;
/**
* Flag indicating the application initiated a {@link CourierSocket#close} call.
*
* An application-initiated close may look like an abnormal closure (code 1006)
* if it occurs before the connection is established. We differentiate to
* prevent retrying the connection when the socket is closed intentionally.
*/
private closeRequested;
private readonly url;
private readonly options;
constructor(options: CourierClientOptions);
/**
* Connects to the Courier WebSocket server.
*
* If the connection is already established, this is a no-op.
*
* @returns A promise that resolves when the connection is established or rejects if the connection could not be established.
*/
connect(): Promise<void>;
/**
* Closes the WebSocket connection.
*
* See {@link https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close} for more details.
*
* @param code The WebSocket close code. Defaults to {@link CLOSE_CODE_NORMAL_CLOSURE}.
* @param reason The WebSocket close reason.
*/
close(code?: number, reason?: string): void;
/**
* Sends a message to the Courier WebSocket server.
*
* @param message The message to send. The message will be serialized to a JSON string.
*/
send(message: Record<string, any>): void;
protected get userId(): string;
/** The sub-tenant ID, if specified by the user. */
protected get subTenantId(): string | undefined;
protected get logger(): Logger | undefined;
/**
* Called when the WebSocket connection is established with the Courier WebSocket server.
*
* @param event The WebSocket open event.
*/
abstract onOpen(event: Event): Promise<void>;
/**
* Called when a message is received from the Courier WebSocket server.
*
* @param data The message received.
*/
abstract onMessageReceived(data: ServerMessage): Promise<void>;
/**
* Called when the WebSocket connection is closed.
*
* @param event The WebSocket close event.
*/
abstract onClose(event: CloseEvent): Promise<void>;
/**
* Called when an error occurs on the WebSocket connection.
*
* @param event The WebSocket error event.
*/
abstract onError(event: Event): Promise<void>;
/**
* Whether the WebSocket connection is currently being established.
*/
get isConnecting(): boolean;
/**
* Whether the WebSocket connection is currently open.
*/
get isOpen(): boolean;
/**
* Constructs the WebSocket URL for the Courier WebSocket server using context
* from the {@link CourierClientOptions} passed to the constructor.
*
* @returns The WebSocket URL
*/
private getWebSocketUrl;
/**
* Parses the Retry-After time from the WebSocket close event reason,
* and returns a new {@link CourierCloseEvent} with the retry after time in seconds
* if present.
*
* The Courier WebSocket server may send the close event reason in the following format:
*
* ```json
* {
* "Retry-After": "10" // The retry after time in seconds
* }
* ```
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/reason
*
* @param closeEvent The WebSocket close event.
* @returns The WebSocket close event with the retry after time in seconds.
*/
private static parseCloseEvent;
/**
* Calculates the retry backoff time in milliseconds based on the current retry attempt.
*/
private getBackoffTimeInMillis;
/**
* Retries the connection to the Courier WebSocket server after
* either {@param suggestedBackoffTimeInMillis} or a random backoff time
* calculated using {@link getBackoffTimeInMillis}.
*
* @param suggestedBackoffTimeInMillis The suggested backoff time in milliseconds.
* @returns A promise that resolves when the connection is established or rejects if the connection could not be established.
*/
protected retryConnection(suggestedBackoffTimeInMillis?: number): Promise<void>;
/**
* Clears the retry timeout if it exists.
*/
private clearRetryTimeout;
}