102 Commits
Author SHA1 Message Date
JoeAllen a9c92e0974 feat: 任务栏图标嵌入、窗口置顶钉子与进程资源采样
- build.rs + embed-resource 嵌入 icon.ico:gpui 从 exe 资源 ID 1
  加载窗口类图标,此前缺失导致任务栏显示系统默认图标
- 标题栏新增钉子按钮:sysmon::set_topmost 经 raw-window-handle
  取 HWND 调 SetWindowPos(HWND_TOPMOST),Pin/PinOff 图标随状态切换
- sysmon 模块:CPU 时间差分、工作集/峰值/提交内存、线程/句柄采样
  与运行时长基准(Windows 实现,其余平台返回空采样)
2026-09-29 17:00:59 +08:00
JoeAllen 4290ffdeeb fix: 标题栏拖拽区吞掉顶栏按钮的鼠标点击
gpui-component 把整条 TitleBar 标记为 WindowControlArea::Drag
(WM_NCHITTEST 返回 HTCAPTION),其上的「新建连接/钉子/主题/菜单」
按钮点击全部被系统当作拖拽标题栏处理。

给右侧按钮簇加 occlude()(HitboxBehavior::BlockMouse):hit_test
收集到 BlockMouse hitbox 即截断,父级 Drag 区不再进入命中列表。
WM_NCHITTEST 探针验证按钮区由 HTCAPTION 变为 HTCLIENT。
2026-09-29 17:00:58 +08:00
JoeAllen 85a3bfcb1b perf: 消息内存按字节预算,杜绝大报文流撑爆内存
- 新增 MessageRing:条数上限 + 每连接 32MB 字节预算双重驱逐
  (从最旧丢弃,均摊 O(1));预分配容量按设置钳制在 512
- 单条 payload 保留上限 256KB → 128KB;MqttRecord::retained_bytes
  计入文本与原始字节,供预算驱逐与资源监控展示
- 清空消息统一走 clear_messages;设置页标注字节预算兜底说明
- 新增单元测试:条数驱逐、字节预算、超预算单条保留、驱逐顺序
2026-09-29 17:00:34 +08:00
JoeAllen b862a50b04 fix: 发布脚本 ps1 修复 $Root 引用顺序与凭证获取
- URL/token 推断块用到 $Root,但其赋值在块之后(首次运行即崩),
  调整到最前
- git credential fill 拒收 PS/cmd 管道的 CRLF 输入(\r 使其报
  missing protocol field),改为写 LF 临时文件、由 cmd 内部重定向;
  stderr 同样留在 cmd 内,避开 PS 5.1 在 EAP=Stop 下对原生命令
  2>$null 抛 NativeCommandError 的问题
- remote 推断加 try/catch,无 remote 时走 GITEA_OWNER/REPO 环境变量
2026-09-29 14:16:21 +08:00
JoeAllen 878ea7cc76 chore: bump 1.0.3;发布脚本零配置化
Release / Meta (push) Canceled after 0s
Release / Test (push) Canceled after 0s
Release / Build (ubuntu-latest) (push) Canceled after 0s
Release / Publish package (push) Canceled after 0s
- 版本升级 1.0.2 → 1.0.3
- 脚本不再要求预置环境变量:GITEA_URL 从 git remote origin 推断,
  GITEA_TOKEN 缺失时自动取 Git Credential Manager 中同一主机的凭证
  (与 git 推送同源的 OAuth 凭证,无需另行创建 API token)
2026-09-29 13:43:30 +08:00
JoeAllen 2ef5133bcd fix: KvEditor key 规范化与传输端口往返保留自定义值
- KvEditor 的 key 统一 trim 并去重(保留最后一条):带首尾空白的 key
  永远无法被 {{key}} 模板引用,重复 key 只有首条生效
- 切换传输方式仅当当前端口仍是某个默认端口时才跟随切换:
  WSS:9443 → TCP → WSS 的往返不再丢失自定义端口
2026-09-29 10:34:22 +08:00
JoeAllen 2f35bca546 fix: 阿里云接入点域名、一机一密签名规范与预设回填
- Token 模式(云消息队列 MQTT 版)接入点修正为 {实例ID}.mqtt.aliyuncs.com,
  原先拼成物联网平台 iothub 域名,连接必失败;region 不参与该产品域名
- 一机一密模式按物联网平台官方直连规范重写:clientId 带
  securemode=2,signmethod=hmacsha256,timestamp 后缀,password 为
  HMAC-SHA256 拼接串签名,接入点 {ProductKey}.iot-as-mqtt.{region}.aliyuncs.com
  (新增 product_key 字段与输入框)
- 对话框选中预设即回填表单:原先只做高亮,保存/连接读的是表单旧值,
  会把所选预设用另一条的数据覆盖(含密钥)或用错误凭据生成连接;
  「新建」同步清空表单
2026-09-29 10:34:22 +08:00
JoeAllen 7426b1fe69 fix: 数据文件损坏防护、写盘 fsync 与临时文件清理
- 加载失败不再静默:elog(stderr + Sentry)记录,本次会话按空数据继续
- 曾加载失败的文件在重新保存前先备份为 <name>.corrupt-<时间戳>,
  杜绝「连接全部消失后被空数据覆盖」的不可恢复丢失
- 写盘 tmp+rename 前补 sync_all,掉电时 rename 提交的目标内容完整;
  tmp 名拼入 pid 防并发互踩,rename 失败清理残留 tmp
2026-09-29 10:34:21 +08:00
JoeAllen ab13f485e0 fix: MQTT 连接生命周期竞态与事件处理
连接句柄(mqtt.rs):
- ConnHandle 增加代数 generation,事件循环退出只在仍是自己这一代时
  才移除句柄——旧循环无条件按 id 删除会把重连后的新句柄删掉,
  导致连接显示在线却无法从 UI 断开、发布/订阅报连接不存在
- connect() 同步插入占位句柄(client=None),建连期间也可被取消;
  建连完成后仅当句柄仍是本代才升级为可用客户端
- 重连 2 秒退避改为可取消的 select:原先 close() 的取消信号在退避
  期间不可见,会对用户已关闭的连接继续真实重连
- 重连成功后清零计数(max_reconnect_times 限流的是连续失败次数);
  v4 CONNACK 拒绝上报真实返回码;test_handshake 断开后再 poll 冲出
  DISCONNECT 报文;建连的证书文件读取移入 spawn_blocking

消息记录与事件(model.rs / app.rs / connection_view.rs):
- 非文本负载保留原始字节(MqttRecord.raw_bytes,仅非法 UTF-8 时
  占用,纯文本零开销),详情 Hex/Base64 不再展示 lossy 失真字节
- EngineEvent::Published 补齐 response_topic/correlation_data/
  message_expiry;correlation_data 两侧统一「优先文本、回退 hex」
- 事件入口加连接存在性守卫:删除连接后排队的引擎事件不再复活
  状态/消息(内存泄漏)或为已删连接写孤儿订阅
- SUBACK 失败时移除乐观插入的订阅行;成功事件只刷新已有订阅,
  不再用默认字段复活 SUBACK 前被删除的订阅
- Connecting 期间侧栏电源按钮防抖;分组名恰为 all/ungrouped 时
  chip 元素 id 改前缀避免共享交互状态
- 「清空」按钮按消息总数而非过滤命中数判断禁用;搜索匹配的
  大小写快速路径限定 ASCII(U+1E9B 等小写映射非自身的字符)
- 应用发布预设后同步模板变量面板,残留行不再写回全局变量
- 日志文件套 BufWriter,高频消息流不再逐条落盘 syscall
2026-09-29 10:33:59 +08:00
JoeAllen 6ff05f7216 ci: 发布脚本自动创建 Release 并按 OTA 命名上传附件
应用内 OTA 只认 Gitea Release 附件(update.rs 查 /releases),此前脚本
只上传 Generic 包,Release 不存在时更新检查永远失败。现在:

- 自动查询/创建与版本同名 tag 的 Release,附件命名规范为
  mqttx-v<ver>-<triple>-mqttx[.exe](不符约定时重命名后上传),
  附带 .sha256 侧车,供 OTA sha256 校验
- 版本号统一剥离 v 前缀(git describe 与 Cargo.toml 两种来源一致)
- 平台三元组按运行环境推断(与 update.rs::platform_triple 一致),
  可用 GITEA_TRIPLE 覆盖
- owner/repo 均支持从 git remote 推断,可用 GITEA_REPO 参数覆盖
- ps1 附件上传走 .NET HttpClient multipart(PS 5.1 无 -Form)
2026-09-29 10:33:42 +08:00
JoeAllen 5dc1a8cc0b fix: OTA 更新需用户同意、下载完整性与暂存区管理
- 安装同意标记:仅「下次启动安装」写入,main.rs 凭标记才自动安装,
  跳过确认对话框不会再被强制升级;对话框新增「暂不更新」(删除暂存包)
- 下载完整性:API 提供大小却未下满/超量时报错(read 返回 0 无法
  区分干净结束与连接截断);失败路径统一清理 tmp 文件
- 版本比较遵循 semver 预发布语义(1.0.0-beta.2 不比 1.0.0 新);
  暂存文件名按尾部锚点解析,预发布后缀不再丢失导致重复下载
- 多版本暂存并存时取最新(readdir 顺序无序);下载完成后清理旧版本残留
- install_staged:spawn 失败(杀毒锁文件)自动恢复旧版本并如实报告回滚结果
- agent 加整体 10 分钟超时;cleanup_old 大小写不敏感、跳过近期 tmp
  避免误删并行实例正在写入的文件
- 设置对话框:下载进度条传百分比(原 0~1 小数只显示 1%);
  立即安装失败显示具体错误;Sentry release 与更新检查同源版本号
2026-09-29 10:33:28 +08:00
JoeAllen f1a7c9eb45 chore: 补记 Cargo.lock 的 1.0.2 版本号 2026-09-29 10:33:28 +08:00
JoeAllen 4a04e3d5b7 chore: bump 1.0.2
Release / Meta (push) Canceled after 0s
Release / Test (push) Canceled after 0s
Release / Build (ubuntu-latest) (push) Canceled after 0s
Release / Publish package (push) Canceled after 0s
2026-09-29 01:08:06 +08:00
JoeAllen 96865c0588 perf: 深度优化消息内存占用
- 消息缓冲 Vec → VecDeque:原来溢出时 drain(0..n) 每条消息 O(n)
  搬移,高频消息下产生大量拷贝;环形缓冲均摊 O(1),并按配置上限
  预分配避免反复扩容
- connection_id/topic/payload 改 Arc<str>:引擎侧主题驻留
  (10k 上限,超出整体重建),同主题数千条记录只存一份;
  消息列表每帧克隆最多 300 条用于渲染,payload 共享后零拷贝
- 单条 payload 历史保留上限 256KB(retained_payload,UTF-8
  边界安全截断),超大报文不再长期占据环形缓冲;消息行显示
  「已截断」徽章;发布记录改用实际发送字节(修 Base64/Hex
  历史内容与真实报文不一致的隐患)
- live 测试适配 Arc<str>;补截断边界单元测试(22 个 lib 测试 +
  2 个 live 测试通过)
2026-09-29 01:07:32 +08:00
JoeAllen 88a8652d7b feat: 接入自建 Sentry 错误上报
- DSN 指向 rustrak 自建 Sentry(项目 8),release 标记 mqttx@版本
- panic 路径:sentry-panic 链式钩子捕获 + 外层钩子 flush 5s,
  确保 panic=abort 终止进程前事件送出
- 存储层 elog! 持久化错误同步 capture_message 上报
- 传输用 reqwest+rustls,避免 openssl 依赖
2026-09-29 00:30:23 +08:00
JoeAllen bc49d1839c feat: OTA 改为静默下载 + 安装需用户确认
- 下载落到数据目录 updates/ 暂存区(退出不丢失),校验后等待安装
- 启动自动检查:静默检查+下载,完成后弹「更新就绪」对话框,
  由用户选择 立即安装(重启) 或 下次启动安装
- main 在进入 UI 前检测暂存区并完成自替换(下次启动安装路径)
- 设置对话框:下载完成后进入「待安装」状态,提供两个安装时机按钮
- install_and_restart 拆分为 download_and_stage / load_staged / install_staged
2026-09-29 00:22:35 +08:00
JoeAllen bf6d165854 feat: OTA 自更新(Gitea Release 为更新源)
Release / Meta (push) Canceled after 0s
Release / Test (push) Canceled after 0s
Release / Build (ubuntu-latest) (push) Canceled after 0s
Release / Publish package (push) Canceled after 0s
- update.rs:检查最新 Release(latest 端点+列表回退)、版本比较、
  平台产物挑选(含 .sha256 侧车)、下载进度、sha256 校验、
  自替换(改名 .old → 换入新 exe → 拉起新进程)、启动清理遗留
- 设置 → 关于:检查更新按钮、发现新版本提示、下载进度条(Progress)、
  失败重试;自动检查更新开关真正生效(启动后台检查并弹通知)
- 版本 1.0.0 → 1.0.1(首个带 OTA 的发布版本)
- 顺手修 clippy 遗留警告(is_none_or、合并 if)
2026-09-28 23:44:56 +08:00
JoeAllen 262bc265d8 ci: release 工作流仅保留 Linux 构建(当前 runner 无 windows-latest 标签)
Release / Meta (push) Canceled after 0s
Release / Test (push) Canceled after 0s
Release / Build (ubuntu-latest) (push) Canceled after 0s
Release / Publish package (push) Canceled after 0s
Windows 产物改由本地 publish-gitea 脚本上传;runner 就绪后可恢复矩阵。
2026-09-28 23:08:01 +08:00
JoeAllen 4e70741f55 feat: Linear 风格 UI 主题(近黑/纯白扁平调色板、靛蓝主色、14px 密度与 6px 圆角)
Release / Meta (push) Canceled after 0s
Release / Test (push) Canceled after 0s
Release / Build (ubuntu-latest) (push) Canceled after 0s
Release / Build (windows-latest) (push) Canceled after 0s
Release / Publish package (push) Canceled after 0s
2026-09-28 22:49:56 +08:00
JoeAllen cd6b6f3201 feat: 预设管理页与发布面板内联变量绑定(占位符提取、快捷改值、渲染预览) 2026-09-28 22:34:02 +08:00
JoeAllen 085d7c5589 feat: 补齐预设与变量注入(遗嘱模板注入、v5 文本属性注入、删除预设二次确认) 2026-09-28 19:04:41 +08:00
JoeAllen f8ce93f0dd fix: 修复 UI 审查问题(图标资产全量化、主区布局贴顶、订阅数据保护与 28 项交互缺陷) 2026-09-28 18:40:58 +08:00
JoeAllen c1c4fc011e feat: GPUI 版补齐 MQTTX 基础功能对标(分组/SSL证书/订阅增强/消息流控制/设置与日志) 2026-09-28 14:41:15 +08:00
JoeAllen bf6937b776 feat: 重写为 GPUI 原生桌面应用并接入 Gitea 软件包发布
- gpui-kit 0.6 原生 UI:连接管理、消息流/日志、发布预设、全局变量、
  设置、阿里云连接预设、原生 Logo
- MQTT 5.0/3.1.1 引擎(rumqttc,TCP/TLS/WS/WSS),独立 tokio runtime
  + 事件泵,真实 broker 端到端测试
- 连接表单:保存前可一键测试连接(宽松校验,自动生成临时 Client ID),
  高级属性(认证/MQTT 5 属性/遗嘱)按需折叠显示,WS 路径仅 WS/WSS 显示
- bug 修复:Hex 奇数长度显式报错、测试连接唯一 Client ID、Base64/Hex
  发布发送真实字节、v5 发布记录携带 Content-Type/用户属性、预设应用
  清除旧 Content-Type、模板时间基准统一;补 8 个单元测试
- Gitea 发布:Generic Package 上传脚本(bash/PowerShell)+ Actions
  release 工作流(tag 触发,双平台构建),README 使用说明
2026-09-28 11:39:47 +08:00
JoeAllen 0152a10ee6 feat: 阿里云 MQTT 连接预设、连接分组与 MQTT 3.1.1 支持
- 后端引入 rumqttc v4 客户端,支持 MQTT 3.1.1 连接/发布/订阅,协议版本随连接下发
- 连接表单:阿里云预设管理(分组、导入导出、去抖自动保存),退出云模式需确认,mqtts 时端口跟随 8883
- 连接列表:分组列就地编辑(输入即创建),空分组提示优化
- 导入按内容去重并提示跳过数量,导出提示含明文密钥
- 调试日志密码脱敏;修复多处取消弹窗的 unhandled rejection
2026-09-04 01:45:19 +08:00
JoeAllen 8a2c63e575 feat: 集成 visual-json 可视化 JSON 编辑/查看并更新品牌图标
- 发送面板 Payload 增加「文本 / JSON 可视化」切换,可视化编辑实时回写
- 消息流 JSON 消息改为只读可视化查看,拦截双击/删除/右键等编辑入口
- visual-json 主题跟随应用亮/暗 comfort 色板
- 更新应用图标与启动页 logo(mqttx.svg + Tauri 各尺寸图标)
2026-08-24 13:41:08 +08:00
Joe Allen 72a388a092 chore: 删除 pipeline.yml 2026-08-20 16:39:09 +08:00
Joe Allen 41929dc7c2 ci: 添加云效流水线配置 (pipeline.yml)
- lint 阶段:pnpm 安装 + vue-tsc 类型检查
- build-linux 阶段:Tauri 系统依赖 + Rust 安装 + pnpm tauri build
- 支持 TAURI_SIGNING_KEY 签名更新构件
- release 阶段(标签触发):生成更新 JSON 元数据
2026-08-20 15:58:39 +08:00
Joe Allen 9f6870440b chore: 取消跟踪 dsh-usage 目录 2026-08-20 15:49:53 +08:00
Joe Allen e2d829630e docs: 更新 README.md 为项目完整文档 2026-08-20 15:26:49 +08:00
Joe Allen f5a702fab1 feat: 添加 Tauri 自动更新器插件支持 (updater plugin)
- 添加 tauri-plugin-updater / tauri-plugin-process Rust 依赖
- 注册 updater 和 process 插件到 Tauri 构建器
- 配置 tauri.conf.json 更新器端点与公钥占位
- 添加 @tauri-apps/plugin-updater / plugin-process npm 依赖
- 创建 useUpdater composable(静默检查、手动检查、下载进度、安装重启)
- 在 AppLayout 标题栏集成更新交互 UI(下载按钮、进度条、安装状态)
- 添加 .pnpm-store 到 .gitignore
2026-08-20 15:16:23 +08:00
Joe Allen 77724e13a1 fix: restore rust-toolchain.toml 2026-08-20 13:54:56 +08:00
Joe Allen 56f162c9a4 feat: add Chinese language support for NSIS and MSI installers
- NSIS: SimpChinese + English
- WiX (MSI): zh-CN + en-US
2026-08-20 13:54:37 +08:00
Joe Allen 6ee84e59b2 fix: use nightly-x86_64-pc-windows-gnu toolchain 2026-08-20 10:16:37 +08:00
Joe Allen f43bdaf1d2 ci: switch Rust to nightly toolchain
- rust-toolchain.toml: channel = nightly
- Add x86_64-pc-windows-gnu target for local mingw64 build
- Fix CI workflow YAML syntax error
2026-08-20 10:08:17 +08:00
Joe Allen 25d9900880 fix: TypeScript errors in CI
- ContextMenu: remove unused cleanup variable (never assigned, TS 6 infer as never)
- GlobalVariableManager: add explicit boolean type to event handler param
- LogPanel: use openPath instead of deprecated open from @tauri-apps/plugin-opener
2026-08-20 09:29:34 +08:00
Joe Allen 49f06f59fa ci: add GitHub Actions workflow
- Frontend: type-check + build (ubuntu-latest)
- Rust: cargo check + clippy (ubuntu-latest)
- Tauri build: Windows (MSVC) + Linux, on push to main
- Upload build artifacts
- rust-toolchain.toml for consistent Rust version
2026-08-20 09:07:36 +08:00
Joe Allen 8407f5daef feat: pinable & draggable preset tabs
- Optional: only presets you pin appear as tabs (click + 添加)
- Pinable: + button opens dropdown to select which presets to pin
- Draggable: drag grip (⠿) to reorder tabs via HTML5 drag & drop
- Unpin: hover tab shows × button to remove it
- Independent editor state per pinned preset
- Drag visual feedback: opacity, border highlight
2026-08-19 11:57:34 +08:00
Joe Allen 1d0c77796d feat: preset tabs for quick switching
- Replace dropdown with tab bar: each preset is a tab
- Click a tab to load that preset's topic/payload/QoS/Retain
- Per-preset independent editor state (variables, v5 props preserved)
- Variables and v5 properties are maintained per-tab, not shared
- Close button on active tab to deselect (when multiple presets)
- Auto-select first preset on load
- Send button shows current preset name
2026-08-19 11:35:59 +08:00
Joe Allen 6646c37722 feat: batch preset send mode
- Toggle between single and batch mode with a button
- Batch mode: multi-select presets, shows selected preset list
- Batch send: sends all selected presets sequentially with progress
- Progress indicators: pending → sending (spinner) → success (✓) / error (✗)
- Single mode: unchanged UX with topic/payload/QoS/Retain editors
- Both modes share variable bindings and v5 properties
2026-08-19 11:31:58 +08:00
Joe Allen 47de6452b4 fix: dark mode color variables
- Override --el-color-white to dark bg to prevent white text on colored backgrounds
- Add comprehensive Element Plus dark mode variables (input, table, tag, dialog, select, checkbox, switch, etc.)
- Fix hardcoded color: #fff in SendPanel toggle-badge to use CSS variable
- Add missing --el-bg-color-page, --el-fill-color-dark, --el-fill-color-blank
2026-08-19 11:05:21 +08:00
Joe Allen f07eaae99c feat: theme follows system preference by default
- No saved preference → use prefers-color-scheme media query
- User clicks toggle → save explicit preference to localStorage
- Listen for system theme changes (OS-level toggle) when no explicit preference
- applyTheme() helper to keep isDark ref and DOM in sync
2026-08-19 11:03:07 +08:00
Joe Allen 7821272bcd fix: hover preview mouse following
- Fixed Chinese variable name that caused JS runtime error (预估Width → estimatedWidth-like logic)
- Proper viewport boundary detection with flip-to-left and flip-to-top
- Uses maxHeight prop instead of hardcoded 360
- Cleaner position calculation with Math.min/Math.max clamping
2026-08-18 19:54:31 +08:00
Joe Allen 9042659fbf feat: hover preview for send panel payload input
- Wrapped payload textarea in HoverPreview
- Shows full formatted JSON on hover (600ms delay)
- Helps when template is too long for the 2-row textarea
2026-08-18 19:47:21 +08:00
Joe Allen 3c04af9532 feat: hover preview for truncated JSON content
New HoverPreview component shows a floating tooltip with full
content on mouse hover (400ms delay). Applied to:
- MessageStream: collapsed + expanded payload views
- PresetList: payload preview in table
- LogPanel: details section

The popup follows the mouse cursor, auto-positions within viewport,
and supports monospace code formatting with scroll for long content.
2026-08-18 19:29:12 +08:00
Joe Allen 85e31e2f96 feat: visual comfort improvements
- Soft color palette with warm earth tones (green-primary, warm neutrals)
- Dark mode support with theme toggle in header (persisted in localStorage)
- Reduced contrast: softer borders, subtle shadows, muted colors
- Custom scrollbar, focus rings, button/input/dialog styling
- Better typography: line-height 1.6, optimized font stack
- ELement Plus theme overrides for consistent comfort styling
- All styles in src/styles/comfort.css with CSS custom properties
2026-08-18 16:37:36 +08:00
Joe Allen 85b7c6b31b feat: message cards expanded by default
Change toggle logic from 'expanded set' (collapsed by default)
to 'collapsed set' (expanded by default). Users can collapse
individual messages with the toggle button.
2026-08-18 14:59:22 +08:00
Joe Allen 6ced5c8444 feat: global right-click control + topic tree context menu
- UseContextMenu composable: global right-click prevention
  - PROD: prevent default browser context menu everywhere
  - DEV: allow native context menu for debugging
- ContextMenu component: reusable custom right-click menu
- TopicTree: right-click nodes for copy topic / subscribe / unsubscribe / filter
  - Copy topic to clipboard
  - Subscribe with QoS 0/1/2
  - Unsubscribe with confirmation
  - Filter by topic
2026-08-18 14:58:31 +08:00
Joe Allen 7f6a4f84d8 feat: auto-format JSON display everywhere
- Shared prettyJson/truncate/isJson utility in src/utils/format.ts
- MessageStream: collapsed preview + expanded view both auto-format JSON
- LogPanel: log details with JSON content auto-formatted
- PresetList: payload preview auto-formatted
- Deduplicated isJson/formatPayload logic
2026-08-18 14:56:00 +08:00
Joe Allen 9b7094dcf2 fix: auto-resubscribe persisted subscriptions on reconnect
The topic tree subscriptions were persisted in localStorage but
never re-subscribed when the connection was re-established. Now
when mqtt:status fires with 'connected', all saved subscriptions
for that connection are automatically re-subscribed.
2026-08-18 14:52:20 +08:00