first commit
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
# HostBackboneTransport
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
Cross-mesh transport for Tier 0 ↔ Tier 0 traffic. Runs over an injected `BackboneWire` (WebSocket, RTCDataChannel, libp2p, anything) and adds the `CrossMeshEnvelope` encode/decode plus a single-handler `onMessage` subscriber that the relay manager hooks into. Decoupling the wire from the envelope shape means a swap from WebSocket to QUIC doesn't touch the manager.
|
||||
|
||||
## Features
|
||||
|
||||
- Pluggable `BackboneWire` interface (`open` / `close` / `write` / `onPayload` / `isConnected`).
|
||||
- Pluggable serializer; default uses JSON over UTF-8 bytes.
|
||||
- `start()` wires the wire's `onPayload` into the local handler set; `stop()` unwires it.
|
||||
- `send` throws `BACKBONE_DISCONNECTED` when the wire reports the host isn't connected.
|
||||
- `onMessage(handler)` returns an unsubscribe function so subscribers don't leak.
|
||||
- `isConnected(hostId)` exposed for observability.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
type BackboneWire,
|
||||
HostBackboneTransport,
|
||||
} from "@suaveplan/network-plugin-relay";
|
||||
|
||||
declare const wire: BackboneWire;
|
||||
|
||||
const backbone = new HostBackboneTransport({ wire });
|
||||
backbone.start();
|
||||
|
||||
await backbone.connect("host-X", "wss://x");
|
||||
await backbone.send("host-X", envelope);
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
HostBackboneTransport,
|
||||
RELAY_CODES,
|
||||
RelayError,
|
||||
} from "@suaveplan/network-plugin-relay";
|
||||
|
||||
const backbone = new HostBackboneTransport({
|
||||
wire,
|
||||
serializer: {
|
||||
encode: (env) => msgpack.encode(env),
|
||||
decode: (b) => msgpack.decode(b) as never,
|
||||
},
|
||||
});
|
||||
backbone.start();
|
||||
|
||||
backbone.onMessage(async (env, fromHostId) => {
|
||||
await manager.deliverInbound(env, fromHostId);
|
||||
});
|
||||
|
||||
try {
|
||||
await backbone.send("host-X", envelope);
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof RelayError &&
|
||||
err.code === RELAY_CODES.BACKBONE_DISCONNECTED
|
||||
) {
|
||||
await backbone.connect("host-X", "wss://x");
|
||||
await backbone.send("host-X", envelope);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `interface BackboneWire { open, close, write, onPayload, isConnected }`.
|
||||
- `interface HostBackboneTransportConfig { wire, serializer? }`.
|
||||
- `start()` / `stop()` — bind / unbind the inbound payload subscriber.
|
||||
- `connect(hostId, address)` / `disconnect(hostId)`.
|
||||
- `send(hostId, envelope): Promise<void>` — throws `BACKBONE_DISCONNECTED` if the wire is not open.
|
||||
- `onMessage(handler) → () => void`.
|
||||
- `isConnected(hostId): boolean`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Inbound handlers are dispatched eagerly with `void h(...)` so an async handler that throws does not block subsequent handlers — this matches the observer-not-subscriber semantics other transports in the network suite use. Encoding via JSON is the default because it's debuggable and small enough for federation traffic; consumers that need binary framing should pass a custom `serializer`. The `onPayload` callback is captured and the unsubscribe stored in `offWire` so `stop()` can reverse the wiring cleanly without leaking listeners on the underlying wire.
|
||||
Reference in New Issue
Block a user