fakeswarm
v0.2.1
Published
Deterministic in-memory fake hyperswarm for tests and demos.
Maintainers
Readme
fakeswarm
Deterministic, single-process, in-memory fake of a Hyperswarm-like swarm. Useful for tests, examples, or labs where you need predictable peer connections without any real DHT, NAT, or network traffic.
What it is
- In-memory swarm that pairs peers by shared topics in a shared Map.
- Deterministic dial election so only one side initiates.
- Uses
@hyperswarm/secret-streamNoise streams for realistic socket shape.
What it is not
- No real networking, NAT traversal, DHT, peer discovery, or reconnection logic.
- Not a drop-in for production Hyperswarm; it is a lab fake.
Install
npm install fakeswarmQuickstart
Two swarms join the same topic and exchange a message:
import { createFakeSwarm } from 'fakeswarm';
import crypto from 'crypto';
const topic = crypto.randomBytes(32);
const swarmA = createFakeSwarm();
const swarmB = createFakeSwarm();
swarmA.join(topic);
swarmB.join(topic);
swarmB.on('connection', (socket, peerInfo) => {
socket.on('data', (data) => {
console.log('B got:', data.toString(), 'from', peerInfo.id);
});
});
swarmA.on('connection', (socket) => {
socket.write('hello');
});Always call close() when done to unpublish topics and destroy sockets.
API
createFakeSwarm(seedOrOpts?, topics?)
seedOrOptscan be:Buffer | Uint8Array | null(legacy seed) or{ seed?, net? }
topics(Map) optional shared topics map. By default a module-level Map is used so multiple swarms share the same space.
Returns an object with:
join(topic, opts?)-> discovery handle: joins a topic (Buffer).optsmirrors Hyperswarm with defaults{ server: true, client: true }.- If
server: false, the swarm will not publish/accept on this topic. - If
client: false, the swarm will not dial on this topic. - Handle exposes
leave()/destroy()(unpublish), andrefresh()/flushed()(immediate no-ops for parity).
- If
leave(topic): unpublish without the handle.connections:Map<peerId, { socket, peerInfo }>of active sockets.topics: Set of encoded topics joined (any mode).on(event, fn)/off(event, fn): EventEmitter style. Events:connection(socket, peerInfo)wherepeerInfo = { publicKey, id, initiator }.closewhen the swarm closes.updatewhen the connection set changes.
flush(timeoutMs?): wait (best-effort) for in-flight dials to settle; useful in tests to let the tick loop quiesce.close()/destroy(): unpublish, stop ticking, destroy sockets, and emitclose.keyPair: the generated keypair.id:idEncoding.encode(publicKey)convenience string.
Network profile (opt-in, default off)
net.reconnectRace lets you simulate a quick disconnect/reconnect overlap:
enabled(boolean): default false. When false, behavior is unchanged.staleRetentionMs(default 25): how long a closed socket is retained internally before destroy.reconnectDelayMs(default 10): how soon a reconnect attempt is triggered.duplicateConnection(boolean): if true, emit a secondconnectionevent for the new socket even while the stale one is retained.connectionsstill exposes only the current socket per peer; stale sockets are kept internally and cleaned up after the retention window.
Join / leave semantics
- Joining registers this swarm in the shared topics map; peers that share a topic will connect.
- Leaving (or closing) removes the entry from the shared map to avoid ghost peers.
- Testing tip: pass a fresh
topics = new Map()per test to avoid cross-test bleed; the default module-level map is shared across all swarms in the process.
Determinism notes
- Dial election: only the lexicographically smaller peerId initiates (
peerId < remotePeerId), preventing double connects. - Backfill: the first
connectionlistener added receives existing connections immediately (if any). - Flush: waits for connecting dials to drain; it does not advance time on its own.
Resource cleanup
- Always call
close()(ordestroy()) to unpublish topics and destroy sockets. flush()can be used in tests to wait until the swarm has no in-flight dials before asserting.
Limitations
- No NAT traversal, DHT, hole-punching, or real network I/O.
- No reconnection, banning, or peer prioritization.
- No peer discovery beyond the shared in-memory topics map you provide.
- Single-process only; for multi-process/multi-machine tests use real Hyperswarm.
License
MIT
