From d104b136d0fec314a651673412117fd356d80089 Mon Sep 17 00:00:00 2001 From: Dan Ditomaso Date: Mon, 14 Jul 2025 19:38:47 -0400 Subject: [PATCH] feat: add disconnect method --- deno.lock | 61 +------------------ packages/core/deno.json | 2 +- packages/core/src/meshDevice.ts | 7 +++ packages/core/src/types.ts | 1 + packages/web/package.json | 10 ++- .../i18n/locales/en/commandPalette.json | 1 + .../src/components/CommandPalette/index.tsx | 10 +++ 7 files changed, 25 insertions(+), 67 deletions(-) diff --git a/deno.lock b/deno.lock index cddc5bc6..d029f88a 100644 --- a/deno.lock +++ b/deno.lock @@ -23,11 +23,6 @@ "npm:@bufbuild/protobuf@^2.2.3": "2.6.0", "npm:@bufbuild/protobuf@^2.6.0": "2.6.0", "npm:@hookform/resolvers@^5.1.1": "5.1.1_react-hook-form@7.60.0__react@19.1.0_react@19.1.0", - "npm:@jsr/meshtastic__core@2.6.4": "2.6.4", - "npm:@jsr/meshtastic__js@2.6.0-0": "2.6.0-0", - "npm:@jsr/meshtastic__transport-http@*": "0.2.1", - "npm:@jsr/meshtastic__transport-web-bluetooth@*": "0.1.2", - "npm:@jsr/meshtastic__transport-web-serial@*": "0.2.1", "npm:@noble/curves@^1.9.2": "1.9.2", "npm:@radix-ui/react-accordion@^1.2.11": "1.2.11_@types+react@19.1.8_@types+react-dom@19.1.6__@types+react@19.1.8_react@19.1.0_react-dom@19.1.0__react@19.1.0", "npm:@radix-ui/react-checkbox@^1.3.2": "1.3.2_@types+react@19.1.8_@types+react-dom@19.1.6__@types+react@19.1.8_react@19.1.0_react-dom@19.1.0__react@19.1.0", @@ -104,6 +99,7 @@ "npm:testing-library@^0.0.2": "0.0.2_@angular+common@6.1.10__@angular+core@6.1.10___rxjs@6.6.7___zone.js@0.8.29__rxjs@6.6.7_@angular+core@6.1.10__rxjs@6.6.7__zone.js@0.8.29", "npm:tslog@^4.9.3": "4.9.3", "npm:typescript@^5.8.3": "5.8.3", + "npm:vite@*": "7.0.2_@types+node@22.16.0_picomatch@4.0.2", "npm:vite@7": "7.0.2_@types+node@22.16.0_picomatch@4.0.2", "npm:vitest@^3.2.4": "3.2.4_@types+node@22.16.0_happy-dom@18.0.1_vite@7.0.2__@types+node@22.16.0__picomatch@4.0.2", "npm:zod@^3.25.75": "3.25.75", @@ -662,56 +658,6 @@ "@jridgewell/sourcemap-codec" ] }, - "@jsr/meshtastic__core@2.6.4": { - "integrity": "sha512-1Kz5DK6peFxluHOJR38vFwfgeJzMXTz+3p6TvibjILVhSQC2U1nu8aJbn6w5zhRqS+j79OmtrRvdzL6VNsTkkQ==", - "dependencies": [ - "@bufbuild/protobuf", - "@jsr/meshtastic__protobufs", - "crc", - "ste-simple-events", - "tslog" - ], - "tarball": "https://npm.jsr.io/~/11/@jsr/meshtastic__core/2.6.4.tgz" - }, - "@jsr/meshtastic__js@2.6.0-0": { - "integrity": "sha512-+xpZpxK6oUIVOuEs7C+LyxRr2druvc7UNNNTK9Rl8ioXj63Jz1uQXlYe2Gj0xjnRAiSQLR7QVaPef21BR/YTxA==", - "dependencies": [ - "@bufbuild/protobuf", - "@jsr/meshtastic__protobufs", - "crc", - "ste-simple-events", - "tslog" - ], - "tarball": "https://npm.jsr.io/~/11/@jsr/meshtastic__js/2.6.0-0.tgz" - }, - "@jsr/meshtastic__protobufs@2.7.0": { - "integrity": "sha512-ndZhUyB/ADSyjJI+iSeSOoIKqNGZ2+ERVjfY0qnh4jgF740tFTwefC5mzZhOqDLbreGFYS79+429NtH5Ujdzdg==", - "dependencies": [ - "@bufbuild/protobuf" - ], - "tarball": "https://npm.jsr.io/~/11/@jsr/meshtastic__protobufs/2.7.0.tgz" - }, - "@jsr/meshtastic__transport-http@0.2.1": { - "integrity": "sha512-lmQKr3aIINKvtGROU4HchmSVqbZSbkIHqajowRRC8IAjsnR0zNTyxz210QyY4pFUF9hpcW3GRjwq5h/VO2JuGg==", - "dependencies": [ - "@jsr/meshtastic__core" - ], - "tarball": "https://npm.jsr.io/~/11/@jsr/meshtastic__transport-http/0.2.1.tgz" - }, - "@jsr/meshtastic__transport-web-bluetooth@0.1.2": { - "integrity": "sha512-Z+5pv9RXNgY0/crKExOH3pZ6LT0HIXFmnBL7NX5AO2knOFRn+4lmxQEhhmiTTlkUfqyEfAvbjuY5u4mq9TPTdQ==", - "dependencies": [ - "@jsr/meshtastic__core" - ], - "tarball": "https://npm.jsr.io/~/11/@jsr/meshtastic__transport-web-bluetooth/0.1.2.tgz" - }, - "@jsr/meshtastic__transport-web-serial@0.2.1": { - "integrity": "sha512-yumjEGLkAuJYOC3aWKvZzbQqi/LnqaKfNpVCY7Ki7oLtAshNiZrBLiwiFhN7+ZR9FfMdJThyBMqREBDRRWTO1Q==", - "dependencies": [ - "@jsr/meshtastic__core" - ], - "tarball": "https://npm.jsr.io/~/11/@jsr/meshtastic__transport-web-serial/0.2.1.tgz" - }, "@mapbox/geojson-rewind@0.5.2": { "integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", "dependencies": [ @@ -5213,11 +5159,6 @@ "dependencies": [ "npm:@bufbuild/protobuf@^2.6.0", "npm:@hookform/resolvers@^5.1.1", - "npm:@jsr/meshtastic__core@2.6.4", - "npm:@jsr/meshtastic__js@2.6.0-0", - "npm:@jsr/meshtastic__transport-http@*", - "npm:@jsr/meshtastic__transport-web-bluetooth@*", - "npm:@jsr/meshtastic__transport-web-serial@*", "npm:@noble/curves@^1.9.2", "npm:@radix-ui/react-accordion@^1.2.11", "npm:@radix-ui/react-checkbox@^1.3.2", diff --git a/packages/core/deno.json b/packages/core/deno.json index 624babd1..1723f56f 100644 --- a/packages/core/deno.json +++ b/packages/core/deno.json @@ -1,6 +1,6 @@ { "name": "@meshtastic/core", - "version": "2.6.4", + "version": "2.6.5", "description": "Core functionalities for Meshtastic web applications.", "exports": { ".": "./mod.ts" diff --git a/packages/core/src/meshDevice.ts b/packages/core/src/meshDevice.ts index 36a2dcfa..8861c764 100755 --- a/packages/core/src/meshDevice.ts +++ b/packages/core/src/meshDevice.ts @@ -818,6 +818,13 @@ export class MeshDevice { this.queue.clear(); } + /** Disconnects from the device **/ + public async disconnect(): Promise { + this.log.debug(Emitter[Emitter.Disconnect], "🔌 Disconnecting from device"); + this.complete(); + await this.transport.toDevice.close(); + } + /** * Gets called when a MeshPacket is received from device */ diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 31457e96..1130824d 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -99,6 +99,7 @@ export enum Emitter { EnterDfuMode = 31, RemoveNodeByNum = 32, SetCannedMessages = 33, + Disconnect = 34, } export interface LogEvent { diff --git a/packages/web/package.json b/packages/web/package.json index 4304fc39..8584c844 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -4,7 +4,6 @@ "type": "module", "description": "Meshtastic web client", "license": "GPL-3.0-only", - "repository": { "type": "git", "url": "git+https://github.com/meshtastic/web.git" @@ -19,11 +18,10 @@ "dependencies": { "@bufbuild/protobuf": "^2.6.0", "@hookform/resolvers": "^5.1.1", - "@meshtastic/core": "npm:@jsr/meshtastic__core@2.6.4", - "@meshtastic/js": "npm:@jsr/meshtastic__js@2.6.0-0", - "@meshtastic/transport-http": "npm:@jsr/meshtastic__transport-http", - "@meshtastic/transport-web-bluetooth": "npm:@jsr/meshtastic__transport-web-bluetooth", - "@meshtastic/transport-web-serial": "npm:@jsr/meshtastic__transport-web-serial", + "@meshtastic/core": "workspace:*", + "@meshtastic/transport-http": "workspace:*", + "@meshtastic/transport-web-bluetooth": "workspace:*", + "@meshtastic/transport-web-serial": "workspace:*", "@noble/curves": "^1.9.2", "@radix-ui/react-accordion": "^1.2.11", "@radix-ui/react-checkbox": "^1.3.2", diff --git a/packages/web/public/i18n/locales/en/commandPalette.json b/packages/web/public/i18n/locales/en/commandPalette.json index 1eed8987..46c58465 100644 --- a/packages/web/public/i18n/locales/en/commandPalette.json +++ b/packages/web/public/i18n/locales/en/commandPalette.json @@ -35,6 +35,7 @@ "scheduleShutdown": "Schedule Shutdown", "scheduleReboot": "Schedule Reboot", "rebootToOtaMode": "Reboot To OTA Mode", + "disconnect": "Disconnect", "resetNodeDb": "Reset Node DB", "factoryResetDevice": "Factory Reset Device", "factoryResetConfig": "Factory Reset Config" diff --git a/packages/web/src/components/CommandPalette/index.tsx b/packages/web/src/components/CommandPalette/index.tsx index 9000bd99..e87277d9 100644 --- a/packages/web/src/components/CommandPalette/index.tsx +++ b/packages/web/src/components/CommandPalette/index.tsx @@ -13,6 +13,7 @@ import { ArrowLeftRightIcon, BoxSelectIcon, BugIcon, + CloudOff, EraserIcon, FactoryIcon, LayersIcon, @@ -199,6 +200,15 @@ export const CommandPalette = () => { connection?.resetNodes(); }, }, + { + label: t("contextual.command.disconnect"), + icon: CloudOff, + action() { + connection?.disconnect().catch((error) => { + console.error("Failed to disconnect:", error); + }); + }, + }, { label: t("contextual.command.factoryResetDevice"), icon: FactoryIcon,