Seam

interface Seam

One peer's view of a multi-peer session.

Symmetry: every peer in the session holds an identical Seam — there is no client/server distinction at this layer. A two-peer topology (e.g. the existing WebSocket transport) is just the degenerate case with peers.value.size == 2.

Fabric lifecycle: state tracks whether the fabric can carry frames. Wait for SeamState.Woven before sending on fabrics that may take time to establish their link (radio/mesh transports). Relay transports reach SeamState.Woven essentially immediately.

Send semantics:

Collecting incoming frames

Collect incoming exactly once per Seam. For multiple consumers, wrap with shareIn in a coroutine scope you control.

Samples

runTest {
    val loom = InMemoryLoom()
    val host = loom.host(Pattern("Alice"))
    val joiner = loom.join(InMemoryTag("Bob"))

    // Collect three frames then stop; proves the flow is cold and single-shot.
    val collected = launch { host.incoming.take(3).toList() }

    repeat(3) { joiner.broadcast("frame-$it".encodeToByteArray()) }
    collected.join()

    host.close()
    joiner.close()
}

Inheritors

Properties

Link copied to clipboard
abstract val incoming: Flow<Swatch>

Frames received from peers, in send order, delivered to a single collector. Cold/single-collection semantics: collect once per Seam; fan-out consumers wrap with shareIn. A second concurrent collector is unsupported and will race.

Link copied to clipboard
abstract val peers: StateFlow<Set<PeerId>>

Live set of peers currently connected. Includes selfId.

Link copied to clipboard
open val plies: StateFlow<Map<PlyId, SeamState>>

Per-ply lifecycle breakdown. Single-ply fabrics report a one-entry map keyed by PlyId.Sole. Invariant: state.value equals the rollup of plies.value.values under "any ply Woven ⇒ Woven".

Link copied to clipboard
abstract val selfId: PeerId

This peer's own identifier.

Link copied to clipboard
abstract val state: StateFlow<SeamState>

The fabric's lifecycle as observed by this peer.

Functions

Link copied to clipboard
abstract suspend fun broadcast(payload: ByteArray)

Send to all other peers. Suspends until accepted by the local transport.

Link copied to clipboard
abstract suspend fun close(reason: CloseReason = CloseReason.Normal)

Disconnect from the session. Idempotent.

Link copied to clipboard
abstract suspend fun sendTo(peer: PeerId, payload: ByteArray)

Send to one peer. Suspends until accepted by the local transport.