UNPKG

flutter-webview-bridge

Version:

A TypeScript/React bridge for seamless communication between Flutter WebView and web applications

160 lines (159 loc) 6.77 kB
/** * @fileoverview Provides a bridge for communication between web applications and Flutter WebView. * This script captures a MessagePort sent from Flutter and facilitates two-way communication. * * @singleton */ var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; /** * Manages the MessagePort connection with the Flutter host. */ var FlutterBridge = /** @class */ (function () { /** * Initializes the bridge and starts listening for the port from Flutter. */ function FlutterBridge(options) { if (options === void 0) { options = {}; } var _this = this; this.port = null; this.subscribers = new Set(); this.options = __assign({ debug: false, captureCommand: "capturePort", confirmationMessage: "portReceived" }, options); if (typeof window !== "undefined") { this.log("Инициализация FlutterBridge, подписка на window message"); window.addEventListener("message", this.capturePort.bind(this)); if (this.options.debug) { // Дополнительная отладка - слушаем ВСЕ сообщения window.addEventListener("message", function (event) { var _a; _this.log("Получено window message:", { data: event.data, origin: event.origin, source: event.source ? "present" : "null", ports: ((_a = event.ports) === null || _a === void 0 ? void 0 : _a.length) || 0, }); }); } } else { this.warn("window недоступен (SSR?)"); } } /** * Captures the MessagePort sent from Flutter. */ FlutterBridge.prototype.capturePort = function (event) { var _a; if (this.options.debug) { this.log("Проверка сообщения на capturePort:", { data: event.data, hasPorts: event.ports && event.ports.length > 0, portsCount: ((_a = event.ports) === null || _a === void 0 ? void 0 : _a.length) || 0, }); } if (event.data === this.options.captureCommand && event.ports && event.ports.length > 0) { this.log("✅ Flutter message port captured!"); this.port = event.ports[0]; this.port.onmessage = this.handleMessage.bind(this); // Уведомляем Flutter, что порт получен this.port.postMessage(this.options.confirmationMessage); this.log("\u041E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435 '".concat(this.options.confirmationMessage, "'")); } else if (this.options.debug) { this.log("❌ Сообщение не соответствует критериям capturePort"); } }; /** * Handles incoming messages from the Flutter port and notifies subscribers. */ FlutterBridge.prototype.handleMessage = function (event) { this.log("Message received from Flutter:", event.data); this.subscribers.forEach(function (callback) { return callback(event.data); }); }; /** * Sends a message to the Flutter application. */ FlutterBridge.prototype.sendMessage = function (data) { if (this.options.debug) { this.log("Попытка отправки сообщения:", { data: data, hasPort: !!this.port, portState: this.port ? "active" : "null", }); } if (this.port) { this.log("✅ Отправка сообщения во Flutter"); this.port.postMessage(data); } else { this.warn("❌ Flutter port not initialized. Cannot send message."); if (this.options.debug) { this.warn("Возможные причины:"); this.warn("1. Flutter еще не отправил порт"); this.warn("2. Сообщение от Flutter имеет неправильный формат"); this.warn("3. Проблема с timing - сообщение отправляется слишком рано"); } } }; /** * Subscribes a callback to listen for messages from Flutter. */ FlutterBridge.prototype.subscribe = function (callback) { var _this = this; this.subscribers.add(callback); this.log("\u041F\u043E\u0434\u043F\u0438\u0441\u0447\u0438\u043A \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D. \u0412\u0441\u0435\u0433\u043E: ".concat(this.subscribers.size)); return function () { _this.subscribers.delete(callback); _this.log("\u041F\u043E\u0434\u043F\u0438\u0441\u0447\u0438\u043A \u0443\u0434\u0430\u043B\u0435\u043D. \u041E\u0441\u0442\u0430\u043B\u043E\u0441\u044C: ".concat(_this.subscribers.size)); }; }; /** * Проверяет состояние подключения */ FlutterBridge.prototype.getConnectionStatus = function () { return { hasPort: !!this.port, subscribersCount: this.subscribers.size, }; }; /** * Проверяет, инициализирован ли порт */ FlutterBridge.prototype.isConnected = function () { return !!this.port; }; /** * Отключает bridge и очищает все подписки */ FlutterBridge.prototype.disconnect = function () { if (this.port) { this.port.close(); this.port = null; } this.subscribers.clear(); this.log("Bridge отключен"); }; FlutterBridge.prototype.log = function (message, data) { if (this.options.debug) { console.log("[FlutterBridge] ".concat(message), data || ""); } }; FlutterBridge.prototype.warn = function (message) { console.warn("[FlutterBridge] ".concat(message)); }; return FlutterBridge; }()); export { FlutterBridge }; // Export a singleton instance of the bridge with debug enabled by default export var flutterBridge = new FlutterBridge({ debug: false });