13 KiB
@suaveplan/react-network-libp2p-demo - React-tier demo UI for @suaveplan/network-transport-libp2p. Decomposed into per-concern subcomponents (status, controls, peer interaction, peer lists, log panel) each renderable standalone for Storybook isolation. Bootstrap list is a required React prop — no hardcoded public defaults.
Summary
React-tier demo UI for @suaveplan/network-transport-libp2p. Splits the
upstream 749-LOC monolithic demo into per-concern subcomponents
(<NodeStatusPanel>, <NodeControls>, <PeerInteractionPanel>,
<PeerList>, <LogPanel>) wired together by a root <Libp2pDemo>
composer. Every subcomponent is standalone-renderable with mock data for
Storybook isolation; the lifecycle + state machine lives in the
useLibp2pDemo hook.
Documentation tree
- libp2p-demo — (no submodules)
- libp2p-demo — (no submodules)
- log-panel — (no submodules)
- log-panel — (no submodules)
- node-controls — (no submodules)
- node-controls — (no submodules)
- node-status-panel — (no submodules)
- node-status-panel — (no submodules)
- peer-interaction-panel — (no submodules)
- peer-interaction-panel — (no submodules)
- peer-list — (no submodules)
- peer-list — (no submodules)
- errors — (no submodules)
- errors — (no submodules)
- use-libp2p-demo — (no submodules) - wire-peer-events — Side-effect helper that subscrib…
- use-libp2p-demo — (no submodules) - wire-peer-events — Side-effect helper that subscrib…
- wire-peer-events — Side-effect helper that subscribes to a
Libp2pDemoNode's three peer events (peer:discovery,peer:connect, `peer:d…
- use-libp2p-demo — (no submodules)- wire-peer-events — Side-effect helper that subscrib…
- wire-peer-events — Side-effect helper that subscribes to a
Libp2pDemoNode's three peer events (peer:discovery,peer:connect, `peer:d… - libp2p-demo — (no submodules)- log-panel — (no submodules)- log-panel — (no submodules)- node-controls — (no submodules)- node-controls — (no submodules)- node-status-panel — (no submodules)- node-status-panel — (no submodules)- peer-interaction-panel — (no submodules)- peer-interaction-panel — (no submodules)- peer-list — (no submodules)- peer-list — (no submodules)- errors — (no submodules)- errors — (no submodules)- use-libp2p-demo — (no submodules)- wire-peer-events — Side-effect helper that subscrib…
- use-libp2p-demo — (no submodules)- wire-peer-events — Side-effect helper that subscrib…
- wire-peer-events — Side-effect helper that subscribes to a
Libp2pDemoNode's three peer events (peer:discovery,peer:connect, `peer:d…
- libp2p-demo — (no submodules)- log-panel — (no submodules)- log-panel — (no submodules)- node-controls — (no submodules)- node-controls — (no submodules)- node-status-panel — (no submodules)- node-status-panel — (no submodules)- peer-interaction-panel — (no submodules)- peer-interaction-panel — (no submodules)- peer-list — (no submodules)- peer-list — (no submodules)- errors — (no submodules)- errors — (no submodules)- use-libp2p-demo — (no submodules)- wire-peer-events — Side-effect helper that subscrib…
- use-libp2p-demo — (no submodules)- wire-peer-events — Side-effect helper that subscrib…
- wire-peer-events — Side-effect helper that subscribes to a
Libp2pDemoNode's three peer events (peer:discovery,peer:connect, `peer:d…
- libp2p-demo — (no submodules)- log-panel — (no submodules) - log-panel — (no submodules)- node-controls — (no submodules) - node-controls — (no submodules)- node-status-panel — (no submodules) - node-status-panel — (no submodules)- peer-interaction-panel — (no submodules) - peer-interaction-panel — (no submodules)- peer-list — (no submodules) - peer-list — (no submodules)- errors — (no submodules) - errors — (no submodules)- use-libp2p-demo — (no submodules) - use-libp2p-demo — (no submodules) - wire-peer-events — Side-effect helper that subscribes to a
Libp2pDemoNode's three peer events (peer:discovery,peer:connect, `peer:d…
Required user-supplied bootstrap
The package never publishes a public bootstrap list. The <Libp2pDemo>
composer (and the underlying useLibp2pDemo hook) accepts a bootstrap: readonly string[] React prop that is REQUIRED — the array may be empty
(for mDNS-only or WebRTC-only flows) but the consumer must always supply
it explicitly. There are no hardcoded fallback peers anywhere in the
source tree.
import { Libp2pDemo } from "@suaveplan/react-network-libp2p-demo";
<Libp2pDemo
nodeFactory={myLibp2pFactory}
bootstrap={["/dnsaddr/your-bootstrap.example/p2p/Qm…"]}
subTransport="webrtc"
/>;
This is a deliberate API choice: hardcoding a default would bake a trust decision into the library that every downstream consumer would silently inherit. Consumers stay in charge of which peers their demo trusts.
What this package owns
- Root composer —
<Libp2pDemo>(components/libp2p-demo) - Hook —
useLibp2pDemo(hooks/use-libp2p-demo) - Peer-event wiring helper —
wirePeerEvents(wiring) - Status panel —
<NodeStatusPanel>(panel) - Lifecycle buttons —
<NodeControls>(controls) - Interaction row —
<PeerInteractionPanel>(row) - Peer lists —
<PeerList>(list) - Log viewer —
<LogPanel>(logs)
Architecture
The package depends on @suaveplan/network-transport-libp2p as a peer
dependency, but never imports libp2p directly. Production consumers
implement a thin Libp2pDemoNodeFactory adapter that wraps the real
libp2p stack and conforms to the structural Libp2pDemoNode contract
defined here. Tests pass a deterministic fake conforming to the same
contract (tests/setup/fake-node.ts).
Error registry
defineCodes("REACT_LIBP2P_DEMO", […]) — 5 codes:
INVALID_OPTIONS, DEMO_DISPOSED, NODE_NOT_STARTED, DIAL_FAILED,
ECHO_FAILED.
Status
- Wave 7.2 (final network-migration package).
- Source files all ≤300 LOC per CLAUDE.md.
- Every component carries Storybook stories (default + playground + variants) per CLAUDE.md.