UNPKG

iframe-connect

Version:

A lightweight, type-safe cross-frame communication library with plugin system and multi-window isolation

322 lines (318 loc) 10.1 kB
var __defProp = Object.defineProperty; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __objRest = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols) for (var prop of __getOwnPropSymbols(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop]; } return target; }; // src/plugins/logger.ts var Logger = class { constructor(bridge, options = {}) { this.bridge = bridge; this.options = __spreadValues({ prefix: "[CrossFrame]", timestamp: true, colors: true, level: "debug" }, options); this.setupLogging(); } setupLogging() { const originalSend = this.bridge.send.bind(this.bridge); this.bridge.send = (type, payload) => { this.log("info", "\u53D1\u9001\u6D88\u606F:", { type, payload }); return originalSend(type, payload); }; const originalRequest = this.bridge.request.bind(this.bridge); this.bridge.request = async (type, payload) => { this.log("info", "\u53D1\u9001\u8BF7\u6C42:", { type, payload }); try { const result = await originalRequest(type, payload); this.log("info", "\u8BF7\u6C42\u6210\u529F:", { type, result }); return result; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); this.log("error", "\u8BF7\u6C42\u5931\u8D25:", { type, error: errorMessage }); throw error; } }; } log(level, message, data) { if (!this.shouldLog(level)) return; const timestamp = this.options.timestamp ? `[${(/* @__PURE__ */ new Date()).toISOString()}]` : ""; const prefix = this.options.prefix; const coloredMessage = this.options.colors ? this.colorize(level, message) : message; console.log(`${timestamp} ${prefix} ${coloredMessage}`, data || ""); } shouldLog(level) { const levels = ["debug", "info", "warn", "error"]; const currentLevelIndex = levels.indexOf(this.options.level); const messageLevelIndex = levels.indexOf(level); return messageLevelIndex >= currentLevelIndex; } colorize(level, message) { if (!this.options.colors) return message; const colors = { debug: "\x1B[36m", // cyan info: "\x1B[32m", // green warn: "\x1B[33m", // yellow error: "\x1B[31m", // red reset: "\x1B[0m" }; return `${colors[level] || ""}${message}${colors.reset}`; } }; function createLogger(bridge, options) { return new Logger(bridge, options); } // src/plugins/retry.ts var RetryManager = class { constructor(bridge, options = {}) { this.bridge = bridge; this.options = __spreadValues({ maxRetries: 3, baseDelay: 1e3, maxDelay: 1e4, backoff: "exponential", retryCondition: (error) => error.message.includes("timeout") }, options); this.setupRetry(); } setupRetry() { const originalRequest = this.bridge.request.bind(this.bridge); this.bridge.request = async (type, payload) => { return this.requestWithRetry(originalRequest, type, payload); }; } async requestWithRetry(originalRequest, type, payload) { let lastError; for (let attempt = 0; attempt <= this.options.maxRetries; attempt++) { try { return await originalRequest(type, payload); } catch (error) { lastError = error instanceof Error ? error : new Error(String(error)); if (!this.options.retryCondition(lastError)) { throw lastError; } if (attempt === this.options.maxRetries) { throw lastError; } const delay = this.calculateDelay(attempt); console.warn( `[CrossFrame] \u8BF7\u6C42\u5931\u8D25\uFF0C${delay}ms \u540E\u91CD\u8BD5 (${attempt + 1}/${this.options.maxRetries})` ); await this.sleep(delay); } } throw lastError; } calculateDelay(attempt) { let delay; if (this.options.backoff === "linear") { delay = this.options.baseDelay * (attempt + 1); } else { delay = this.options.baseDelay * Math.pow(2, attempt); } return Math.min(delay, this.options.maxDelay); } sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } // 手动重试方法 async retryRequest(type, payload, customOptions) { const options = __spreadValues(__spreadValues({}, this.options), customOptions); for (let attempt = 0; attempt <= options.maxRetries; attempt++) { try { return await this.bridge.request(type, payload); } catch (error) { const err = error instanceof Error ? error : new Error(String(error)); if (!options.retryCondition(err) || attempt === options.maxRetries) { throw err; } const delay = this.calculateDelayWithOptions(attempt, options); await this.sleep(delay); } } throw new Error("Retry failed"); } calculateDelayWithOptions(attempt, options) { let delay; if (options.backoff === "linear") { delay = options.baseDelay * (attempt + 1); } else { delay = options.baseDelay * Math.pow(2, attempt); } return Math.min(delay, options.maxDelay); } }; function createRetryManager(bridge, options) { return new RetryManager(bridge, options); } // src/plugins/queue-manager.ts var QueueManager = class { constructor(bridge, options = {}) { this.messageQueue = []; this.processing = false; this.bridge = bridge; this.options = __spreadValues({ maxSize: 100, flushInterval: 1e3, batchSize: 10, priority: false }, options); this.setupQueue(); this.startFlushTimer(); } setupQueue() { this.bridge.send.bind(this.bridge); this.bridge.send = (type, payload) => { this.enqueue({ type, payload, timestamp: Date.now() }); }; this.bridge.request.bind(this.bridge); this.bridge.request = (type, payload, requestTimeout) => { return new Promise((resolve, reject) => { this.enqueue({ type, payload, timestamp: Date.now(), resolve, reject, requestTimeout }); }); }; } enqueue(message) { if (this.messageQueue.length >= this.options.maxSize) { const error = new Error("\u6D88\u606F\u961F\u5217\u5DF2\u6EE1"); if (message.reject) { message.reject(error); } else { console.warn("[CrossFrame] \u6D88\u606F\u961F\u5217\u5DF2\u6EE1\uFF0C\u4E22\u5F03\u6D88\u606F:", message); } return; } this.messageQueue.push(message); if (this.options.priority) { this.messageQueue.sort((a, b) => (b.priority || 0) - (a.priority || 0)); } if (this.messageQueue.length >= this.options.batchSize) { this.flush(); } } startFlushTimer() { this.flushTimer = setInterval(() => { if (this.messageQueue.length > 0) { this.flush(); } }, this.options.flushInterval); } async flush() { if (this.processing || this.messageQueue.length === 0) { return; } this.processing = true; const batch = this.messageQueue.splice(0, this.options.batchSize); try { for (const message of batch) { try { if (message.resolve) { const result = await this.bridge.request( message.type, message.payload, message.requestTimeout ); message.resolve(result); } else { this.bridge.send(message.type, message.payload); } } catch (error) { if (message.reject) { message.reject( error instanceof Error ? error : new Error(String(error)) ); } else { console.error("[CrossFrame] \u6D88\u606F\u5904\u7406\u5931\u8D25:", error); } } } } finally { this.processing = false; } } // 手动刷新队列 async flushNow() { return this.flush(); } // 设置消息优先级 setPriority(type, payload, priority) { this.enqueue({ type, payload, priority, timestamp: Date.now() }); } // 获取队列状态 getQueueStatus() { return { size: this.messageQueue.length, maxSize: this.options.maxSize, processing: this.processing, usage: this.messageQueue.length / this.options.maxSize * 100 }; } // 清空队列 clear() { const rejectedCount = this.messageQueue.filter((msg) => msg.reject).length; this.messageQueue.forEach((msg) => { if (msg.reject) { msg.reject(new Error("\u961F\u5217\u5DF2\u6E05\u7A7A")); } }); this.messageQueue = []; console.log(`[CrossFrame] \u961F\u5217\u5DF2\u6E05\u7A7A\uFF0C${rejectedCount} \u4E2A\u8BF7\u6C42\u88AB\u62D2\u7EDD`); } // 销毁队列管理器 destroy() { if (this.flushTimer) { clearInterval(this.flushTimer); } this.clear(); } }; function createQueueManager(bridge, options) { return new QueueManager(bridge, options); } export { Logger, QueueManager, RetryManager, __objRest, __spreadValues, createLogger, createQueueManager, createRetryManager }; //# sourceMappingURL=chunk-JI2PIO5G.mjs.map //# sourceMappingURL=chunk-JI2PIO5G.mjs.map