Browse Source
* fixed github workflows to improve handling of mutl runtimes * updating readme * Update packages/core/src/meshDevice.ts Co-authored-by: Copilot <[email protected]> * Update packages/core/package.json Co-authored-by: Copilot <[email protected]> * Update packages/transport-http/package.json Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>pull/723/head
committed by
GitHub
39 changed files with 8538 additions and 3024 deletions
@ -3,12 +3,51 @@ |
|||||
"workspaces": { |
"workspaces": { |
||||
"": { |
"": { |
||||
"name": "meshtastic-web", |
"name": "meshtastic-web", |
||||
|
"dependencies": { |
||||
|
"@bufbuild/protobuf": "^2.6.1", |
||||
|
"ste-simple-events": "^3.0.11", |
||||
|
"tslog": "^4.9.3", |
||||
|
}, |
||||
"devDependencies": { |
"devDependencies": { |
||||
"@biomejs/biome": "^1.8.3", |
"@types/node": "^22.16.4", |
||||
"bun": "^1.1.18", |
"bun": "^1.2.18", |
||||
"typescript": "^5.8.3", |
"typescript": "^5.8.3", |
||||
}, |
}, |
||||
}, |
}, |
||||
|
"packages/core": { |
||||
|
"name": "@meshtastic/core", |
||||
|
"version": "2.6.5", |
||||
|
"dependencies": { |
||||
|
"@meshtastic/protobufs": "npm:@jsr/meshtastic__protobufs", |
||||
|
"crc": "npm:crc@^4.3.2", |
||||
|
}, |
||||
|
}, |
||||
|
"packages/transport-deno": { |
||||
|
"name": "@meshtastic/transport-deno", |
||||
|
"version": "0.1.1", |
||||
|
}, |
||||
|
"packages/transport-http": { |
||||
|
"name": "@meshtastic/transport-http", |
||||
|
"version": "0.2.1", |
||||
|
}, |
||||
|
"packages/transport-node": { |
||||
|
"name": "@meshtastic/transport-node", |
||||
|
"version": "0.0.1", |
||||
|
}, |
||||
|
"packages/transport-web-bluetooth": { |
||||
|
"name": "@meshtastic/transport-web-bluetooth", |
||||
|
"version": "0.1.2", |
||||
|
"devDependencies": { |
||||
|
"@types/web-bluetooth": "npm:@types/web-bluetooth@^0.0.20", |
||||
|
}, |
||||
|
}, |
||||
|
"packages/transport-web-serial": { |
||||
|
"name": "@meshtastic/transport-web-serial", |
||||
|
"version": "0.2.1", |
||||
|
"dependencies": { |
||||
|
"@types/w3c-web-serial": "npm:@types/w3c-web-serial@^1.0.7", |
||||
|
}, |
||||
|
}, |
||||
"packages/web": { |
"packages/web": { |
||||
"name": "meshtastic-web", |
"name": "meshtastic-web", |
||||
"version": "2.7.0-0", |
"version": "2.7.0-0", |
||||
@ -167,25 +206,25 @@ |
|||||
|
|
||||
"@babel/types": ["@babel/[email protected]", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ=="], |
"@babel/types": ["@babel/[email protected]", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ=="], |
||||
|
|
||||
"@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="], |
"@biomejs/biome": ["@biomejs/biome@2.0.6", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.0.6", "@biomejs/cli-darwin-x64": "2.0.6", "@biomejs/cli-linux-arm64": "2.0.6", "@biomejs/cli-linux-arm64-musl": "2.0.6", "@biomejs/cli-linux-x64": "2.0.6", "@biomejs/cli-linux-x64-musl": "2.0.6", "@biomejs/cli-win32-arm64": "2.0.6", "@biomejs/cli-win32-x64": "2.0.6" }, "bin": { "biome": "bin/biome" } }, "sha512-RRP+9cdh5qwe2t0gORwXaa27oTOiQRQvrFf49x2PA1tnpsyU7FIHX4ZOFMtBC4QNtyWsN7Dqkf5EDbg4X+9iqA=="], |
||||
|
|
||||
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.9.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw=="], |
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.0.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-AzdiNNjNzsE6LfqWyBvcL29uWoIuZUkndu+wwlXW13EKcBHbbKjNQEZIJKYDc6IL+p7bmWGx3v9ZtcRyIoIz5A=="], |
||||
|
|
||||
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@1.9.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg=="], |
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.0.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-wJjjP4E7bO4WJmiQaLnsdXMa516dbtC6542qeRkyJg0MqMXP0fvs4gdsHhZ7p9XWTAmGIjZHFKXdsjBvKGIJJQ=="], |
||||
|
|
||||
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g=="], |
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.0.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZSVf6TYo5rNMUHIW1tww+rs/krol7U5A1Is/yzWyHVZguuB0lBnIodqyFuwCNqG9aJGyk7xIMS8HG0qGUPz0SA=="], |
||||
|
|
||||
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA=="], |
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.0.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-CVPEMlin3bW49sBqLBg2x016Pws7eUXA27XYDFlEtponD0luYjg2zQaMJ2nOqlkKG9fqzzkamdYxHdMDc2gZFw=="], |
||||
|
|
||||
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg=="], |
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.0.6", "", { "os": "linux", "cpu": "x64" }, "sha512-geM1MkHTV1Kh2Cs/Xzot9BOF3WBacihw6bkEmxkz4nSga8B9/hWy5BDiOG3gHDGIBa8WxT0nzsJs2f/hPqQIQw=="], |
||||
|
|
||||
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg=="], |
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.0.6", "", { "os": "linux", "cpu": "x64" }, "sha512-mKHE/e954hR/hSnAcJSjkf4xGqZc/53Kh39HVW1EgO5iFi0JutTN07TSjEMg616julRtfSNJi0KNyxvc30Y4rQ=="], |
||||
|
|
||||
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@1.9.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg=="], |
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.0.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-290V4oSFoKaprKE1zkYVsDfAdn0An5DowZ+GIABgjoq1ndhvNxkJcpxPsiYtT7slbVe3xmlT0ncdfOsN7KruzA=="], |
||||
|
|
||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="], |
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.0.6", "", { "os": "win32", "cpu": "x64" }, "sha512-bfM1Bce0d69Ao7pjTjUS+AWSZ02+5UHdiAP85Th8e9yV5xzw6JrHXbL5YWlcEKQ84FIZMdDc7ncuti1wd2sdbw=="], |
||||
|
|
||||
"@bufbuild/protobuf": ["@bufbuild/[email protected].0", "", {}, "sha512-6cuonJVNOIL7lTj5zgo/Rc2bKAo4/GvN+rKCrUj7GdEHRzCk8zKOfFwUsL9nAVk5rSIsRmlgcpLzTRysopEeeg=="], |
"@bufbuild/protobuf": ["@bufbuild/[email protected].1", "", {}, "sha512-DaG6XlyKpz08bmHY5SGX2gfIllaqtDJ/KwVoxsmP22COOLYwDBe7yD3DZGwXem/Xq7QOc9cuR7R3MpAv5CFfDw=="], |
||||
|
|
||||
"@esbuild/aix-ppc64": ["@esbuild/[email protected]", "", { "os": "aix", "cpu": "ppc64" }, "sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw=="], |
"@esbuild/aix-ppc64": ["@esbuild/[email protected]", "", { "os": "aix", "cpu": "ppc64" }, "sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw=="], |
||||
|
|
||||
@ -281,13 +320,19 @@ |
|||||
|
|
||||
"@maplibre/maplibre-gl-style-spec": ["@maplibre/[email protected]", "", { "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/unitbezier": "^0.0.1", "json-stringify-pretty-compact": "^4.0.0", "minimist": "^1.2.8", "quickselect": "^3.0.0", "rw": "^1.3.3", "tinyqueue": "^3.0.0" }, "bin": { "gl-style-format": "dist/gl-style-format.mjs", "gl-style-migrate": "dist/gl-style-migrate.mjs", "gl-style-validate": "dist/gl-style-validate.mjs" } }, "sha512-IGJtuBbaGzOUgODdBRg66p8stnwj9iDXkgbYKoYcNiiQmaez5WVRfXm4b03MCDwmZyX93csbfHFWEJJYHnn5oA=="], |
"@maplibre/maplibre-gl-style-spec": ["@maplibre/[email protected]", "", { "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/unitbezier": "^0.0.1", "json-stringify-pretty-compact": "^4.0.0", "minimist": "^1.2.8", "quickselect": "^3.0.0", "rw": "^1.3.3", "tinyqueue": "^3.0.0" }, "bin": { "gl-style-format": "dist/gl-style-format.mjs", "gl-style-migrate": "dist/gl-style-migrate.mjs", "gl-style-validate": "dist/gl-style-validate.mjs" } }, "sha512-IGJtuBbaGzOUgODdBRg66p8stnwj9iDXkgbYKoYcNiiQmaez5WVRfXm4b03MCDwmZyX93csbfHFWEJJYHnn5oA=="], |
||||
|
|
||||
"@meshtastic/core": ["@jsr/[email protected]", "https://npm.jsr.io/~/11/@jsr/meshtastic__core/2.6.4.tgz", { "dependencies": { "@bufbuild/protobuf": "^2.2.3", "@jsr/meshtastic__protobufs": "^2.6.2", "crc": "^4.3.2", "ste-simple-events": "^3.0.11", "tslog": "^4.9.3" } }, "sha512-1Kz5DK6peFxluHOJR38vFwfgeJzMXTz+3p6TvibjILVhSQC2U1nu8aJbn6w5zhRqS+j79OmtrRvdzL6VNsTkkQ=="], |
"@meshtastic/core": ["@meshtastic/core@workspace:packages/core"], |
||||
|
|
||||
|
"@meshtastic/protobufs": ["@jsr/[email protected]", "https://npm.jsr.io/~/11/@jsr/meshtastic__protobufs/2.7.0.tgz", { "dependencies": { "@bufbuild/protobuf": "^2.2.3" } }, "sha512-ndZhUyB/ADSyjJI+iSeSOoIKqNGZ2+ERVjfY0qnh4jgF740tFTwefC5mzZhOqDLbreGFYS79+429NtH5Ujdzdg=="], |
||||
|
|
||||
|
"@meshtastic/transport-deno": ["@meshtastic/transport-deno@workspace:packages/transport-deno"], |
||||
|
|
||||
"@meshtastic/transport-http": ["@jsr/[email protected]", "https://npm.jsr.io/~/11/@jsr/meshtastic__transport-http/0.2.1.tgz", { "dependencies": { "@jsr/meshtastic__core": "^2.6.0" } }, "sha512-lmQKr3aIINKvtGROU4HchmSVqbZSbkIHqajowRRC8IAjsnR0zNTyxz210QyY4pFUF9hpcW3GRjwq5h/VO2JuGg=="], |
"@meshtastic/transport-http": ["@meshtastic/transport-http@workspace:packages/transport-http"], |
||||
|
|
||||
"@meshtastic/transport-web-bluetooth": ["@jsr/[email protected]", "https://npm.jsr.io/~/11/@jsr/meshtastic__transport-web-bluetooth/0.1.2.tgz", { "dependencies": { "@jsr/meshtastic__core": "^2.6.4" } }, "sha512-Z+5pv9RXNgY0/crKExOH3pZ6LT0HIXFmnBL7NX5AO2knOFRn+4lmxQEhhmiTTlkUfqyEfAvbjuY5u4mq9TPTdQ=="], |
"@meshtastic/transport-node": ["@meshtastic/transport-node@workspace:packages/transport-node"], |
||||
|
|
||||
"@meshtastic/transport-web-serial": ["@jsr/[email protected]", "https://npm.jsr.io/~/11/@jsr/meshtastic__transport-web-serial/0.2.1.tgz", { "dependencies": { "@jsr/meshtastic__core": "^2.6.0" } }, "sha512-yumjEGLkAuJYOC3aWKvZzbQqi/LnqaKfNpVCY7Ki7oLtAshNiZrBLiwiFhN7+ZR9FfMdJThyBMqREBDRRWTO1Q=="], |
"@meshtastic/transport-web-bluetooth": ["@meshtastic/transport-web-bluetooth@workspace:packages/transport-web-bluetooth"], |
||||
|
|
||||
|
"@meshtastic/transport-web-serial": ["@meshtastic/transport-web-serial@workspace:packages/transport-web-serial"], |
||||
|
|
||||
"@noble/curves": ["@noble/[email protected]", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g=="], |
"@noble/curves": ["@noble/[email protected]", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g=="], |
||||
|
|
||||
@ -781,7 +826,7 @@ |
|||||
|
|
||||
"@types/mapbox__vector-tile": ["@types/[email protected]", "", { "dependencies": { "@types/geojson": "*", "@types/mapbox__point-geometry": "*", "@types/pbf": "*" } }, "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg=="], |
"@types/mapbox__vector-tile": ["@types/[email protected]", "", { "dependencies": { "@types/geojson": "*", "@types/mapbox__point-geometry": "*", "@types/pbf": "*" } }, "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg=="], |
||||
|
|
||||
"@types/node": ["@types/node@24.0.14", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-4zXMWD91vBLGRtHK3YbIoFMia+1nqEz72coM42C5ETjnNCa/heoj7NT1G67iAfOqMmcfhuCZ4uNpyz8EjlAejw=="], |
"@types/node": ["@types/node@22.16.4", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-PYRhNtZdm2wH/NT2k/oAJ6/f2VD2N2Dag0lGlx2vWgMSJXGNmlce5MiTQzoWAiIJtso30mjnfQCOKVH+kAQC/g=="], |
||||
|
|
||||
"@types/pbf": ["@types/[email protected]", "", {}, "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA=="], |
"@types/pbf": ["@types/[email protected]", "", {}, "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA=="], |
||||
|
|
||||
@ -795,7 +840,7 @@ |
|||||
|
|
||||
"@types/w3c-web-serial": ["@types/[email protected]", "", {}, "sha512-QQOT+bxQJhRGXoZDZGLs3ksLud1dMNnMiSQtBA0w8KXvLpXX4oM4TZb6J0GgJ8UbCaHo5s9/4VQT8uXy9JER2A=="], |
"@types/w3c-web-serial": ["@types/[email protected]", "", {}, "sha512-QQOT+bxQJhRGXoZDZGLs3ksLud1dMNnMiSQtBA0w8KXvLpXX4oM4TZb6J0GgJ8UbCaHo5s9/4VQT8uXy9JER2A=="], |
||||
|
|
||||
"@types/web-bluetooth": ["@types/[email protected]1", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], |
"@types/web-bluetooth": ["@types/[email protected]0", "", {}, "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="], |
||||
|
|
||||
"@types/whatwg-mimetype": ["@types/[email protected]", "", {}, "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA=="], |
"@types/whatwg-mimetype": ["@types/[email protected]", "", {}, "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA=="], |
||||
|
|
||||
@ -1335,7 +1380,7 @@ |
|||||
|
|
||||
"typewise-core": ["[email protected]", "", {}, "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg=="], |
"typewise-core": ["[email protected]", "", {}, "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg=="], |
||||
|
|
||||
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="], |
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], |
||||
|
|
||||
"union-value": ["[email protected]", "", { "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^2.0.1" } }, "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg=="], |
"union-value": ["[email protected]", "", { "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^2.0.1" } }, "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg=="], |
||||
|
|
||||
@ -1393,6 +1438,12 @@ |
|||||
|
|
||||
"zustand": ["[email protected]", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-ihAqNeUVhe0MAD+X8M5UzqyZ9k3FFZLBTtqo6JLPwV53cbRB/mJwBI0PxcIgqhBBHlEs8G45OTDTMq3gNcLq3A=="], |
"zustand": ["[email protected]", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-ihAqNeUVhe0MAD+X8M5UzqyZ9k3FFZLBTtqo6JLPwV53cbRB/mJwBI0PxcIgqhBBHlEs8G45OTDTMq3gNcLq3A=="], |
||||
|
|
||||
|
"@jsr/meshtastic__core/@bufbuild/protobuf": ["@bufbuild/[email protected]", "", {}, "sha512-6cuonJVNOIL7lTj5zgo/Rc2bKAo4/GvN+rKCrUj7GdEHRzCk8zKOfFwUsL9nAVk5rSIsRmlgcpLzTRysopEeeg=="], |
||||
|
|
||||
|
"@jsr/meshtastic__protobufs/@bufbuild/protobuf": ["@bufbuild/[email protected]", "", {}, "sha512-6cuonJVNOIL7lTj5zgo/Rc2bKAo4/GvN+rKCrUj7GdEHRzCk8zKOfFwUsL9nAVk5rSIsRmlgcpLzTRysopEeeg=="], |
||||
|
|
||||
|
"@meshtastic/protobufs/@bufbuild/protobuf": ["@bufbuild/[email protected]", "", {}, "sha512-6cuonJVNOIL7lTj5zgo/Rc2bKAo4/GvN+rKCrUj7GdEHRzCk8zKOfFwUsL9nAVk5rSIsRmlgcpLzTRysopEeeg=="], |
||||
|
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/[email protected]", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.3", "tslib": "^2.4.0" }, "bundled": true }, "sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g=="], |
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/[email protected]", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.3", "tslib": "^2.4.0" }, "bundled": true }, "sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g=="], |
||||
|
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg=="], |
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg=="], |
||||
@ -1645,7 +1696,15 @@ |
|||||
|
|
||||
"lru-cache/yallist": ["[email protected]", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], |
"lru-cache/yallist": ["[email protected]", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], |
||||
|
|
||||
"meshtastic-web/@biomejs/biome": ["@biomejs/[email protected]", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.0.6", "@biomejs/cli-darwin-x64": "2.0.6", "@biomejs/cli-linux-arm64": "2.0.6", "@biomejs/cli-linux-arm64-musl": "2.0.6", "@biomejs/cli-linux-x64": "2.0.6", "@biomejs/cli-linux-x64-musl": "2.0.6", "@biomejs/cli-win32-arm64": "2.0.6", "@biomejs/cli-win32-x64": "2.0.6" }, "bin": { "biome": "bin/biome" } }, "sha512-RRP+9cdh5qwe2t0gORwXaa27oTOiQRQvrFf49x2PA1tnpsyU7FIHX4ZOFMtBC4QNtyWsN7Dqkf5EDbg4X+9iqA=="], |
"meshtastic-web/@meshtastic/core": ["@jsr/[email protected]", "https://npm.jsr.io/~/11/@jsr/meshtastic__core/2.6.4.tgz", { "dependencies": { "@bufbuild/protobuf": "^2.2.3", "@jsr/meshtastic__protobufs": "^2.6.2", "crc": "^4.3.2", "ste-simple-events": "^3.0.11", "tslog": "^4.9.3" } }, "sha512-1Kz5DK6peFxluHOJR38vFwfgeJzMXTz+3p6TvibjILVhSQC2U1nu8aJbn6w5zhRqS+j79OmtrRvdzL6VNsTkkQ=="], |
||||
|
|
||||
|
"meshtastic-web/@meshtastic/transport-http": ["@jsr/[email protected]", "https://npm.jsr.io/~/11/@jsr/meshtastic__transport-http/0.2.1.tgz", { "dependencies": { "@jsr/meshtastic__core": "^2.6.0" } }, "sha512-lmQKr3aIINKvtGROU4HchmSVqbZSbkIHqajowRRC8IAjsnR0zNTyxz210QyY4pFUF9hpcW3GRjwq5h/VO2JuGg=="], |
||||
|
|
||||
|
"meshtastic-web/@meshtastic/transport-web-bluetooth": ["@jsr/[email protected]", "https://npm.jsr.io/~/11/@jsr/meshtastic__transport-web-bluetooth/0.1.2.tgz", { "dependencies": { "@jsr/meshtastic__core": "^2.6.4" } }, "sha512-Z+5pv9RXNgY0/crKExOH3pZ6LT0HIXFmnBL7NX5AO2knOFRn+4lmxQEhhmiTTlkUfqyEfAvbjuY5u4mq9TPTdQ=="], |
||||
|
|
||||
|
"meshtastic-web/@meshtastic/transport-web-serial": ["@jsr/[email protected]", "https://npm.jsr.io/~/11/@jsr/meshtastic__transport-web-serial/0.2.1.tgz", { "dependencies": { "@jsr/meshtastic__core": "^2.6.0" } }, "sha512-yumjEGLkAuJYOC3aWKvZzbQqi/LnqaKfNpVCY7Ki7oLtAshNiZrBLiwiFhN7+ZR9FfMdJThyBMqREBDRRWTO1Q=="], |
||||
|
|
||||
|
"meshtastic-web/@types/node": ["@types/[email protected]", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-4zXMWD91vBLGRtHK3YbIoFMia+1nqEz72coM42C5ETjnNCa/heoj7NT1G67iAfOqMmcfhuCZ4uNpyz8EjlAejw=="], |
||||
|
|
||||
"peek-stream/through2": ["[email protected]", "", { "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="], |
"peek-stream/through2": ["[email protected]", "", { "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="], |
||||
|
|
||||
@ -1689,23 +1748,9 @@ |
|||||
|
|
||||
"geojson-polygon-self-intersections/rbush/quickselect": ["[email protected]", "", {}, "sha512-qN0Gqdw4c4KGPsBOQafj6yj/PA6c/L63f6CaZ/DCF/xF4Esu3jVmKLUDYxghFx8Kb/O7y9tI7x2RjTSXwdK1iQ=="], |
"geojson-polygon-self-intersections/rbush/quickselect": ["[email protected]", "", {}, "sha512-qN0Gqdw4c4KGPsBOQafj6yj/PA6c/L63f6CaZ/DCF/xF4Esu3jVmKLUDYxghFx8Kb/O7y9tI7x2RjTSXwdK1iQ=="], |
||||
|
|
||||
"happy-dom/@types/node/undici-types": ["[email protected]", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], |
"meshtastic-web/@meshtastic/core/@bufbuild/protobuf": ["@bufbuild/[email protected]", "", {}, "sha512-6cuonJVNOIL7lTj5zgo/Rc2bKAo4/GvN+rKCrUj7GdEHRzCk8zKOfFwUsL9nAVk5rSIsRmlgcpLzTRysopEeeg=="], |
||||
|
|
||||
"meshtastic-web/@biomejs/biome/@biomejs/cli-darwin-arm64": ["@biomejs/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-AzdiNNjNzsE6LfqWyBvcL29uWoIuZUkndu+wwlXW13EKcBHbbKjNQEZIJKYDc6IL+p7bmWGx3v9ZtcRyIoIz5A=="], |
|
||||
|
|
||||
"meshtastic-web/@biomejs/biome/@biomejs/cli-darwin-x64": ["@biomejs/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-wJjjP4E7bO4WJmiQaLnsdXMa516dbtC6542qeRkyJg0MqMXP0fvs4gdsHhZ7p9XWTAmGIjZHFKXdsjBvKGIJJQ=="], |
|
||||
|
|
||||
"meshtastic-web/@biomejs/biome/@biomejs/cli-linux-arm64": ["@biomejs/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZSVf6TYo5rNMUHIW1tww+rs/krol7U5A1Is/yzWyHVZguuB0lBnIodqyFuwCNqG9aJGyk7xIMS8HG0qGUPz0SA=="], |
|
||||
|
|
||||
"meshtastic-web/@biomejs/biome/@biomejs/cli-linux-arm64-musl": ["@biomejs/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-CVPEMlin3bW49sBqLBg2x016Pws7eUXA27XYDFlEtponD0luYjg2zQaMJ2nOqlkKG9fqzzkamdYxHdMDc2gZFw=="], |
|
||||
|
|
||||
"meshtastic-web/@biomejs/biome/@biomejs/cli-linux-x64": ["@biomejs/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-geM1MkHTV1Kh2Cs/Xzot9BOF3WBacihw6bkEmxkz4nSga8B9/hWy5BDiOG3gHDGIBa8WxT0nzsJs2f/hPqQIQw=="], |
|
||||
|
|
||||
"meshtastic-web/@biomejs/biome/@biomejs/cli-linux-x64-musl": ["@biomejs/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-mKHE/e954hR/hSnAcJSjkf4xGqZc/53Kh39HVW1EgO5iFi0JutTN07TSjEMg616julRtfSNJi0KNyxvc30Y4rQ=="], |
|
||||
|
|
||||
"meshtastic-web/@biomejs/biome/@biomejs/cli-win32-arm64": ["@biomejs/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-290V4oSFoKaprKE1zkYVsDfAdn0An5DowZ+GIABgjoq1ndhvNxkJcpxPsiYtT7slbVe3xmlT0ncdfOsN7KruzA=="], |
|
||||
|
|
||||
"meshtastic-web/@biomejs/biome/@biomejs/cli-win32-x64": ["@biomejs/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-bfM1Bce0d69Ao7pjTjUS+AWSZ02+5UHdiAP85Th8e9yV5xzw6JrHXbL5YWlcEKQ84FIZMdDc7ncuti1wd2sdbw=="], |
"meshtastic-web/@types/node/undici-types": ["[email protected]", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="], |
||||
|
|
||||
"peek-stream/through2/readable-stream": ["[email protected]", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], |
"peek-stream/through2/readable-stream": ["[email protected]", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], |
||||
|
|
||||
|
|||||
File diff suppressed because it is too large
@ -1,11 +0,0 @@ |
|||||
{ |
|
||||
"name": "@meshtastic/core", |
|
||||
"version": "2.6.4", |
|
||||
"description": "Core functionalities for Meshtastic web applications.", |
|
||||
"exports": { |
|
||||
".": "./mod.ts" |
|
||||
}, |
|
||||
"imports": { |
|
||||
"crc": "npm:crc@^4.3.2" |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,11 @@ |
|||||
|
{ |
||||
|
"name": "@meshtastic/core", |
||||
|
"version": "2.6.5", |
||||
|
"description": "Core functionalities for Meshtastic web applications.", |
||||
|
"exports": { |
||||
|
".": "./mod.ts" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"crc": "npm:crc@^4.3.2" |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
@ -1,71 +1,71 @@ |
|||||
import type { DeviceOutput } from "../../types.ts"; |
import type { DeviceOutput } from "../../types.ts"; |
||||
|
|
||||
export const fromDeviceStream: () => TransformStream<Uint8Array, DeviceOutput> = |
export const fromDeviceStream: () => TransformStream<Uint8Array, DeviceOutput> = |
||||
( |
( |
||||
// onReleaseEvent: SimpleEventDispatcher<boolean>,
|
// onReleaseEvent: SimpleEventDispatcher<boolean>,
|
||||
) => { |
) => { |
||||
let byteBuffer = new Uint8Array([]); |
let byteBuffer = new Uint8Array([]); |
||||
const textDecoder = new TextDecoder(); |
const textDecoder = new TextDecoder(); |
||||
return new TransformStream<Uint8Array, DeviceOutput>({ |
return new TransformStream<Uint8Array, DeviceOutput>({ |
||||
transform(chunk: Uint8Array, controller): void { |
transform(chunk: Uint8Array, controller): void { |
||||
// onReleaseEvent.subscribe(() => {
|
// onReleaseEvent.subscribe(() => {
|
||||
// controller.terminate();
|
// controller.terminate();
|
||||
// });
|
// });
|
||||
byteBuffer = new Uint8Array([...byteBuffer, ...chunk]); |
byteBuffer = new Uint8Array([...byteBuffer, ...chunk]); |
||||
let processingExhausted = false; |
let processingExhausted = false; |
||||
while (byteBuffer.length !== 0 && !processingExhausted) { |
while (byteBuffer.length !== 0 && !processingExhausted) { |
||||
const framingIndex = byteBuffer.findIndex((byte) => byte === 0x94); |
const framingIndex = byteBuffer.findIndex((byte) => byte === 0x94); |
||||
const framingByte2 = byteBuffer[framingIndex + 1]; |
const framingByte2 = byteBuffer[framingIndex + 1]; |
||||
if (framingByte2 === 0xc3) { |
if (framingByte2 === 0xc3) { |
||||
if (byteBuffer.subarray(0, framingIndex).length) { |
if (byteBuffer.subarray(0, framingIndex).length) { |
||||
controller.enqueue({ |
controller.enqueue({ |
||||
type: "debug", |
type: "debug", |
||||
data: textDecoder.decode(byteBuffer.subarray(0, framingIndex)), |
data: textDecoder.decode(byteBuffer.subarray(0, framingIndex)), |
||||
}); |
}); |
||||
byteBuffer = byteBuffer.subarray(framingIndex); |
byteBuffer = byteBuffer.subarray(framingIndex); |
||||
} |
} |
||||
|
|
||||
const msb = byteBuffer[2]; |
const msb = byteBuffer[2]; |
||||
const lsb = byteBuffer[3]; |
const lsb = byteBuffer[3]; |
||||
|
|
||||
if ( |
if ( |
||||
msb !== undefined && |
msb !== undefined && |
||||
lsb !== undefined && |
lsb !== undefined && |
||||
byteBuffer.length >= 4 + (msb << 8) + lsb |
byteBuffer.length >= 4 + (msb << 8) + lsb |
||||
) { |
) { |
||||
const packet = byteBuffer.subarray(4, 4 + (msb << 8) + lsb); |
const packet = byteBuffer.subarray(4, 4 + (msb << 8) + lsb); |
||||
|
|
||||
const malformedDetectorIndex = packet.findIndex( |
const malformedDetectorIndex = packet.findIndex( |
||||
(byte) => byte === 0x94, |
(byte) => byte === 0x94, |
||||
); |
); |
||||
if ( |
if ( |
||||
malformedDetectorIndex !== -1 && |
malformedDetectorIndex !== -1 && |
||||
packet[malformedDetectorIndex + 1] === 0xc3 |
packet[malformedDetectorIndex + 1] === 0xc3 |
||||
) { |
) { |
||||
console.warn( |
console.warn( |
||||
`⚠️ Malformed packet found, discarding: ${byteBuffer |
`⚠️ Malformed packet found, discarding: ${byteBuffer |
||||
.subarray(0, malformedDetectorIndex - 1) |
.subarray(0, malformedDetectorIndex - 1) |
||||
.toString()}`,
|
.toString()}`,
|
||||
); |
); |
||||
|
|
||||
byteBuffer = byteBuffer.subarray(malformedDetectorIndex); |
byteBuffer = byteBuffer.subarray(malformedDetectorIndex); |
||||
} else { |
} else { |
||||
byteBuffer = byteBuffer.subarray(3 + (msb << 8) + lsb + 1); |
byteBuffer = byteBuffer.subarray(3 + (msb << 8) + lsb + 1); |
||||
|
|
||||
controller.enqueue({ |
controller.enqueue({ |
||||
type: "packet", |
type: "packet", |
||||
data: packet, |
data: packet, |
||||
}); |
}); |
||||
} |
} |
||||
} else { |
} else { |
||||
/** Only partioal message in buffer, wait for the rest */ |
/** Only partioal message in buffer, wait for the rest */ |
||||
processingExhausted = true; |
processingExhausted = true; |
||||
} |
} |
||||
} else { |
} else { |
||||
/** Message not complete, only 1 byte in buffer */ |
/** Message not complete, only 1 byte in buffer */ |
||||
processingExhausted = true; |
processingExhausted = true; |
||||
} |
} |
||||
} |
} |
||||
}, |
}, |
||||
}); |
}); |
||||
}; |
}; |
||||
|
|||||
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"name": "@meshtastic/transport-http", |
||||
|
"version": "0.2.2", |
||||
|
"exports": "./mod.ts" |
||||
|
} |
||||
@ -1,8 +1,9 @@ |
|||||
{ |
{ |
||||
"name": "@meshtastic/transport-http", |
"name": "@meshtastic/transport-http", |
||||
"version": "0.2.1", |
"version": "0.2.2", |
||||
"description": "A transport layer for Meshtastic applications using HTTP.", |
"description": "A transport layer for Meshtastic applications using HTTP.", |
||||
"exports": { |
"exports": {".": "./mod.ts"}, |
||||
".": "./mod.ts" |
"tasks": { |
||||
|
"build": "deno build" |
||||
} |
} |
||||
} |
} |
||||
@ -1,89 +1,89 @@ |
|||||
import type { Types } from "@meshtastic/core"; |
import type { Types } from "@meshtastic/core"; |
||||
|
|
||||
export class TransportHTTP implements Types.Transport { |
export class TransportHTTP implements Types.Transport { |
||||
private _toDevice: WritableStream<Uint8Array>; |
private _toDevice: WritableStream<Uint8Array>; |
||||
private _fromDevice: ReadableStream<Types.DeviceOutput>; |
private _fromDevice: ReadableStream<Types.DeviceOutput>; |
||||
private url: string; |
private url: string; |
||||
private receiveBatchRequests: boolean; |
private receiveBatchRequests: boolean; |
||||
private fetchInterval: number; |
private fetchInterval: number; |
||||
|
|
||||
public static async create( |
public static async create( |
||||
address: string, |
address: string, |
||||
tls?: boolean, |
tls?: boolean, |
||||
): Promise<TransportHTTP> { |
): Promise<TransportHTTP> { |
||||
const connectionUrl = `${tls ? "https" : "http"}://${address}`; |
const connectionUrl = `${tls ? "https" : "http"}://${address}`; |
||||
await fetch(`${connectionUrl}/json/report`); |
await fetch(`${connectionUrl}/json/report`); |
||||
await Promise.resolve(); |
await Promise.resolve(); |
||||
return new TransportHTTP(connectionUrl); |
return new TransportHTTP(connectionUrl); |
||||
} |
} |
||||
|
|
||||
constructor(url: string) { |
constructor(url: string) { |
||||
this.url = url; |
this.url = url; |
||||
this.receiveBatchRequests = false; |
this.receiveBatchRequests = false; |
||||
this.fetchInterval = 3000; |
this.fetchInterval = 3000; |
||||
|
|
||||
this._toDevice = new WritableStream<Uint8Array>({ |
this._toDevice = new WritableStream<Uint8Array>({ |
||||
write: async (chunk) => { |
write: async (chunk) => { |
||||
await this.writeToRadio(chunk); |
await this.writeToRadio(chunk); |
||||
}, |
}, |
||||
}); |
}); |
||||
|
|
||||
let controller: ReadableStreamDefaultController<Types.DeviceOutput>; |
let controller: ReadableStreamDefaultController<Types.DeviceOutput>; |
||||
|
|
||||
this._fromDevice = new ReadableStream<Types.DeviceOutput>({ |
this._fromDevice = new ReadableStream<Types.DeviceOutput>({ |
||||
start: (ctrl) => { |
start: (ctrl) => { |
||||
controller = ctrl; |
controller = ctrl; |
||||
}, |
}, |
||||
}); |
}); |
||||
|
|
||||
setInterval(async () => { |
setInterval(async () => { |
||||
await this.readFromRadio(controller); |
await this.readFromRadio(controller); |
||||
}, this.fetchInterval); |
}, this.fetchInterval); |
||||
} |
} |
||||
|
|
||||
private async readFromRadio( |
private async readFromRadio( |
||||
controller: ReadableStreamDefaultController<Types.DeviceOutput>, |
controller: ReadableStreamDefaultController<Types.DeviceOutput>, |
||||
): Promise<void> { |
): Promise<void> { |
||||
let readBuffer = new ArrayBuffer(1); |
let readBuffer = new ArrayBuffer(1); |
||||
while (readBuffer.byteLength > 0) { |
while (readBuffer.byteLength > 0) { |
||||
const response = await fetch( |
const response = await fetch( |
||||
`${this.url}/api/v1/fromradio?all=${ |
`${this.url}/api/v1/fromradio?all=${ |
||||
this.receiveBatchRequests ? "true" : "false" |
this.receiveBatchRequests ? "true" : "false" |
||||
}`,
|
}`,
|
||||
{ |
{ |
||||
method: "GET", |
method: "GET", |
||||
headers: { |
headers: { |
||||
Accept: "application/x-protobuf", |
Accept: "application/x-protobuf", |
||||
}, |
}, |
||||
}, |
}, |
||||
); |
); |
||||
|
|
||||
readBuffer = await response.arrayBuffer(); |
readBuffer = await response.arrayBuffer(); |
||||
|
|
||||
if (readBuffer.byteLength > 0) { |
if (readBuffer.byteLength > 0) { |
||||
controller.enqueue({ |
controller.enqueue({ |
||||
type: "packet", |
type: "packet", |
||||
data: new Uint8Array(readBuffer), |
data: new Uint8Array(readBuffer), |
||||
}); |
}); |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
private async writeToRadio(data: Uint8Array): Promise<void> { |
private async writeToRadio(data: Uint8Array): Promise<void> { |
||||
await fetch(`${this.url}/api/v1/toradio`, { |
await fetch(`${this.url}/api/v1/toradio`, { |
||||
method: "PUT", |
method: "PUT", |
||||
headers: { |
headers: { |
||||
"Content-Type": "application/x-protobuf", |
"Content-Type": "application/x-protobuf", |
||||
}, |
}, |
||||
body: data, |
body: data, |
||||
}); |
}); |
||||
} |
} |
||||
|
|
||||
get toDevice(): WritableStream<Uint8Array> { |
get toDevice(): WritableStream<Uint8Array> { |
||||
return this._toDevice; |
return this._toDevice; |
||||
} |
} |
||||
|
|
||||
get fromDevice(): ReadableStream<Types.DeviceOutput> { |
get fromDevice(): ReadableStream<Types.DeviceOutput> { |
||||
return this._fromDevice; |
return this._fromDevice; |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"name": "@meshtastic/transport-web-bluetooth", |
||||
|
"version": "0.1.3", |
||||
|
"exports": "./mod.ts" |
||||
|
} |
||||
@ -1,14 +1,14 @@ |
|||||
{ |
{ |
||||
"name": "@meshtastic/transport-web-bluetooth", |
"name": "@meshtastic/transport-web-bluetooth", |
||||
"version": "0.1.2", |
"version": "0.1.3", |
||||
"description": "A transport layer for Meshtastic applications using Web Bluetooth.", |
"description": "A transport layer for Meshtastic applications using Web Bluetooth.", |
||||
"exports": { |
"exports": { |
||||
".": "./mod.ts" |
".": "./mod.ts" |
||||
}, |
}, |
||||
"imports": { |
"devDependencies": { |
||||
"@types/web-bluetooth": "npm:@types/web-bluetooth@^0.0.20" |
"@types/web-bluetooth": "npm:@types/web-bluetooth@^0.0.20" |
||||
}, |
}, |
||||
"compilerOptions": { |
"compilerOptions": { |
||||
"types": ["@types/web-bluetooth"] |
"types": ["@types/web-bluetooth"] |
||||
} |
} |
||||
} |
} |
||||
@ -1,133 +1,135 @@ |
|||||
import type { Types } from "@meshtastic/core"; |
import type { Types } from "@meshtastic/core"; |
||||
|
|
||||
export class TransportWebBluetooth implements Types.Transport { |
export class TransportWebBluetooth implements Types.Transport { |
||||
private _toDevice: WritableStream<Uint8Array>; |
private _toDevice: WritableStream<Uint8Array>; |
||||
private _fromDevice: ReadableStream<Types.DeviceOutput>; |
private _fromDevice: ReadableStream<Types.DeviceOutput>; |
||||
private _fromDeviceController?: ReadableStreamDefaultController<Types.DeviceOutput>; |
private _fromDeviceController?: ReadableStreamDefaultController<Types.DeviceOutput>; |
||||
private _isFirstWrite = true; |
private _isFirstWrite = true; |
||||
|
|
||||
private toRadioCharacteristic: BluetoothRemoteGATTCharacteristic; |
private toRadioCharacteristic: BluetoothRemoteGATTCharacteristic; |
||||
private fromRadioCharacteristic: BluetoothRemoteGATTCharacteristic; |
private fromRadioCharacteristic: BluetoothRemoteGATTCharacteristic; |
||||
private fromNumCharacteristic: BluetoothRemoteGATTCharacteristic; |
private fromNumCharacteristic: BluetoothRemoteGATTCharacteristic; |
||||
|
|
||||
static ToRadioUuid = "f75c76d2-129e-4dad-a1dd-7866124401e7"; |
static ToRadioUuid = "f75c76d2-129e-4dad-a1dd-7866124401e7"; |
||||
static FromRadioUuid = "2c55e69e-4993-11ed-b878-0242ac120002"; |
static FromRadioUuid = "2c55e69e-4993-11ed-b878-0242ac120002"; |
||||
static FromNumUuid = "ed9da18c-a800-4f66-a670-aa7547e34453"; |
static FromNumUuid = "ed9da18c-a800-4f66-a670-aa7547e34453"; |
||||
static ServiceUuid = "6ba1b218-15a8-461f-9fa8-5dcae273eafd"; |
static ServiceUuid = "6ba1b218-15a8-461f-9fa8-5dcae273eafd"; |
||||
|
|
||||
public static async create(): Promise<TransportWebBluetooth> { |
public static async create(): Promise<TransportWebBluetooth> { |
||||
const device = await navigator.bluetooth.requestDevice({ |
const device = await navigator.bluetooth.requestDevice({ |
||||
filters: [{ services: [this.ServiceUuid] }], |
filters: [{ services: [TransportWebBluetooth.ServiceUuid] }], |
||||
}); |
}); |
||||
return await this.prepareConnection(device); |
return await TransportWebBluetooth.prepareConnection(device); |
||||
} |
} |
||||
|
|
||||
public static async createFromDevice( |
public static async createFromDevice( |
||||
device: BluetoothDevice, |
device: BluetoothDevice, |
||||
): Promise<TransportWebBluetooth> { |
): Promise<TransportWebBluetooth> { |
||||
return await this.prepareConnection(device); |
return await TransportWebBluetooth.prepareConnection(device); |
||||
} |
} |
||||
|
|
||||
public static async prepareConnection( |
public static async prepareConnection( |
||||
device: BluetoothDevice, |
device: BluetoothDevice, |
||||
): Promise<TransportWebBluetooth> { |
): Promise<TransportWebBluetooth> { |
||||
const gattServer = await device.gatt?.connect(); |
const gattServer = await device.gatt?.connect(); |
||||
|
|
||||
if (!gattServer) { |
if (!gattServer) { |
||||
throw new Error("Failed to connect to GATT server"); |
throw new Error("Failed to connect to GATT server"); |
||||
} |
} |
||||
|
|
||||
const service = await gattServer.getPrimaryService(this.ServiceUuid); |
const service = await gattServer.getPrimaryService( |
||||
|
TransportWebBluetooth.ServiceUuid, |
||||
const toRadioCharacteristic = await service.getCharacteristic( |
); |
||||
this.ToRadioUuid, |
|
||||
); |
const toRadioCharacteristic = await service.getCharacteristic( |
||||
const fromRadioCharacteristic = await service.getCharacteristic( |
TransportWebBluetooth.ToRadioUuid, |
||||
this.FromRadioUuid, |
); |
||||
); |
const fromRadioCharacteristic = await service.getCharacteristic( |
||||
const fromNumCharacteristic = await service.getCharacteristic( |
TransportWebBluetooth.FromRadioUuid, |
||||
this.FromNumUuid, |
); |
||||
); |
const fromNumCharacteristic = await service.getCharacteristic( |
||||
|
TransportWebBluetooth.FromNumUuid, |
||||
if ( |
); |
||||
!toRadioCharacteristic || |
|
||||
!fromRadioCharacteristic || |
if ( |
||||
!fromNumCharacteristic |
!toRadioCharacteristic || |
||||
) { |
!fromRadioCharacteristic || |
||||
throw new Error("Failed to find required characteristics"); |
!fromNumCharacteristic |
||||
} |
) { |
||||
|
throw new Error("Failed to find required characteristics"); |
||||
console.log("Connected to device", device.name); |
} |
||||
|
|
||||
return new TransportWebBluetooth( |
console.log("Connected to device", device.name); |
||||
toRadioCharacteristic, |
|
||||
fromRadioCharacteristic, |
return new TransportWebBluetooth( |
||||
fromNumCharacteristic, |
toRadioCharacteristic, |
||||
); |
fromRadioCharacteristic, |
||||
} |
fromNumCharacteristic, |
||||
|
); |
||||
constructor( |
} |
||||
toRadioCharacteristic: BluetoothRemoteGATTCharacteristic, |
|
||||
fromRadioCharacteristic: BluetoothRemoteGATTCharacteristic, |
constructor( |
||||
fromNumCharacteristic: BluetoothRemoteGATTCharacteristic, |
toRadioCharacteristic: BluetoothRemoteGATTCharacteristic, |
||||
) { |
fromRadioCharacteristic: BluetoothRemoteGATTCharacteristic, |
||||
this.toRadioCharacteristic = toRadioCharacteristic; |
fromNumCharacteristic: BluetoothRemoteGATTCharacteristic, |
||||
this.fromRadioCharacteristic = fromRadioCharacteristic; |
) { |
||||
this.fromNumCharacteristic = fromNumCharacteristic; |
this.toRadioCharacteristic = toRadioCharacteristic; |
||||
|
this.fromRadioCharacteristic = fromRadioCharacteristic; |
||||
this._fromDevice = new ReadableStream({ |
this.fromNumCharacteristic = fromNumCharacteristic; |
||||
start: (ctrl) => { |
|
||||
this._fromDeviceController = ctrl; |
this._fromDevice = new ReadableStream({ |
||||
}, |
start: (ctrl) => { |
||||
}); |
this._fromDeviceController = ctrl; |
||||
|
}, |
||||
this._toDevice = new WritableStream({ |
}); |
||||
write: async (chunk) => { |
|
||||
await this.toRadioCharacteristic.writeValue(chunk); |
this._toDevice = new WritableStream({ |
||||
|
write: async (chunk) => { |
||||
if (this._isFirstWrite && this._fromDeviceController) { |
await this.toRadioCharacteristic.writeValue(chunk); |
||||
this._isFirstWrite = false; |
|
||||
setTimeout(() => { |
if (this._isFirstWrite && this._fromDeviceController) { |
||||
this.readFromRadio(this._fromDeviceController!); |
this._isFirstWrite = false; |
||||
}, 50); |
setTimeout(() => { |
||||
} |
this.readFromRadio(this._fromDeviceController!); |
||||
}, |
}, 50); |
||||
}); |
} |
||||
|
}, |
||||
this.fromNumCharacteristic.addEventListener( |
}); |
||||
"characteristicvaluechanged", |
|
||||
() => { |
this.fromNumCharacteristic.addEventListener( |
||||
if (this._fromDeviceController) { |
"characteristicvaluechanged", |
||||
this.readFromRadio(this._fromDeviceController); |
() => { |
||||
} |
if (this._fromDeviceController) { |
||||
}, |
this.readFromRadio(this._fromDeviceController); |
||||
); |
} |
||||
|
}, |
||||
this.fromNumCharacteristic.startNotifications(); |
); |
||||
} |
|
||||
|
this.fromNumCharacteristic.startNotifications(); |
||||
get toDevice(): WritableStream<Uint8Array> { |
} |
||||
return this._toDevice; |
|
||||
} |
get toDevice(): WritableStream<Uint8Array> { |
||||
|
return this._toDevice; |
||||
get fromDevice(): ReadableStream<Types.DeviceOutput> { |
} |
||||
return this._fromDevice; |
|
||||
} |
get fromDevice(): ReadableStream<Types.DeviceOutput> { |
||||
|
return this._fromDevice; |
||||
protected async readFromRadio( |
} |
||||
controller: ReadableStreamDefaultController<Types.DeviceOutput>, |
|
||||
): Promise<void> { |
protected async readFromRadio( |
||||
let hasMoreData = true; |
controller: ReadableStreamDefaultController<Types.DeviceOutput>, |
||||
while (hasMoreData && this.fromRadioCharacteristic) { |
): Promise<void> { |
||||
const value = await this.fromRadioCharacteristic.readValue(); |
let hasMoreData = true; |
||||
if (value.byteLength === 0) { |
while (hasMoreData && this.fromRadioCharacteristic) { |
||||
hasMoreData = false; |
const value = await this.fromRadioCharacteristic.readValue(); |
||||
continue; |
if (value.byteLength === 0) { |
||||
} |
hasMoreData = false; |
||||
controller.enqueue({ |
continue; |
||||
type: "packet", |
} |
||||
data: new Uint8Array(value.buffer), |
controller.enqueue({ |
||||
}); |
type: "packet", |
||||
} |
data: new Uint8Array(value.buffer), |
||||
} |
}); |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
|
|||||
@ -1,14 +0,0 @@ |
|||||
{ |
|
||||
"name": "@meshtastic/transport-web-serial", |
|
||||
"version": "0.2.1", |
|
||||
"description": "A transport layer for Meshtastic applications using Web Serial API.", |
|
||||
"exports": { |
|
||||
".": "./mod.ts" |
|
||||
}, |
|
||||
"imports": { |
|
||||
"@types/w3c-web-serial": "npm:@types/w3c-web-serial@^1.0.7" |
|
||||
}, |
|
||||
"compilerOptions": { |
|
||||
"types": ["@types/w3c-web-serial"] |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"name": "@meshtastic/transport-web-serial", |
||||
|
"version": "0.2.2", |
||||
|
"exports": "./mod.ts" |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
{ |
||||
|
"name": "@meshtastic/transport-web-serial", |
||||
|
"version": "0.2.2", |
||||
|
"description": "A transport layer for Meshtastic applications using Web Serial API.", |
||||
|
"exports": { |
||||
|
".": "./mod.ts" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"@types/w3c-web-serial": "npm:@types/w3c-web-serial@^1.0.7" |
||||
|
}, |
||||
|
"compilerOptions": { |
||||
|
"types": ["@types/w3c-web-serial"] |
||||
|
} |
||||
|
} |
||||
@ -1,11 +1,11 @@ |
|||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||
|
|
||||
interface ImportMetaEnv { |
interface ImportMetaEnv { |
||||
readonly env: { |
readonly env: { |
||||
readonly VITE_COMMIT_HASH: string; |
readonly VITE_COMMIT_HASH: string; |
||||
}; |
}; |
||||
} |
} |
||||
|
|
||||
interface ImportMeta { |
interface ImportMeta { |
||||
readonly env: ImportMetaEnv; |
readonly env: ImportMetaEnv; |
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue