iframe-bridge-sdk
Version:
Universal iframe communication SDK - unified package for host and guest applications
278 lines • 8.22 kB
JavaScript
// ==================== 基础消息类型 ====================
/**
* 预定义错误代码
*/
export var ErrorCode;
(function (ErrorCode) {
/** 请求超时 */
ErrorCode["TIMEOUT"] = "TIMEOUT";
/** 无效消息格式 */
ErrorCode["INVALID_MESSAGE"] = "INVALID_MESSAGE";
/** 未找到处理器 */
ErrorCode["NO_HANDLER"] = "NO_HANDLER";
/** 初始化失败 */
ErrorCode["INIT_FAILED"] = "INIT_FAILED";
/** 连接丢失 */
ErrorCode["CONNECTION_LOST"] = "CONNECTION_LOST";
})(ErrorCode || (ErrorCode = {}));
/**
* SDK状态
*/
export var SDKState;
(function (SDKState) {
/** 未初始化 */
SDKState["IDLE"] = "idle";
/** 初始化中 */
SDKState["INITIALIZING"] = "initializing";
/** 已就绪 */
SDKState["READY"] = "ready";
/** 已销毁 */
SDKState["DESTROYED"] = "destroyed";
})(SDKState || (SDKState = {}));
// ==================== 基础消息处理类 ====================
/**
* 基础消息处理类
* 提供事件发送、请求-响应、监听器管理等功能
*/
export class BaseMessenger {
constructor() {
// ==================== 私有属性 ====================
/** 事件监听器映射 */
this.eventListeners = new Map();
/** 请求处理器映射 */
this.requestHandlers = new Map();
/** 待处理的请求映射 */
this.pendingRequests = new Map();
/** 当前状态 */
this.state = SDKState.IDLE;
/** 请求超时时间(毫秒) */
this.timeout = 10000;
}
// ==================== 公共方法 ====================
/**
* 发送事件
* @param event 事件名称
* @param data 事件数据
*/
emit(event, data) {
const message = {
event,
data,
timestamp: Date.now(),
};
this.sendMessage(message);
}
/**
* 发送请求并等待响应
* @param event 请求事件名称
* @param data 请求数据
* @returns Promise<any> 响应数据
*/
request(event, data) {
const id = this.generateId();
const message = {
event,
data,
id,
timestamp: Date.now(),
};
return new Promise((resolve, reject) => {
// 设置超时
const timeoutId = setTimeout(() => {
this.pendingRequests.delete(id);
reject(new Error(`Request timeout: ${event}`));
}, this.timeout);
// 存储待处理的请求
this.pendingRequests.set(id, {
resolve: (result) => {
clearTimeout(timeoutId);
resolve(result);
},
reject: (error) => {
clearTimeout(timeoutId);
reject(error);
},
timestamp: Date.now(),
});
// 发送消息
this.sendMessage(message);
});
}
/**
* 监听事件
* @param event 事件名称
* @param callback 回调函数
*/
on(event, callback) {
if (!this.eventListeners.has(event)) {
this.eventListeners.set(event, new Set());
}
this.eventListeners.get(event).add(callback);
}
/**
* 移除事件监听
* @param event 事件名称
* @param callback 回调函数(可选,不传则移除所有监听器)
*/
off(event, callback) {
const listeners = this.eventListeners.get(event);
if (!listeners)
return;
if (callback) {
listeners.delete(callback);
if (listeners.size === 0) {
this.eventListeners.delete(event);
}
}
else {
this.eventListeners.delete(event);
}
}
/**
* 处理请求
* @param event 请求事件名称
* @param handler 处理函数
*/
onRequest(event, handler) {
this.requestHandlers.set(event, handler);
}
/**
* 移除请求处理器
* @param event 请求事件名称
*/
offRequest(event) {
this.requestHandlers.delete(event);
}
/**
* 设置请求超时时间
* @param timeout 超时时间(毫秒)
*/
setTimeout(timeout) {
this.timeout = timeout;
}
/**
* 获取当前状态
*/
getState() {
return this.state;
}
/**
* 设置状态
* @param state 新状态
*/
setState(state) {
this.state = state;
}
/**
* 销毁实例
*/
destroy() {
if (this.state === SDKState.DESTROYED) {
return;
}
// 清理所有监听器
this.eventListeners.clear();
this.requestHandlers.clear();
// 拒绝所有待处理的请求
this.pendingRequests.forEach((request) => {
request.reject(new Error('SDK destroyed'));
});
this.pendingRequests.clear();
// 清理定时器
if (this.cleanupTimer) {
clearTimeout(this.cleanupTimer);
}
this.setState(SDKState.DESTROYED);
}
/**
* 处理接收到的消息
* @param message 接收到的消息
*/
handleIncomingMessage(message) {
// 验证消息格式
if (!this.isValidMessage(message)) {
console.warn('Invalid message format:', message);
return;
}
const { event, data, id } = message;
// 处理响应消息
if (id && this.pendingRequests.has(id)) {
const request = this.pendingRequests.get(id);
this.pendingRequests.delete(id);
request.resolve(data);
return;
}
// 处理请求消息
if (this.requestHandlers.has(event)) {
const handler = this.requestHandlers.get(event);
try {
handler(data, (result) => {
this.sendMessage({
event: `${event}_response`,
data: result,
id,
timestamp: Date.now(),
});
});
}
catch (error) {
this.sendMessage({
event: `${event}_response`,
data: { error: error instanceof Error ? error.message : 'Unknown error' },
id,
timestamp: Date.now(),
});
}
return;
}
// 触发事件监听器
const listeners = this.eventListeners.get(event);
if (listeners) {
listeners.forEach((callback) => {
try {
callback(data);
}
catch (error) {
console.error(`Error in event listener for ${event}:`, error);
}
});
}
}
// ==================== 私有方法 ====================
/**
* 生成唯一ID
*/
generateId() {
return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
/**
* 验证消息格式
* @param message 消息对象
*/
isValidMessage(message) {
return (message &&
typeof message === 'object' &&
typeof message.event === 'string' &&
(message.data === undefined || message.data !== undefined) &&
(message.id === undefined || typeof message.id === 'string') &&
(message.timestamp === undefined || typeof message.timestamp === 'number'));
}
/**
* 清理过期的请求
*/
cleanupExpiredRequests() {
const now = Date.now();
const expiredIds = [];
this.pendingRequests.forEach((request, id) => {
if (now - request.timestamp > this.timeout) {
expiredIds.push(id);
}
});
expiredIds.forEach((id) => {
const request = this.pendingRequests.get(id);
this.pendingRequests.delete(id);
request.reject(new Error('Request timeout'));
});
}
}
//# sourceMappingURL=shared.js.map