UNPKG

modbus-connect

Version:

Modbus RTU over Web Serial and Node.js SerialPort

178 lines (177 loc) 5.81 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var PortConnectionTracker_exports = {}; __export(PortConnectionTracker_exports, { PortConnectionTracker: () => PortConnectionTracker }); module.exports = __toCommonJS(PortConnectionTracker_exports); var import_async_mutex = require("async-mutex"); var import_modbus_types = require("../../types/modbus-types.js"); class PortConnectionTracker { _handler; _state; _debounceMs; _mutex = new import_async_mutex.Mutex(); _debounceTimeout = null; constructor(options = {}) { this._debounceMs = options.debounceMs ?? 300; this._state = { isConnected: false, slaveIds: [], timestamp: Date.now() }; } /** * Устанавливает обработчик изменения состояния порта. * При установке — вызывает обработчик с текущим состоянием. */ async setHandler(handler) { const release = await this._mutex.acquire(); try { this._handler = handler; handler( this._state.isConnected, this._state.slaveIds, this._state.isConnected ? void 0 : { type: this._state.errorType, message: this._state.errorMessage } ); } finally { release(); } } /** * Уведомляет о подключении порта. * Игнорируется, если порт уже подключён. * @param slaveIds — список slaveId, подключённых к порту */ async notifyConnected(slaveIds = []) { const release = await this._mutex.acquire(); try { if (this._debounceTimeout) { clearTimeout(this._debounceTimeout); this._debounceTimeout = null; } if (this._state.isConnected && arraysEqual(this._state.slaveIds, slaveIds)) { return; } this._state = { isConnected: true, slaveIds: [...slaveIds], timestamp: Date.now() }; this._handler?.(true, this._state.slaveIds); } finally { release(); } } /** * Уведомляет об отключении порта с trailing debounce. * Последний вызов в серии будет выполнен через `debounceMs`. * @param errorType Тип ошибки, по умолчанию: `ConnectionErrorType.UnknownError` * @param errorMessage Подробное сообщение, по умолчанию: `'Port disconnected'` * @param slaveIds Список slaveId, которые были активны */ notifyDisconnected(errorType = import_modbus_types.ConnectionErrorType.UnknownError, errorMessage = "Port disconnected", slaveIds = []) { if (this._debounceTimeout) { clearTimeout(this._debounceTimeout); } (async () => { const release = await this._mutex.acquire(); try { if (!this._state.isConnected) { return; } this._state = { isConnected: false, errorType, errorMessage, slaveIds: [...slaveIds], timestamp: Date.now() }; this._debounceTimeout = setTimeout(() => { this._debounceTimeout = null; this._handler?.(false, this._state.slaveIds, { type: errorType, message: errorMessage }); }, this._debounceMs); } finally { release(); } })(); } /** * Возвращает копию текущего состояния порта. */ async getState() { const release = await this._mutex.acquire(); try { return { ...this._state, slaveIds: [...this._state.slaveIds] }; } finally { release(); } } /** * Очищает таймер дебонса и сбрасывает состояние. * Вызывается при `destroy()` или полном сбросе. */ async clear() { const release = await this._mutex.acquire(); try { if (this._debounceTimeout) { clearTimeout(this._debounceTimeout); this._debounceTimeout = null; } this._state = { isConnected: false, slaveIds: [], timestamp: Date.now() }; } finally { release(); } } /** * Проверяет, подключён ли порт. */ async isConnected() { const release = await this._mutex.acquire(); try { return this._state.isConnected; } finally { release(); } } /** * Сбрасывает таймер дебонса (только для тестов). * @internal */ __resetDebounce() { if (this._debounceTimeout) { clearTimeout(this._debounceTimeout); this._debounceTimeout = null; } } } function arraysEqual(a, b) { if (a.length !== b.length) return false; const sortedA = [...a].sort((x, y) => x - y); const sortedB = [...b].sort((x, y) => x - y); return sortedA.every((val, idx) => val === sortedB[idx]); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { PortConnectionTracker });