- Create docs/architecture/event-targets/ with individual specs: in-process, redis, websocket-client, websocket-server, worker, iroh-spoke, iroh-hub - Update event-targets.md to serve as index with topology model (symmetric vs fan-out) and adapter status table - Update architecture.md index to reference new directory
2.9 KiB
2.9 KiB
status, last_updated
| status | last_updated |
|---|---|
| draft | 2026-05-07 |
Iroh Hub Event Target
Import: @alkdev/pubsub/event-target-iroh-hub
Peer dep: @rayhanadev/iroh (optional, NAPI-RS native addon)
Status: Not yet implemented. Needs R&D on binding stability, NAPI under Deno.
P2P QUIC event target for the hub (server) side. The hub accepts incoming connections and bidirectional streams. Manages multiple connected spokes.
createIrohHubEventTarget
async function createIrohHubEventTarget<TEvent extends TypedEvent>(
args: CreateIrohHubEventTargetArgs,
): Promise<TypedEventTarget<TEvent>>;
CreateIrohHubEventTargetArgs
| Field | Type | Required | Description |
|---|---|---|---|
endpoint |
Endpoint |
Yes | iroh endpoint (created with Endpoint.create()) |
alpn |
string |
No | Application-layer protocol. Default: "alkpubsub/1" |
How It Works
Similar to the WebSocket server adapter, the Iroh hub adapter manages multiple connections:
dispatchEvent→ writes JSON envelope to all connected spokes'SendStreamsaddEventListener→ registers local listeners for events from any spoke- On incoming connection →
endpoint.accept()→connection.acceptBi()→ new spoke tracked
Each spoke gets its own read loop that parses length-prefixed JSON messages from RecvStream and dispatches locally.
Connection Lifecycle
- Hub creates
Endpointand starts accepting - Spoke connects → hub gets
Connectionfromendpoint.accept() - Hub accepts stream →
connection.acceptBi()→SendStream+RecvStream - Hub creates per-spoke read loop
- On disconnect →
RecvStream.readExact()throws → remove spoke from set - Hub continues accepting new connections
Fan-Out
dispatchEvent(event) {
const message = encodeEnvelope(event.detail);
for (const spoke of this.spokes) {
spoke.sendStream.writeAll(message);
}
return true;
}
Key Properties
- Multi-connection — manages a set of connected spokes
- Fan-out — dispatchEvent sends to all connected spokes
- Accepts incoming — endpoint.accept() loop runs continuously
- Cryptographic identity — each spoke verified by Ed25519 NodeId
R&D Needed
- Binding stability — same as spoke adapter.
@rayhanadev/irohneeds testing. - Concurrent accept — can
endpoint.accept()handle multiple simultaneous connections? - Stream vs. Connection per spoke — current design: one bidirectional stream per spoke on a single connection. Alternative: one connection per spoke. Need to benchmark which is better for the expected workload.
- 1:N fan-out — for hub to N spokes, each spoke gets its own stream. For true broadcast,
iroh-gossipwould be better (not yet available in TS). - Connection rejection — how to reject connections from unknown
NodeIds.
See ../iroh-transport.md for full protocol details, identity, and comparison with WebSocket.