Browse Source
* feat: add node transport * updated readme * Update packages/transport-node/README.md Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>pull/705/head
committed by
GitHub
6 changed files with 117 additions and 1 deletions
@ -0,0 +1,28 @@ |
|||||
|
# @meshtastic/transport-node |
||||
|
|
||||
|
[](https://jsr.io/@meshtastic/transport-node) |
||||
|
[](https://github.com/meshtastic/js/actions/workflows/ci.yml) |
||||
|
[](https://cla-assistant.io/meshtastic/meshtastic.js) |
||||
|
[](https://opencollective.com/meshtastic/) |
||||
|
[](https://vercel.com?utm_source=meshtastic&utm_campaign=oss) |
||||
|
|
||||
|
## Overview |
||||
|
|
||||
|
`@meshtastic/transport-node` Provides TCP transport (Node) for Meshtastic |
||||
|
devices. Installation instructions are available at |
||||
|
[JSR](https://jsr.io/@meshtastic/transport-node) |
||||
|
[NPM](https://www.npmjs.com/package/@meshtastic/transport-node) |
||||
|
|
||||
|
## Usage |
||||
|
|
||||
|
```ts |
||||
|
import { MeshDevice } from "@meshtastic/core"; |
||||
|
import { TransportNode } from "@meshtastic/transport-node"; |
||||
|
|
||||
|
const transport = await TransportNode.create("10.10.0.57"); |
||||
|
const device = new MeshDevice(transport); |
||||
|
``` |
||||
|
|
||||
|
## Stats |
||||
|
|
||||
|
 |
||||
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"name": "@meshtastic/transport-node", |
||||
|
"version": "0.0.1", |
||||
|
"description": "NodeJS-specific transport layer for Meshtastic web applications.", |
||||
|
"exports": { |
||||
|
".": "./mod.ts" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1 @@ |
|||||
|
export { TransportNode } from "./src/transport.ts"; |
||||
@ -0,0 +1,77 @@ |
|||||
|
import { Utils } from "@meshtastic/core"; |
||||
|
import type { Types } from "@meshtastic/core"; |
||||
|
import { Socket } from "node:net"; |
||||
|
import { Readable, Writable } from "node:stream"; |
||||
|
|
||||
|
export class TransportNode implements Types.Transport { |
||||
|
private readonly _toDevice: WritableStream<Uint8Array>; |
||||
|
private readonly _fromDevice: ReadableStream<Types.DeviceOutput>; |
||||
|
|
||||
|
/** |
||||
|
* Creates and connects a new TransportNode instance. |
||||
|
* @param hostname - The IP address or hostname of the Meshtastic device. |
||||
|
* @param port - The port number for the TCP connection (defaults to 4403). |
||||
|
* @returns A promise that resolves with a connected TransportNode instance. |
||||
|
*/ |
||||
|
public static create(hostname: string, port = 4403): Promise<TransportNode> { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
const socket = new Socket(); |
||||
|
|
||||
|
const onError = (err: Error) => { |
||||
|
socket.destroy(); |
||||
|
reject(err); |
||||
|
}; |
||||
|
|
||||
|
socket.once("error", onError); |
||||
|
|
||||
|
socket.connect(port, hostname, () => { |
||||
|
socket.removeListener("error", onError); |
||||
|
resolve(new TransportNode(socket)); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Constructs a new TransportNode. |
||||
|
* @param connection - An active Node.js net.Socket connection. |
||||
|
*/ |
||||
|
constructor(connection: Socket) { |
||||
|
connection.on("error", (err) => { |
||||
|
console.error("Socket connection error:", err); |
||||
|
}); |
||||
|
|
||||
|
const fromDeviceSource = Readable.toWeb(connection) as ReadableStream< |
||||
|
Uint8Array |
||||
|
>; |
||||
|
this._fromDevice = fromDeviceSource.pipeThrough(Utils.fromDeviceStream()); |
||||
|
|
||||
|
// Stream for data going FROM the application TO the Meshtastic device.
|
||||
|
const toDeviceTransform = new TransformStream<Uint8Array, Uint8Array>(); |
||||
|
this._toDevice = toDeviceTransform.writable; |
||||
|
|
||||
|
// The readable end of the transform is then piped to the Node.js socket.
|
||||
|
// A similar assertion is needed here because `Writable.toWeb` also returns
|
||||
|
// a generically typed stream (`WritableStream<any>`).
|
||||
|
toDeviceTransform.readable.pipeTo( |
||||
|
Writable.toWeb(connection) as WritableStream<Uint8Array>, |
||||
|
) |
||||
|
.catch((err) => { |
||||
|
console.error("Error piping data to socket:", err); |
||||
|
connection.destroy(err as Error); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* The WritableStream to send data to the Meshtastic device. |
||||
|
*/ |
||||
|
public get toDevice(): WritableStream<Uint8Array> { |
||||
|
return this._toDevice; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* The ReadableStream to receive data from the Meshtastic device. |
||||
|
*/ |
||||
|
public get fromDevice(): ReadableStream<Types.DeviceOutput> { |
||||
|
return this._fromDevice; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue