first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
# @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.
<!-- begin:auto-docs -->
## Documentation tree
- [libp2p-demo](./src/components/libp2p-demo/libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [libp2p-demo](./src/components/libp2p-demo/libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [log-panel](./src/components/log-panel/log-panel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [log-panel](./src/components/log-panel/log-panel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [node-controls](./src/components/node-controls/node-controls.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [node-controls](./src/components/node-controls/node-controls.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [node-status-panel](./src/components/node-status-panel/node-status-panel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [node-status-panel](./src/components/node-status-panel/node-status-panel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [peer-interaction-panel](./src/components/peer-interaction-panel/peer-interaction-panel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [peer-interaction-panel](./src/components/peer-interaction-panel/peer-interaction-panel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [peer-list](./src/components/peer-list/peer-list.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [peer-list](./src/components/peer-list/peer-list.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-libp2p-demo](./src/hooks/use-libp2p-demo/use-libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - wire-peer-events — Side-effect helper that subscrib…
- [use-libp2p-demo](./src/hooks/use-libp2p-demo/use-libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - wire-peer-events — Side-effect helper that subscrib…
- [wire-peer-events](./src/hooks/use-libp2p-demo/wire-peer-events.md) — Side-effect helper that subscribes to a `Libp2pDemoNode`'s three peer events (`peer:discovery`, `peer:connect`, `peer:d…
<!-- end:auto-docs --> - [libp2p-demo](./src/components/libp2p-demo/libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_- [log-panel](./src/components/log-panel/log-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [log-panel](./src/components/log-panel/log-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-controls](./src/components/node-controls/node-controls.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-controls](./src/components/node-controls/node-controls.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-status-panel](./src/components/node-status-panel/node-status-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-status-panel](./src/components/node-status-panel/node-status-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-interaction-panel](./src/components/peer-interaction-panel/peer-interaction-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-interaction-panel](./src/components/peer-interaction-panel/peer-interaction-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-list](./src/components/peer-list/peer-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-list](./src/components/peer-list/peer-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-libp2p-demo](./src/hooks/use-libp2p-demo/use-libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_- wire-peer-events — Side-effect helper that subscrib…
- [use-libp2p-demo](./src/hooks/use-libp2p-demo/use-libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_- wire-peer-events — Side-effect helper that subscrib…
- [wire-peer-events](./src/hooks/use-libp2p-demo/wire-peer-events.md) — Side-effect helper that subscribes to a `Libp2pDemoNode`'s three peer events (`peer:discovery`, `peer:connect`, `peer:d…
- [libp2p-demo](./src/components/libp2p-demo/libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_- [log-panel](./src/components/log-panel/log-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [log-panel](./src/components/log-panel/log-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-controls](./src/components/node-controls/node-controls.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-controls](./src/components/node-controls/node-controls.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-status-panel](./src/components/node-status-panel/node-status-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-status-panel](./src/components/node-status-panel/node-status-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-interaction-panel](./src/components/peer-interaction-panel/peer-interaction-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-interaction-panel](./src/components/peer-interaction-panel/peer-interaction-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-list](./src/components/peer-list/peer-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-list](./src/components/peer-list/peer-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-libp2p-demo](./src/hooks/use-libp2p-demo/use-libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_- wire-peer-events — Side-effect helper that subscrib…
- [use-libp2p-demo](./src/hooks/use-libp2p-demo/use-libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_- wire-peer-events — Side-effect helper that subscrib…
- [wire-peer-events](./src/hooks/use-libp2p-demo/wire-peer-events.md) — Side-effect helper that subscribes to a `Libp2pDemoNode`'s three peer events (`peer:discovery`, `peer:connect`, `peer:d…
- [libp2p-demo](./src/components/libp2p-demo/libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_- [log-panel](./src/components/log-panel/log-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [log-panel](./src/components/log-panel/log-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-controls](./src/components/node-controls/node-controls.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-controls](./src/components/node-controls/node-controls.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-status-panel](./src/components/node-status-panel/node-status-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-status-panel](./src/components/node-status-panel/node-status-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-interaction-panel](./src/components/peer-interaction-panel/peer-interaction-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-interaction-panel](./src/components/peer-interaction-panel/peer-interaction-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-list](./src/components/peer-list/peer-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-list](./src/components/peer-list/peer-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-libp2p-demo](./src/hooks/use-libp2p-demo/use-libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_- wire-peer-events — Side-effect helper that subscrib…
- [use-libp2p-demo](./src/hooks/use-libp2p-demo/use-libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_- wire-peer-events — Side-effect helper that subscrib…
- [wire-peer-events](./src/hooks/use-libp2p-demo/wire-peer-events.md) — Side-effect helper that subscribes to a `Libp2pDemoNode`'s three peer events (`peer:discovery`, `peer:connect`, `peer:d…
- [libp2p-demo](./src/components/libp2p-demo/libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_- [log-panel](./src/components/log-panel/log-panel.md) — <!-- begin:auto-docs --> _(no submodules)_ - [log-panel](./src/components/log-panel/log-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-controls](./src/components/node-controls/node-controls.md) — <!-- begin:auto-docs --> _(no submodules)_ - [node-controls](./src/components/node-controls/node-controls.md) — <!-- begin:auto-docs --> _(no submodules)_- [node-status-panel](./src/components/node-status-panel/node-status-panel.md) — <!-- begin:auto-docs --> _(no submodules)_ - [node-status-panel](./src/components/node-status-panel/node-status-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-interaction-panel](./src/components/peer-interaction-panel/peer-interaction-panel.md) — <!-- begin:auto-docs --> _(no submodules)_ - [peer-interaction-panel](./src/components/peer-interaction-panel/peer-interaction-panel.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-list](./src/components/peer-list/peer-list.md) — <!-- begin:auto-docs --> _(no submodules)_ - [peer-list](./src/components/peer-list/peer-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ - [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-libp2p-demo](./src/hooks/use-libp2p-demo/use-libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-libp2p-demo](./src/hooks/use-libp2p-demo/use-libp2p-demo.md) — <!-- begin:auto-docs --> _(no submodules)_ - [wire-peer-events](./src/hooks/use-libp2p-demo/wire-peer-events.md) — 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.
```tsx
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`](./src/components/libp2p-demo/libp2p-demo.md))
- **Hook** — `useLibp2pDemo` ([`hooks/use-libp2p-demo`](./src/hooks/use-libp2p-demo/use-libp2p-demo.md))
- **Peer-event wiring helper** — `wirePeerEvents` ([wiring](./src/hooks/use-libp2p-demo/wire-peer-events.md))
- **Status panel** — `<NodeStatusPanel>` ([panel](./src/components/node-status-panel/node-status-panel.md))
- **Lifecycle buttons** — `<NodeControls>` ([controls](./src/components/node-controls/node-controls.md))
- **Interaction row** — `<PeerInteractionPanel>` ([row](./src/components/peer-interaction-panel/peer-interaction-panel.md))
- **Peer lists** — `<PeerList>` ([list](./src/components/peer-list/peer-list.md))
- **Log viewer** — `<LogPanel>` ([logs](./src/components/log-panel/log-panel.md))
## 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.